From 6d83e3bc4608ba62d9f1a118a6191c7dd340bb06 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 17 Jul 2024 03:43:29 -0400 Subject: [PATCH 01/58] refactor: restrict PrefixedHexString types (#3510) * refactor: restrict PrefixedHexString types * block: remove null from comments * client: minor type fixes --- packages/block/src/types.ts | 176 +++++++++++------------ packages/client/src/rpc/modules/debug.ts | 2 +- packages/client/src/rpc/modules/eth.ts | 3 +- packages/common/src/types.ts | 22 ++- packages/util/src/bytes.ts | 15 +- 5 files changed, 104 insertions(+), 114 deletions(-) diff --git a/packages/block/src/types.ts b/packages/block/src/types.ts index 409705b60d..e1fa075796 100644 --- a/packages/block/src/types.ts +++ b/packages/block/src/types.ts @@ -83,29 +83,28 @@ export interface BlockOptions { /** * A block header's data. */ -// TODO: Deprecate the string type and only keep BytesLike/AddressLike/BigIntLike export interface HeaderData { - parentHash?: BytesLike | string - uncleHash?: BytesLike | string - coinbase?: AddressLike | string - stateRoot?: BytesLike | string - transactionsTrie?: BytesLike | string - receiptTrie?: BytesLike | string - logsBloom?: BytesLike | string - difficulty?: BigIntLike | string - number?: BigIntLike | string - gasLimit?: BigIntLike | string - gasUsed?: BigIntLike | string - timestamp?: BigIntLike | string - extraData?: BytesLike | string - mixHash?: BytesLike | string - nonce?: BytesLike | string - baseFeePerGas?: BigIntLike | string - withdrawalsRoot?: BytesLike | string - blobGasUsed?: BigIntLike | string - excessBlobGas?: BigIntLike | string - parentBeaconBlockRoot?: BytesLike | string - requestsRoot?: BytesLike | string + parentHash?: BytesLike + uncleHash?: BytesLike + coinbase?: AddressLike + stateRoot?: BytesLike + transactionsTrie?: BytesLike + receiptTrie?: BytesLike + logsBloom?: BytesLike + difficulty?: BigIntLike + number?: BigIntLike + gasLimit?: BigIntLike + gasUsed?: BigIntLike + timestamp?: BigIntLike + extraData?: BytesLike + mixHash?: BytesLike + nonce?: BytesLike + baseFeePerGas?: BigIntLike + withdrawalsRoot?: BytesLike + blobGasUsed?: BigIntLike + excessBlobGas?: BigIntLike + parentBeaconBlockRoot?: BytesLike + requestsRoot?: BytesLike } /** @@ -177,65 +176,63 @@ export interface JsonBlock { /** * An object with the block header's data represented as 0x-prefixed hex strings. */ -// TODO: Remove the string type and only keep PrefixedHexString export interface JsonHeader { - parentHash?: PrefixedHexString | string - uncleHash?: PrefixedHexString | string - coinbase?: PrefixedHexString | string - stateRoot?: PrefixedHexString | string - transactionsTrie?: PrefixedHexString | string - receiptTrie?: PrefixedHexString | string - logsBloom?: PrefixedHexString | string - difficulty?: PrefixedHexString | string - number?: PrefixedHexString | string - gasLimit?: PrefixedHexString | string - gasUsed?: PrefixedHexString | string - timestamp?: PrefixedHexString | string - extraData?: PrefixedHexString | string - mixHash?: PrefixedHexString | string - nonce?: PrefixedHexString | string - baseFeePerGas?: PrefixedHexString | string - withdrawalsRoot?: PrefixedHexString | string - blobGasUsed?: PrefixedHexString | string - excessBlobGas?: PrefixedHexString | string - parentBeaconBlockRoot?: PrefixedHexString | string - requestsRoot?: PrefixedHexString | string + parentHash?: PrefixedHexString + uncleHash?: PrefixedHexString + coinbase?: PrefixedHexString + stateRoot?: PrefixedHexString + transactionsTrie?: PrefixedHexString + receiptTrie?: PrefixedHexString + logsBloom?: PrefixedHexString + difficulty?: PrefixedHexString + number?: PrefixedHexString + gasLimit?: PrefixedHexString + gasUsed?: PrefixedHexString + timestamp?: PrefixedHexString + extraData?: PrefixedHexString + mixHash?: PrefixedHexString + nonce?: PrefixedHexString + baseFeePerGas?: PrefixedHexString + withdrawalsRoot?: PrefixedHexString + blobGasUsed?: PrefixedHexString + excessBlobGas?: PrefixedHexString + parentBeaconBlockRoot?: PrefixedHexString + requestsRoot?: PrefixedHexString } /* * Based on https://ethereum.org/en/developers/docs/apis/json-rpc/ */ -// TODO: Remove the string type and only keep PrefixedHexString export interface JsonRpcBlock { - number: PrefixedHexString | string // the block number. null when pending block. - hash: PrefixedHexString | string // hash of the block. null when pending block. - parentHash: PrefixedHexString | string // hash of the parent block. - mixHash?: PrefixedHexString | string // bit hash which proves combined with the nonce that a sufficient amount of computation has been carried out on this block. - nonce: PrefixedHexString | string // hash of the generated proof-of-work. null when pending block. - sha3Uncles: PrefixedHexString | string // SHA3 of the uncles data in the block. - logsBloom: PrefixedHexString | string // the bloom filter for the logs of the block. null when pending block. - transactionsRoot: PrefixedHexString | string // the root of the transaction trie of the block. - stateRoot: PrefixedHexString | string // the root of the final state trie of the block. - receiptsRoot: PrefixedHexString | string // the root of the receipts trie of the block. - miner: PrefixedHexString | string // the address of the beneficiary to whom the mining rewards were given. - difficulty: PrefixedHexString | string // integer of the difficulty for this block. - totalDifficulty: PrefixedHexString | string // integer of the total difficulty of the chain until this block. - extraData: PrefixedHexString | string // the “extra data” field of this block. - size: PrefixedHexString | string // integer the size of this block in bytes. - gasLimit: PrefixedHexString | string // the maximum gas allowed in this block. - gasUsed: PrefixedHexString | string // the total used gas by all transactions in this block. - timestamp: PrefixedHexString | string // the unix timestamp for when the block was collated. - transactions: Array // Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. - uncles: PrefixedHexString[] | string[] // Array of uncle hashes - baseFeePerGas?: PrefixedHexString | string // If EIP-1559 is enabled for this block, returns the base fee per gas + number: PrefixedHexString // the block number. + hash: PrefixedHexString // hash of the block. + parentHash: PrefixedHexString // hash of the parent block. + mixHash?: PrefixedHexString // bit hash which proves combined with the nonce that a sufficient amount of computation has been carried out on this block. + nonce: PrefixedHexString // hash of the generated proof-of-work. + sha3Uncles: PrefixedHexString // SHA3 of the uncles data in the block. + logsBloom: PrefixedHexString // the bloom filter for the logs of the block. + transactionsRoot: PrefixedHexString // the root of the transaction trie of the block. + stateRoot: PrefixedHexString // the root of the final state trie of the block. + receiptsRoot: PrefixedHexString // the root of the receipts trie of the block. + miner: PrefixedHexString // the address of the beneficiary to whom the mining rewards were given. + difficulty: PrefixedHexString // integer of the difficulty for this block. + totalDifficulty: PrefixedHexString // integer of the total difficulty of the chain until this block. + extraData: PrefixedHexString // the “extra data” field of this block. + size: PrefixedHexString // integer the size of this block in bytes. + gasLimit: PrefixedHexString // the maximum gas allowed in this block. + gasUsed: PrefixedHexString // the total used gas by all transactions in this block. + timestamp: PrefixedHexString // the unix timestamp for when the block was collated. + transactions: Array // Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter. + uncles: PrefixedHexString[] // Array of uncle hashes + baseFeePerGas?: PrefixedHexString // If EIP-1559 is enabled for this block, returns the base fee per gas withdrawals?: Array // If EIP-4895 is enabled for this block, array of withdrawals - withdrawalsRoot?: PrefixedHexString | string // If EIP-4895 is enabled for this block, the root of the withdrawal trie of the block. - blobGasUsed?: PrefixedHexString | string // If EIP-4844 is enabled for this block, returns the blob gas used for the block - excessBlobGas?: PrefixedHexString | string // If EIP-4844 is enabled for this block, returns the excess blob gas for the block - parentBeaconBlockRoot?: PrefixedHexString | string // If EIP-4788 is enabled for this block, returns parent beacon block root + withdrawalsRoot?: PrefixedHexString // If EIP-4895 is enabled for this block, the root of the withdrawal trie of the block. + blobGasUsed?: PrefixedHexString // If EIP-4844 is enabled for this block, returns the blob gas used for the block + excessBlobGas?: PrefixedHexString // If EIP-4844 is enabled for this block, returns the excess blob gas for the block + parentBeaconBlockRoot?: PrefixedHexString // If EIP-4788 is enabled for this block, returns parent beacon block root executionWitness?: VerkleExecutionWitness | null // If Verkle is enabled for this block - requestsRoot?: PrefixedHexString | string // If EIP-7685 is enabled for this block, returns the requests root - requests?: Array // If EIP-7685 is enabled for this block, array of serialized CL requests + requestsRoot?: PrefixedHexString // If EIP-7685 is enabled for this block, returns the requests root + requests?: Array // If EIP-7685 is enabled for this block, array of serialized CL requests } export type WithdrawalV1 = { @@ -246,26 +243,25 @@ export type WithdrawalV1 = { } // Note: all these strings are 0x-prefixed -// TODO: Remove the string type and only keep PrefixedHexString export type ExecutionPayload = { - parentHash: PrefixedHexString | string // DATA, 32 Bytes - feeRecipient: PrefixedHexString | string // DATA, 20 Bytes - stateRoot: PrefixedHexString | string // DATA, 32 Bytes - receiptsRoot: PrefixedHexString | string // DATA, 32 bytes - logsBloom: PrefixedHexString | string // DATA, 256 Bytes - prevRandao: PrefixedHexString | string // DATA, 32 Bytes - blockNumber: PrefixedHexString | string // QUANTITY, 64 Bits - gasLimit: PrefixedHexString | string // QUANTITY, 64 Bits - gasUsed: PrefixedHexString | string // QUANTITY, 64 Bits - timestamp: PrefixedHexString | string // QUANTITY, 64 Bits - extraData: PrefixedHexString | string // DATA, 0 to 32 Bytes - baseFeePerGas: PrefixedHexString | string // QUANTITY, 256 Bits - blockHash: PrefixedHexString | string // DATA, 32 Bytes - transactions: PrefixedHexString[] | string[] // Array of DATA - Array of transaction rlp strings, + parentHash: PrefixedHexString // DATA, 32 Bytes + feeRecipient: PrefixedHexString // DATA, 20 Bytes + stateRoot: PrefixedHexString // DATA, 32 Bytes + receiptsRoot: PrefixedHexString // DATA, 32 bytes + logsBloom: PrefixedHexString // DATA, 256 Bytes + prevRandao: PrefixedHexString // DATA, 32 Bytes + blockNumber: PrefixedHexString // QUANTITY, 64 Bits + gasLimit: PrefixedHexString // QUANTITY, 64 Bits + gasUsed: PrefixedHexString // QUANTITY, 64 Bits + timestamp: PrefixedHexString // QUANTITY, 64 Bits + extraData: PrefixedHexString // DATA, 0 to 32 Bytes + baseFeePerGas: PrefixedHexString // QUANTITY, 256 Bits + blockHash: PrefixedHexString // DATA, 32 Bytes + transactions: PrefixedHexString[] // Array of DATA - Array of transaction rlp strings, withdrawals?: WithdrawalV1[] // Array of withdrawal objects - blobGasUsed?: PrefixedHexString | string // QUANTITY, 64 Bits - excessBlobGas?: PrefixedHexString | string // QUANTITY, 64 Bits - parentBeaconBlockRoot?: PrefixedHexString | string // QUANTITY, 64 Bits + blobGasUsed?: PrefixedHexString // QUANTITY, 64 Bits + excessBlobGas?: PrefixedHexString // QUANTITY, 64 Bits + parentBeaconBlockRoot?: PrefixedHexString // QUANTITY, 64 Bits // VerkleExecutionWitness is already a hex serialized object executionWitness?: VerkleExecutionWitness | null // QUANTITY, 64 Bits, null implies not available depositRequests?: DepositRequestV1[] // Array of 6110 deposit requests diff --git a/packages/client/src/rpc/modules/debug.ts b/packages/client/src/rpc/modules/debug.ts index abfd4eaffa..be7a61f23c 100644 --- a/packages/client/src/rpc/modules/debug.ts +++ b/packages/client/src/rpc/modules/debug.ts @@ -398,7 +398,7 @@ export class Debug { * Returns the bytes of the transaction. * @param blockOpt Block number or tag */ - async getRawTransaction(params: [string]) { + async getRawTransaction(params: [PrefixedHexString]) { const [txHash] = params if (!this.service.execution.receiptsManager) throw new Error('missing receiptsManager') const result = await this.service.execution.receiptsManager.getReceiptByTxHash( diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 0a6bb135a6..26519f9f0b 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -14,6 +14,7 @@ import { equalsBytes, hexToBytes, intToHex, + isHexString, setLengthLeft, toType, } from '@ethereumjs/util' @@ -918,7 +919,7 @@ export class Eth { const [blockOpt] = params let block: Block try { - if (blockOpt.length === 66) { + if (isHexString(blockOpt, 64)) { block = await this._chain.getBlock(hexToBytes(blockOpt)) } else { block = await getBlockByOption(blockOpt, this._chain) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 6507efbadd..8569e3cb80 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -41,15 +41,14 @@ export interface ChainConfig { depositContractAddress?: PrefixedHexString } -// TODO: Remove the string type and only keep PrefixedHexString export interface GenesisBlockConfig { - timestamp?: PrefixedHexString | string - gasLimit: number | PrefixedHexString | string - difficulty: number | PrefixedHexString | string - nonce: PrefixedHexString | string - extraData: PrefixedHexString | string - baseFeePerGas?: PrefixedHexString | string - excessBlobGas?: PrefixedHexString | string + timestamp?: PrefixedHexString + gasLimit: number | PrefixedHexString + difficulty: number | PrefixedHexString + nonce: PrefixedHexString + extraData: PrefixedHexString + baseFeePerGas?: PrefixedHexString + excessBlobGas?: PrefixedHexString } export interface HardforkTransitionConfig { @@ -159,11 +158,10 @@ export interface GethConfigOpts extends BaseOpts { mergeForkIdPostMerge?: boolean } -// TODO: Deprecate the string type and only keep BigIntLike export interface HardforkByOpts { - blockNumber?: BigIntLike | string - timestamp?: BigIntLike | string - td?: BigIntLike | string + blockNumber?: BigIntLike + timestamp?: BigIntLike + td?: BigIntLike } export type EIPOrHFConfig = { diff --git a/packages/util/src/bytes.ts b/packages/util/src/bytes.ts index 907bf2ad3d..8ab36fb35e 100644 --- a/packages/util/src/bytes.ts +++ b/packages/util/src/bytes.ts @@ -107,14 +107,13 @@ export const bytesToInt = (bytes: Uint8Array): number => { return res } -// TODO: Restrict the input type to only PrefixedHexString /** * Converts a {@link PrefixedHexString} to a {@link Uint8Array} - * @param {PrefixedHexString | string} hex The 0x-prefixed hex string to convert + * @param {PrefixedHexString} hex The 0x-prefixed hex string to convert * @returns {Uint8Array} The converted bytes * @throws If the input is not a valid 0x-prefixed hex string */ -export const hexToBytes = (hex: PrefixedHexString | string): Uint8Array => { +export const hexToBytes = (hex: PrefixedHexString): Uint8Array => { if (typeof hex !== 'string') { throw new Error(`hex argument type ${typeof hex} must be of type string`) } @@ -257,21 +256,18 @@ export const unpadArray = (a: number[]): number[] => { return stripZeros(a) } -// TODO: Restrict the input type to only PrefixedHexString /** * Trims leading zeros from a `PrefixedHexString`. - * @param {PrefixedHexString | string} a + * @param {PrefixedHexString} a * @return {PrefixedHexString} */ -export const unpadHex = (a: PrefixedHexString | string): PrefixedHexString => { +export const unpadHex = (a: PrefixedHexString): PrefixedHexString => { assertIsHexString(a) return `0x${stripZeros(stripHexPrefix(a))}` } -// TODO: remove the string type from this function (only keep PrefixedHexString) export type ToBytesInputTypes = | PrefixedHexString - | string | number | bigint | Uint8Array @@ -552,7 +548,6 @@ export function bigInt64ToBytes(value: bigint, littleEndian: boolean = false): U // eslint-disable-next-line no-restricted-imports export { bytesToUtf8, equalsBytes, utf8ToBytes } from 'ethereum-cryptography/utils.js' -// TODO: Restrict the input type to only PrefixedHexString -export function hexToBigInt(input: PrefixedHexString | string): bigint { +export function hexToBigInt(input: PrefixedHexString): bigint { return bytesToBigInt(hexToBytes(isHexString(input) ? input : `0x${input}`)) } From 03fa9124d59eed777ee7c57448d0593e088a9e46 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Wed, 17 Jul 2024 11:15:00 +0200 Subject: [PATCH 02/58] Blockchain: More Modern and Flexible Consensus Layout / Tree Shaking Optimization (#3504) * Switch to a more flexible Blockchain consensusDict options structure allowing to pass in different consensus objects * Remove misplaced (non consensus checkand useless (already checked in block header) difficulty equals 0 check from CasperConsensus * Shift to a new consensus semantics adhering to the fact that *consensus* and *consensus validation* is basically the same, allowing for more flexible instantiation and optional consensus object usage * Remove redundant validateConsensus flag, fix block validation, clique and custom consensus tests * Readd validateConsensus flag (default: true) to allow for more fine-grained settings to use the mechanism (e.g. Clique) but skip the respective validation * Find a middle ground between convenience (allow mainnet default blockchain without need for ethash passing in) and consensus availability validation (now in the validate() call) * Add clique example * Client fixes * Fix VM test * Minor * Remove Ethash dependency from Blockchain, adjust EthashConsensus ethash object integration * Re-add CasperConsensus exports * Rebuild package-lock.json * EtashConsensus fix * Fixes * Fix client CLI tests * Cleaner consensus check on validate call * More consistent check for consensus object, re-add test for custom consensus transition * Re-add difficulty check for PoS, re-activate removed test --- package-lock.json | 6 +- packages/blockchain/examples/clique.ts | 12 ++ packages/blockchain/package.json | 5 +- packages/blockchain/src/blockchain.ts | 103 +++++++----------- packages/blockchain/src/consensus/casper.ts | 3 + packages/blockchain/src/consensus/ethash.ts | 16 +-- packages/blockchain/src/constructors.ts | 4 +- packages/blockchain/src/types.ts | 52 ++++++--- .../blockchain/test/blockValidation.spec.ts | 27 +++-- packages/blockchain/test/clique.spec.ts | 13 ++- .../blockchain/test/customConsensus.spec.ts | 34 +++--- packages/blockchain/test/pos.spec.ts | 1 - packages/blockchain/test/reorg.spec.ts | 10 +- packages/blockchain/test/util.ts | 1 - packages/client/bin/cli.ts | 14 ++- packages/client/src/blockchain/chain.ts | 9 +- .../client/test/integration/merge.spec.ts | 9 +- .../client/test/integration/miner.spec.ts | 7 +- packages/client/test/integration/util.ts | 8 +- packages/vm/examples/run-blockchain.ts | 15 ++- packages/vm/package.json | 1 + packages/vm/test/api/buildBlock.spec.ts | 29 ++++- .../tester/runners/BlockchainTestsRunner.ts | 12 +- 23 files changed, 237 insertions(+), 154 deletions(-) create mode 100644 packages/blockchain/examples/clique.ts diff --git a/package-lock.json b/package-lock.json index 7d78164924..dc5d3c1479 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16638,7 +16638,6 @@ "dependencies": { "@ethereumjs/block": "^5.2.0", "@ethereumjs/common": "^4.3.0", - "@ethereumjs/ethash": "^3.0.3", "@ethereumjs/rlp": "^5.0.2", "@ethereumjs/trie": "^6.2.0", "@ethereumjs/tx": "^5.3.0", @@ -16647,7 +16646,9 @@ "ethereum-cryptography": "^2.2.1", "lru-cache": "10.1.0" }, - "devDependencies": {}, + "devDependencies": { + "@ethereumjs/ethash": "^3.0.3" + }, "engines": { "node": ">=18" } @@ -17026,6 +17027,7 @@ "ethereum-cryptography": "^2.2.1" }, "devDependencies": { + "@ethereumjs/ethash": "^3.0.3", "@ethersproject/abi": "^5.0.12", "@types/benchmark": "^1.0.33", "@types/core-js": "^2.5.0", diff --git a/packages/blockchain/examples/clique.ts b/packages/blockchain/examples/clique.ts new file mode 100644 index 0000000000..92a822a03f --- /dev/null +++ b/packages/blockchain/examples/clique.ts @@ -0,0 +1,12 @@ +import { createBlockchain, CliqueConsensus, ConsensusDict } from '@ethereumjs/blockchain' +import { Chain, Common, ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' + +const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.London }) + +const consensusDict: ConsensusDict = {} +consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() +const blockchain = await createBlockchain({ + consensusDict, + common, +}) +console.log(`Created blockchain with ${blockchain.consensus.algorithm} consensus algorithm`) diff --git a/packages/blockchain/package.json b/packages/blockchain/package.json index 1ea6f94b08..05478ccba1 100644 --- a/packages/blockchain/package.json +++ b/packages/blockchain/package.json @@ -49,7 +49,6 @@ "dependencies": { "@ethereumjs/block": "^5.2.0", "@ethereumjs/common": "^4.3.0", - "@ethereumjs/ethash": "^3.0.3", "@ethereumjs/rlp": "^5.0.2", "@ethereumjs/trie": "^6.2.0", "@ethereumjs/tx": "^5.3.0", @@ -58,7 +57,9 @@ "ethereum-cryptography": "^2.2.1", "lru-cache": "10.1.0" }, - "devDependencies": {}, + "devDependencies": { + "@ethereumjs/ethash": "^3.0.3" + }, "engines": { "node": ">=18" } diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index ff6d8ac8b0..f07b3dc3ab 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -14,7 +14,7 @@ import { equalsBytes, } from '@ethereumjs/util' -import { CasperConsensus, CliqueConsensus, EthashConsensus } from './consensus/index.js' +import { CasperConsensus } from './consensus/casper.js' import { DBOp, DBSaveLookups, @@ -30,6 +30,7 @@ import type { BlockchainInterface, BlockchainOptions, Consensus, + ConsensusDict, OnBlock, } from './types.js' import type { HeaderData } from '@ethereumjs/block' @@ -37,10 +38,16 @@ import type { CliqueConfig } from '@ethereumjs/common' import type { BigIntLike, DB, DBObject, GenesisState } from '@ethereumjs/util' /** - * This class stores and interacts with blocks. + * Blockchain implementation to create and maintain a valid canonical chain + * of block headers or blocks with support for reorgs and the ability to provide + * custom DB backends. + * + * By default consensus validation is not provided since with the swith to + * Proof-of-Stake consensus is validated by the Ethereum consensus layer. + * If consensus validation is desired for Etash or Clique blockchains the + * optional `consensusDict` option can be used to pass in validation objects. */ export class Blockchain implements BlockchainInterface { - consensus: Consensus db: DB dbManager: DBManager events: AsyncEventEmitter @@ -70,8 +77,9 @@ export class Blockchain implements BlockchainInterface { public readonly common: Common private _hardforkByHeadBlockNumber: boolean - private readonly _validateConsensus: boolean private readonly _validateBlocks: boolean + private readonly _validateConsensus: boolean + private _consensusDict: ConsensusDict /** * This is used to track which canonical blocks are deleted. After a method calls @@ -103,8 +111,8 @@ export class Blockchain implements BlockchainInterface { } this._hardforkByHeadBlockNumber = opts.hardforkByHeadBlockNumber ?? false - this._validateConsensus = opts.validateConsensus ?? true this._validateBlocks = opts.validateBlocks ?? true + this._validateConsensus = opts.validateConsensus ?? false this._customGenesisState = opts.genesisState this.db = opts.db !== undefined ? opts.db : new MapDB() @@ -113,38 +121,13 @@ export class Blockchain implements BlockchainInterface { this.events = new AsyncEventEmitter() - if (opts.consensus) { - this.consensus = opts.consensus - } else { - switch (this.common.consensusAlgorithm()) { - case ConsensusAlgorithm.Casper: - this.consensus = new CasperConsensus() - break - case ConsensusAlgorithm.Clique: - this.consensus = new CliqueConsensus() - break - case ConsensusAlgorithm.Ethash: - this.consensus = new EthashConsensus() - break - default: - throw new Error(`consensus algorithm ${this.common.consensusAlgorithm()} not supported`) - } - } + this._consensusDict = {} + this._consensusDict[ConsensusAlgorithm.Casper] = new CasperConsensus() - if (this._validateConsensus) { - if (this.common.consensusType() === ConsensusType.ProofOfWork) { - if (this.common.consensusAlgorithm() !== ConsensusAlgorithm.Ethash) { - throw new Error('consensus validation only supported for pow ethash algorithm') - } - } - if (this.common.consensusType() === ConsensusType.ProofOfAuthority) { - if (this.common.consensusAlgorithm() !== ConsensusAlgorithm.Clique) { - throw new Error( - 'consensus (signature) validation only supported for poa clique algorithm' - ) - } - } + if (opts.consensusDict !== undefined) { + this._consensusDict = { ...this._consensusDict, ...opts.consensusDict } } + this._consensusCheck() this._heads = {} @@ -155,6 +138,22 @@ export class Blockchain implements BlockchainInterface { } } + private _consensusCheck() { + if (this._validateConsensus && this.consensus === undefined) { + throw new Error( + `Consensus object for ${this.common.consensusAlgorithm()} must be passed (see consensusDict option) if consensus validation is activated` + ) + } + } + + /** + * Returns an eventual consensus object matching the current consensus algorithm from Common + * or undefined if non available + */ + get consensus(): Consensus | undefined { + return this._consensusDict[this.common.consensusAlgorithm()] + } + /** * Returns a deep copy of this {@link Blockchain} instance. * @@ -390,7 +389,7 @@ export class Blockchain implements BlockchainInterface { } if (this._validateConsensus) { - await this.consensus.validateConsensus(block) + await this.consensus!.validateConsensus(block) } // set total difficulty in the current context scope @@ -453,7 +452,7 @@ export class Blockchain implements BlockchainInterface { const ops = dbOps.concat(this._saveHeadOps()) await this.dbManager.batch(ops) - await this.consensus.newBlock(block, commonAncestor, ancestorHeaders) + await this.consensus?.newBlock(block, commonAncestor, ancestorHeaders) } catch (e) { // restore head to the previouly sane state this._heads = oldHeads @@ -499,7 +498,7 @@ export class Blockchain implements BlockchainInterface { throw new Error(`invalid timestamp ${header.errorStr()}`) } - if (!(header.common.consensusType() === 'pos')) await this.consensus.validateDifficulty(header) + if (!(header.common.consensusType() === 'pos')) await this.consensus?.validateDifficulty(header) if (this.common.consensusAlgorithm() === ConsensusAlgorithm.Clique) { const period = (this.common.consensusConfig() as CliqueConfig).period @@ -1221,31 +1220,9 @@ export class Blockchain implements BlockchainInterface { timestamp, }) - // If custom consensus algorithm is used, skip merge hardfork consensus checks - if (!Object.values(ConsensusAlgorithm).includes(this.consensus.algorithm as ConsensusAlgorithm)) - return - - switch (this.common.consensusAlgorithm()) { - case ConsensusAlgorithm.Casper: - if (!(this.consensus instanceof CasperConsensus)) { - this.consensus = new CasperConsensus() - } - break - case ConsensusAlgorithm.Clique: - if (!(this.consensus instanceof CliqueConsensus)) { - this.consensus = new CliqueConsensus() - } - break - case ConsensusAlgorithm.Ethash: - if (!(this.consensus instanceof EthashConsensus)) { - this.consensus = new EthashConsensus() - } - break - default: - throw new Error(`consensus algorithm ${this.common.consensusAlgorithm()} not supported`) - } - await this.consensus.setup({ blockchain: this }) - await this.consensus.genesisInit(this.genesisBlock) + this._consensusCheck() + await this.consensus?.setup({ blockchain: this }) + await this.consensus?.genesisInit(this.genesisBlock) } /** diff --git a/packages/blockchain/src/consensus/casper.ts b/packages/blockchain/src/consensus/casper.ts index 1cd3779d64..8d006e7367 100644 --- a/packages/blockchain/src/consensus/casper.ts +++ b/packages/blockchain/src/consensus/casper.ts @@ -21,6 +21,9 @@ export class CasperConsensus implements Consensus { public async validateConsensus(): Promise {} public async validateDifficulty(header: BlockHeader): Promise { + // TODO: This is not really part of consensus validation and it should be analyzed + // if it is possible to replace by a more generic hardfork check between block and + // blockchain along adding new blocks or headers if (header.difficulty !== BIGINT_0) { const msg = 'invalid difficulty. PoS blocks must have difficulty 0' throw new Error(`${msg} ${header.errorStr()}`) diff --git a/packages/blockchain/src/consensus/ethash.ts b/packages/blockchain/src/consensus/ethash.ts index b02f4229c8..315c37e798 100644 --- a/packages/blockchain/src/consensus/ethash.ts +++ b/packages/blockchain/src/consensus/ethash.ts @@ -1,26 +1,28 @@ import { ConsensusAlgorithm } from '@ethereumjs/common' -import { Ethash } from '@ethereumjs/ethash' import type { Blockchain } from '../index.js' import type { Consensus, ConsensusOptions } from '../types.js' import type { Block, BlockHeader } from '@ethereumjs/block' +type MinimalEthashInterface = { + cacheDB?: any + verifyPOW(block: Block): Promise +} + /** * This class encapsulates Ethash-related consensus functionality when used with the Blockchain class. */ export class EthashConsensus implements Consensus { blockchain: Blockchain | undefined algorithm: ConsensusAlgorithm - _ethash: Ethash | undefined + _ethash: MinimalEthashInterface - constructor() { + constructor(ethash: MinimalEthashInterface) { this.algorithm = ConsensusAlgorithm.Ethash + this._ethash = ethash } async validateConsensus(block: Block): Promise { - if (!this._ethash) { - throw new Error('blockchain not provided') - } const valid = await this._ethash.verifyPOW(block) if (!valid) { throw new Error('invalid POW') @@ -44,7 +46,7 @@ export class EthashConsensus implements Consensus { public async genesisInit(): Promise {} public async setup({ blockchain }: ConsensusOptions): Promise { this.blockchain = blockchain - this._ethash = new Ethash(this.blockchain!.db as any) + this._ethash.cacheDB = this.blockchain!.db as any } public async newBlock(): Promise {} } diff --git a/packages/blockchain/src/constructors.ts b/packages/blockchain/src/constructors.ts index ad310b9d8d..f48b9354eb 100644 --- a/packages/blockchain/src/constructors.ts +++ b/packages/blockchain/src/constructors.ts @@ -17,7 +17,7 @@ import type { Chain } from '@ethereumjs/common' export async function createBlockchain(opts: BlockchainOptions = {}) { const blockchain = new Blockchain(opts) - await blockchain.consensus.setup({ blockchain }) + await blockchain.consensus?.setup({ blockchain }) let stateRoot = opts.genesisBlock?.header.stateRoot ?? opts.genesisStateRoot if (stateRoot === undefined) { @@ -56,7 +56,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { DBSetBlockOrHeader(genesisBlock).map((op) => dbOps.push(op)) DBSaveLookups(genesisHash, BIGINT_0).map((op) => dbOps.push(op)) await blockchain.dbManager.batch(dbOps) - await blockchain.consensus.genesisInit(genesisBlock) + await blockchain.consensus?.genesisInit(genesisBlock) } // At this point, we can safely set the genesis: diff --git a/packages/blockchain/src/types.ts b/packages/blockchain/src/types.ts index 7ae0b75539..10599b6964 100644 --- a/packages/blockchain/src/types.ts +++ b/packages/blockchain/src/types.ts @@ -10,7 +10,7 @@ export type BlockchainEvents = { } export interface BlockchainInterface { - consensus: Consensus + consensus: Consensus | undefined /** * Adds a block to the blockchain. * @@ -132,6 +132,10 @@ export interface GenesisOptions { genesisStateRoot?: Uint8Array } +export type ConsensusDict = { + [consensusAlgorithm: ConsensusAlgorithm | string]: Consensus +} + /** * This are the options that the Blockchain constructor can receive. */ @@ -161,17 +165,6 @@ export interface BlockchainOptions extends GenesisOptions { */ db?: DB - /** - * This flags indicates if a block should be validated along the consensus algorithm - * or protocol used by the chain, e.g. by verifying the PoW on the block. - * - * Supported consensus types and algorithms (taken from the `Common` instance): - * - 'pow' with 'ethash' algorithm (validates the proof-of-work) - * - 'poa' with 'clique' algorithm (verifies the block signatures) - * Default: `true`. - */ - validateConsensus?: boolean - /** * This flag indicates if protocol-given consistency checks on * block headers and included uncles and transactions should be performed, @@ -181,9 +174,40 @@ export interface BlockchainOptions extends GenesisOptions { validateBlocks?: boolean /** - * Optional custom consensus that implements the {@link Consensus} class + * Validate the consensus with the respective consensus implementation passed + * to `consensusDict` (see respective option) `CapserConsensus` (which effectively + * does nothing) is available by default. + * + * For the build-in validation classes the following validations take place. + * - 'pow' with 'ethash' algorithm (validates the proof-of-work) + * - 'poa' with 'clique' algorithm (verifies the block signatures) + * Default: `false`. + */ + validateConsensus?: boolean + + /** + * Optional dictionary with consensus objects (adhering to the {@link Consensus} interface) + * if consensus validation is wished for certain consensus algorithms. + * + * Since consensus validation moved to the Ethereum consensus layer with Proof-of-Stake + * consensus is not validated by default. For `ConsensusAlgorithm.Ethash` and + * `ConsensusAlgorith.Clique` consensus validation can be activated by passing in the + * respective consensus validation objects `EthashConsensus` or `CliqueConsensus`. + * + * ```ts + * import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' + * import type { ConsensusDict } from '@ethereumjs/blockchain' + * + * const consensusDict: ConsensusDict = {} + * consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() + * const blockchain = await createBlockchain({ common, consensusDict }) + * ``` + * + * Additionally it is possible to provide a fully custom consensus implementation. + * Note that this needs a custom `Common` object passed to the blockchain where + * the `ConsensusAlgorithm` string matches the string used here. */ - consensus?: Consensus + consensusDict?: ConsensusDict } /** diff --git a/packages/blockchain/test/blockValidation.spec.ts b/packages/blockchain/test/blockValidation.spec.ts index 2cdef214a8..a2ea9d0717 100644 --- a/packages/blockchain/test/blockValidation.spec.ts +++ b/packages/blockchain/test/blockValidation.spec.ts @@ -1,18 +1,21 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' -import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { Chain, Common, ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { RLP } from '@ethereumjs/rlp' import { KECCAK256_RLP, bytesToHex, randomBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, expect, it } from 'vitest' -import { createBlockchain } from '../src/index.js' +import { EthashConsensus, createBlockchain } from '../src/index.js' import { createBlock } from './util.js' +import type { ConsensusDict } from '../src/index.js' + describe('[Blockchain]: Block validation tests', () => { it('should throw if an uncle is included before', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -39,7 +42,7 @@ describe('[Blockchain]: Block validation tests', () => { it('should throw if the uncle parent block is not part of the canonical chain', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -66,7 +69,7 @@ describe('[Blockchain]: Block validation tests', () => { it('should throw if the uncle is too old', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -99,7 +102,7 @@ describe('[Blockchain]: Block validation tests', () => { it('should throw if uncle is too young', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -120,8 +123,10 @@ describe('[Blockchain]: Block validation tests', () => { }) it('should throw if the uncle header is invalid', async () => { + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common, validateConsensus: false, consensusDict }) const genesis = blockchain.genesisBlock @@ -155,7 +160,7 @@ describe('[Blockchain]: Block validation tests', () => { it('throws if uncle is a canonical block', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -178,7 +183,7 @@ describe('[Blockchain]: Block validation tests', () => { it('successfully validates uncles', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock @@ -204,7 +209,7 @@ describe('[Blockchain]: Block validation tests', () => { hardfork: Hardfork.London, }) - const blockchain = await createBlockchain({ common, validateConsensus: false }) + const blockchain = await createBlockchain({ common }) const genesis = blockchain.genesisBlock // Small hack to hack in the activation block number @@ -300,7 +305,6 @@ describe('[Blockchain]: Block validation tests', () => { const blockchain = await createBlockchain({ common, - validateConsensus: false, validateBlocks: false, }) @@ -389,7 +393,6 @@ describe('EIP 7685: requests field validation tests', () => { }) const blockchain = await createBlockchain({ common, - validateConsensus: false, }) const block = createBlockFromBlockData( { diff --git a/packages/blockchain/test/clique.spec.ts b/packages/blockchain/test/clique.spec.ts index 832a8b2b7e..2b05a42cb3 100644 --- a/packages/blockchain/test/clique.spec.ts +++ b/packages/blockchain/test/clique.spec.ts @@ -10,11 +10,10 @@ import { import { Address, concatBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { CLIQUE_NONCE_AUTH, CLIQUE_NONCE_DROP } from '../src/consensus/clique.js' +import { CLIQUE_NONCE_AUTH, CLIQUE_NONCE_DROP, CliqueConsensus } from '../src/consensus/clique.js' import { createBlockchain } from '../src/index.js' -import type { CliqueConsensus } from '../src/consensus/clique.js' -import type { Blockchain } from '../src/index.js' +import type { Blockchain, ConsensusDict } from '../src/index.js' import type { Block } from '@ethereumjs/block' import type { CliqueConfig } from '@ethereumjs/common' @@ -91,9 +90,13 @@ const initWithSigners = async (signers: Signer[], common?: Common) => { ) blocks.push(genesisBlock) + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() + const blockchain = await createBlockchain({ validateBlocks: true, validateConsensus: true, + consensusDict, genesisBlock, common, }) @@ -191,7 +194,9 @@ const addNextBlock = async ( describe('Clique: Initialization', () => { it('should initialize a clique blockchain', async () => { const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Chainstart }) - const blockchain = await createBlockchain({ common }) + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() + const blockchain = await createBlockchain({ common, consensusDict }) const head = await blockchain.getIteratorHead() assert.deepEqual(head.hash(), blockchain.genesisBlock.hash(), 'correct genesis hash') diff --git a/packages/blockchain/test/customConsensus.spec.ts b/packages/blockchain/test/customConsensus.spec.ts index 23dc717441..1a82b93e50 100644 --- a/packages/blockchain/test/customConsensus.spec.ts +++ b/packages/blockchain/test/customConsensus.spec.ts @@ -3,9 +3,11 @@ import { Common, Hardfork } from '@ethereumjs/common' import { bytesToHex } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EthashConsensus, createBlockchain } from '../src/index.js' +import { createBlockchain } from '../src/index.js' -import type { Consensus } from '../src/index.js' +import * as testnet from './testdata/testnet.json' + +import type { Consensus, ConsensusDict } from '../src/index.js' import type { Block, BlockHeader } from '@ethereumjs/block' class fibonacciConsensus implements Consensus { @@ -41,12 +43,15 @@ class fibonacciConsensus implements Consensus { } } +testnet.default.consensus.algorithm = 'fibonacci' +const consensusDict: ConsensusDict = {} +consensusDict['fibonacci'] = new fibonacciConsensus() + describe('Optional consensus parameter in blockchain constructor', () => { it('blockchain constructor should work with custom consensus', async () => { - const common = new Common({ chain: 'mainnet', hardfork: Hardfork.Chainstart }) - const consensus = new fibonacciConsensus() + const common = new Common({ chain: testnet, hardfork: Hardfork.Chainstart }) try { - const blockchain = await createBlockchain({ common, consensus }) + const blockchain = await createBlockchain({ common, validateConsensus: true, consensusDict }) assert.equal( (blockchain.consensus as fibonacciConsensus).algorithm, 'fibonacciConsensus', @@ -60,9 +65,8 @@ describe('Optional consensus parameter in blockchain constructor', () => { describe('Custom consensus validation rules', () => { it('should validat custom consensus rules', async () => { - const common = new Common({ chain: 'mainnet', hardfork: Hardfork.Chainstart }) - const consensus = new fibonacciConsensus() - const blockchain = await createBlockchain({ common, consensus }) + const common = new Common({ chain: testnet, hardfork: Hardfork.Chainstart }) + const blockchain = await createBlockchain({ common, validateConsensus: true, consensusDict }) const block = createBlockFromBlockData( { header: { @@ -138,9 +142,8 @@ describe('Custom consensus validation rules', () => { describe('consensus transition checks', () => { it('should transition correctly', async () => { - const common = new Common({ chain: 'mainnet', hardfork: Hardfork.Chainstart }) - const consensus = new fibonacciConsensus() - const blockchain = await createBlockchain({ common, consensus }) + const common = new Common({ chain: testnet, hardfork: Hardfork.Chainstart }) + const blockchain = await createBlockchain({ common, validateConsensus: true, consensusDict }) try { await blockchain.checkAndTransitionHardForkByNumber(5n) @@ -151,8 +154,7 @@ describe('consensus transition checks', () => { ) } - blockchain.consensus = new EthashConsensus() - blockchain.common.consensusAlgorithm = () => 'fibonacci' + blockchain.common.consensusAlgorithm = () => 'ethash' try { await blockchain.checkAndTransitionHardForkByNumber(5n) @@ -160,11 +162,7 @@ describe('consensus transition checks', () => { 'checkAndTransitionHardForkByNumber should throw when using standard consensus (ethash, clique, casper) but consensus algorithm defined in common is different' ) } catch (err: any) { - assert.equal( - err.message, - 'consensus algorithm fibonacci not supported', - `checkAndTransitionHardForkByNumber correctly throws when using standard consensus (ethash, clique, casper) but consensus algorithm defined in common is different, error=${err.message}` - ) + assert.ok(err.message.includes('Consensus object for ethash must be passed')) } }) }) diff --git a/packages/blockchain/test/pos.spec.ts b/packages/blockchain/test/pos.spec.ts index 4ad1c33d5c..406ebbe122 100644 --- a/packages/blockchain/test/pos.spec.ts +++ b/packages/blockchain/test/pos.spec.ts @@ -63,7 +63,6 @@ describe('Proof of Stake - inserting blocks into blockchain', () => { it('should pass', async () => { const blockchain = await createBlockchain({ validateBlocks: true, - validateConsensus: false, common: s.common, hardforkByHeadBlockNumber: true, }) diff --git a/packages/blockchain/test/reorg.spec.ts b/packages/blockchain/test/reorg.spec.ts index 5873765d12..fdbaf78ff6 100644 --- a/packages/blockchain/test/reorg.spec.ts +++ b/packages/blockchain/test/reorg.spec.ts @@ -1,14 +1,14 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { Chain, Common, ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' import { Address, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { CLIQUE_NONCE_AUTH } from '../src/consensus/clique.js' +import { CLIQUE_NONCE_AUTH, CliqueConsensus } from '../src/consensus/clique.js' import { createBlockchain } from '../src/index.js' import { generateConsecutiveBlock } from './util.js' -import type { CliqueConsensus } from '../src/consensus/clique.js' +import type { ConsensusDict } from '../src/index.js' import type { Block } from '@ethereumjs/block' describe('reorg tests', () => { @@ -71,9 +71,13 @@ describe('reorg tests', () => { { header: { extraData: new Uint8Array(97) } }, { common } ) + + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() const blockchain = await createBlockchain({ validateBlocks: false, validateConsensus: false, + consensusDict, common, genesisBlock, }) diff --git a/packages/blockchain/test/util.ts b/packages/blockchain/test/util.ts index 2d519f85dd..bebc96fdce 100644 --- a/packages/blockchain/test/util.ts +++ b/packages/blockchain/test/util.ts @@ -53,7 +53,6 @@ export const generateBlockchain = async (numberOfBlocks: number, genesis?: Block const blockchain = await createBlockchain({ validateBlocks: true, - validateConsensus: false, genesisBlock: genesis ?? blocks[0], }) try { diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 67a930d40e..6e692ca1e9 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node import { createBlockFromValuesArray } from '@ethereumjs/block' -import { createBlockchain } from '@ethereumjs/blockchain' +import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, @@ -63,6 +63,7 @@ import type { FullEthereumService } from '../src/service/index.js' import type { ClientOpts } from '../src/types.js' import type { RPCArgs } from './startRpc.js' import type { Block, BlockBytes } from '@ethereumjs/block' +import type { ConsensusDict } from '@ethereumjs/blockchain' import type { CustomCrypto } from '@ethereumjs/common' import type { GenesisState, PrefixedHexString } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' @@ -636,14 +637,21 @@ async function startClient( let blockchain if (genesisMeta.genesisState !== undefined || genesisMeta.genesisStateRoot !== undefined) { - const validateConsensus = config.chainCommon.consensusAlgorithm() === ConsensusAlgorithm.Clique + let validateConsensus = false + const consensusDict: ConsensusDict = {} + if (config.chainCommon.consensusAlgorithm() === ConsensusAlgorithm.Clique) { + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() + validateConsensus = true + } + blockchain = await createBlockchain({ db: new LevelDB(dbs.chainDB), ...genesisMeta, common: config.chainCommon, hardforkByHeadBlockNumber: true, - validateConsensus, validateBlocks: true, + validateConsensus, + consensusDict, genesisState: genesisMeta.genesisState, genesisStateRoot: genesisMeta.genesisStateRoot, }) diff --git a/packages/client/src/blockchain/chain.ts b/packages/client/src/blockchain/chain.ts index a2a8dbe50a..b2adafd7b7 100644 --- a/packages/client/src/blockchain/chain.ts +++ b/packages/client/src/blockchain/chain.ts @@ -1,5 +1,5 @@ import { BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' -import { createBlockchain } from '@ethereumjs/blockchain' +import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' import { ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' import { BIGINT_0, BIGINT_1, equalsBytes } from '@ethereumjs/util' @@ -8,7 +8,7 @@ import { Event } from '../types.js' import type { Config } from '../config.js' import type { Block } from '@ethereumjs/block' -import type { Blockchain } from '@ethereumjs/blockchain' +import type { Blockchain, ConsensusDict } from '@ethereumjs/blockchain' import type { DB, DBObject, GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' @@ -158,7 +158,9 @@ export class Chain { */ public static async create(options: ChainOptions) { let validateConsensus = false + const consensusDict: ConsensusDict = {} if (options.config.chainCommon.consensusAlgorithm() === ConsensusAlgorithm.Clique) { + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() validateConsensus = true } @@ -170,6 +172,7 @@ export class Chain { hardforkByHeadBlockNumber: true, validateBlocks: true, validateConsensus, + consensusDict, genesisState: options.genesisState, genesisStateRoot: options.genesisStateRoot, })) @@ -448,7 +451,7 @@ export class Chain { td, b.header.timestamp ) - await this.blockchain.consensus.setup({ blockchain: this.blockchain }) + await this.blockchain.consensus?.setup({ blockchain: this.blockchain }) } const block = createBlockFromValuesArray(b.raw(), { diff --git a/packages/client/test/integration/merge.spec.ts b/packages/client/test/integration/merge.spec.ts index 5e07abd0f0..f9702dcaec 100644 --- a/packages/client/test/integration/merge.spec.ts +++ b/packages/client/test/integration/merge.spec.ts @@ -1,5 +1,5 @@ import { BlockHeader } from '@ethereumjs/block' -import { createBlockchain } from '@ethereumjs/blockchain' +import { CliqueConsensus, EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Chain as ChainCommon, ConsensusAlgorithm, @@ -7,6 +7,7 @@ import { Hardfork, createCustomCommon, } from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { Address, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -18,7 +19,7 @@ import { Event } from '../../src/types.js' import { MockServer } from './mocks/mockserver.js' import { destroy, setup } from './util.js' -import type { CliqueConsensus } from '@ethereumjs/blockchain' +import type { ConsensusDict } from '@ethereumjs/blockchain' import type { Common } from '@ethereumjs/common' const commonPoA = createCustomCommon( @@ -74,10 +75,14 @@ const accounts: [Address, Uint8Array][] = [ async function minerSetup(common: Common): Promise<[MockServer, FullEthereumService]> { const config = new Config({ common, accountCache: 10000, storageCache: 1000 }) const server = new MockServer({ config }) as any + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() + consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) const blockchain = await createBlockchain({ common, validateBlocks: false, validateConsensus: false, + consensusDict, }) ;(blockchain.consensus as CliqueConsensus).cliqueActiveSigners = () => [accounts[0][0]] // stub const serviceConfig = new Config({ diff --git a/packages/client/test/integration/miner.spec.ts b/packages/client/test/integration/miner.spec.ts index 64d7dd98d7..a92685eedf 100644 --- a/packages/client/test/integration/miner.spec.ts +++ b/packages/client/test/integration/miner.spec.ts @@ -1,4 +1,4 @@ -import { createBlockchain } from '@ethereumjs/blockchain' +import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Chain as ChainCommon, Common, @@ -18,7 +18,7 @@ import { Event } from '../../src/types.js' import { MockServer } from './mocks/mockserver.js' import { destroy, setup } from './util.js' -import type { CliqueConsensus } from '@ethereumjs/blockchain' +import type { ConsensusDict } from '@ethereumjs/blockchain' // Schedule london at 0 and also unset any past scheduled timestamp hardforks that might collide with test const hardforks = new Common({ chain: ChainCommon.Goerli }) @@ -52,10 +52,13 @@ async function minerSetup(): Promise<[MockServer, FullEthereumService]> { const config = new Config({ common, accountCache: 10000, storageCache: 1000 }) const server = new MockServer({ config }) as any + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() const blockchain = await createBlockchain({ common, validateBlocks: false, validateConsensus: false, + consensusDict, }) ;(blockchain.consensus as CliqueConsensus).cliqueActiveSigners = () => [accounts[0][0]] // stub const chain = await Chain.create({ config, blockchain }) diff --git a/packages/client/test/integration/util.ts b/packages/client/test/integration/util.ts index 16e9cf0e78..7d467505b4 100644 --- a/packages/client/test/integration/util.ts +++ b/packages/client/test/integration/util.ts @@ -1,4 +1,5 @@ -import { createBlockchain } from '@ethereumjs/blockchain' +import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' +import { type Common, ConsensusAlgorithm } from '@ethereumjs/common' import { MemoryLevel } from 'memory-level' import { Config } from '../../src/config.js' @@ -9,7 +10,7 @@ import { MockChain } from './mocks/mockchain.js' import { MockServer } from './mocks/mockserver.js' import type { SyncMode } from '../../src/config.js' -import type { Common } from '@ethereumjs/common' +import type { ConsensusDict } from '@ethereumjs/blockchain' interface SetupOptions { location?: string @@ -39,9 +40,12 @@ export async function setup( }) const server = new MockServer({ config, location }) as any + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus() const blockchain = await createBlockchain({ validateBlocks: false, validateConsensus: false, + consensusDict, common, }) diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index e86bcde817..3d52b2d2e7 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -12,8 +12,14 @@ import { createBlockFromBlockData, createBlockFromRLPSerializedBlock, } from '@ethereumjs/block' -import { Blockchain, createBlockchain } from '@ethereumjs/blockchain' -import { Common, ConsensusType } from '@ethereumjs/common' +import { + Blockchain, + ConsensusDict, + createBlockchain, + EthashConsensus, +} from '@ethereumjs/blockchain' +import { Common, ConsensusAlgorithm, ConsensusType } from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { VM } from '@ethereumjs/vm' import testData from './helpers/blockchain-mock-data.json' @@ -25,10 +31,13 @@ async function main() { const genesisBlock = createBlockFromBlockData({ header: testData.genesisBlockHeader }, { common }) + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) const blockchain = await createBlockchain({ common, - validateConsensus: validatePow, validateBlocks, + validateConsensus: validatePow, + consensusDict, genesisBlock, }) diff --git a/packages/vm/package.json b/packages/vm/package.json index 4179f435db..b862d625d1 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -77,6 +77,7 @@ "ethereum-cryptography": "^2.2.1" }, "devDependencies": { + "@ethereumjs/ethash": "^3.0.3", "@ethersproject/abi": "^5.0.12", "@types/benchmark": "^1.0.33", "@types/core-js": "^2.5.0", diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index 6d8a4af233..9b385469ee 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -1,13 +1,22 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { createBlockchain } from '@ethereumjs/blockchain' -import { Chain, Common, Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' +import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' +import { + Chain, + Common, + ConsensusAlgorithm, + Hardfork, + createCommonFromGethGenesis, +} from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, concatBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../src/vm' +import { VM } from '../../src/vm.js' -import { setBalance } from './utils' +import { setBalance } from './utils.js' + +import type { ConsensusDict } from '@ethereumjs/blockchain' const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109') const pKeyAddress = Address.fromPrivateKey(privateKey) @@ -81,7 +90,15 @@ describe('BlockBuilder', () => { it('should correctly seal a PoW block', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) const genesisBlock = createBlockFromBlockData({ header: { gasLimit: 50000 } }, { common }) - const blockchain = await createBlockchain({ genesisBlock, common, validateConsensus: false }) + + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) + const blockchain = await createBlockchain({ + genesisBlock, + common, + validateConsensus: false, + consensusDict, + }) const vm = await VM.create({ common, blockchain }) await setBalance(vm, pKeyAddress) @@ -107,7 +124,7 @@ describe('BlockBuilder', () => { assert.deepEqual(block.header.mixHash, sealOpts.mixHash) assert.deepEqual(block.header.nonce, sealOpts.nonce) - assert.doesNotThrow(async () => vm.blockchain.consensus.validateDifficulty(block.header)) + assert.doesNotThrow(async () => vm.blockchain.consensus!.validateDifficulty(block.header)) }) it('should correctly seal a PoA block', async () => { diff --git a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts index b8f2b50928..48d911100c 100644 --- a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts +++ b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts @@ -1,6 +1,7 @@ import { createBlockFromBlockData, createBlockFromRLPSerializedBlock } from '@ethereumjs/block' -import { createBlockchain } from '@ethereumjs/blockchain' +import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' import { ConsensusAlgorithm } from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { RLP } from '@ethereumjs/rlp' import { DefaultStateManager } from '@ethereumjs/statemanager' import { Trie } from '@ethereumjs/trie' @@ -15,11 +16,11 @@ import { toBytes, } from '@ethereumjs/util' -import { VM } from '../../../src/vm' -import { setupPreConditions, verifyPostConditions } from '../../util' +import { VM } from '../../../src/vm.js' +import { setupPreConditions, verifyPostConditions } from '../../util.js' import type { Block } from '@ethereumjs/block' -import type { EthashConsensus } from '@ethereumjs/blockchain' +import type { ConsensusDict } from '@ethereumjs/blockchain' import type { Common } from '@ethereumjs/common' import type { PrefixedHexString } from '@ethereumjs/util' import type * as tape from 'tape' @@ -73,10 +74,13 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes t.deepEquals(genesisBlock.serialize(), rlp, 'correct genesis RLP') } + const consensusDict: ConsensusDict = {} + consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) let blockchain = await createBlockchain({ common, validateBlocks: true, validateConsensus: validatePow, + consensusDict, genesisBlock, }) From 41931d6d737f83c107a9927fbc85dc820cf8f0db Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Wed, 17 Jul 2024 13:16:25 +0200 Subject: [PATCH 03/58] Ensure EthJS and Grandine talk (#3511) * jwt-simple: ensure unpadded payloads are accepted * jwt-simple: ensure encoded jwts are also unpadded --- packages/client/src/ext/jwt-simple.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/ext/jwt-simple.ts b/packages/client/src/ext/jwt-simple.ts index 9357ef52c3..45ce840259 100644 --- a/packages/client/src/ext/jwt-simple.ts +++ b/packages/client/src/ext/jwt-simple.ts @@ -7,7 +7,7 @@ * module dependencies */ import { bytesToUtf8, utf8ToBytes } from '@ethereumjs/util' -import { base64url } from '@scure/base' +import { base64url, base64urlnopad } from '@scure/base' import crypto from 'crypto' /** @@ -121,7 +121,7 @@ const decode = function jwt_decode( // base64 decode and parse JSON const header = JSON.parse(bytesToUtf8(base64url.decode(headerSeg))) - const payload = JSON.parse(bytesToUtf8(base64url.decode(payloadSeg))) + const payload = JSON.parse(bytesToUtf8(base64urlnopad.decode(payloadSeg))) if (!noVerify) { if (!algorithm && /BEGIN( RSA)? PUBLIC KEY/.test(key.toString())) { @@ -193,7 +193,7 @@ const encode = function jwt_encode( // create segments, all segments should be base64 string const segments = [] segments.push(base64url.encode(utf8ToBytes(JSON.stringify(header)))) - segments.push(base64url.encode(utf8ToBytes(JSON.stringify(payload)))) + segments.push(base64urlnopad.encode(utf8ToBytes(JSON.stringify(payload)))) segments.push(sign(segments.join('.'), key, signingMethod, signingType)) return segments.join('.') From df31a69f96c6ec93dcf417f046de0da936046dba Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Wed, 17 Jul 2024 14:43:23 +0200 Subject: [PATCH 04/58] Common: Simplify EIP and Hardfork Config Structure (#3512) * Remove comment, url, status from hardfork and EIP configs (moved to code docs) * Minor --- packages/common/src/eips.ts | 299 +++++++++++++--------- packages/common/src/hardforks.ts | 174 +++++++------ packages/common/src/types.ts | 3 - packages/common/test/customChains.spec.ts | 9 +- 4 files changed, 284 insertions(+), 201 deletions(-) diff --git a/packages/common/src/eips.ts b/packages/common/src/eips.ts index b6016ba84b..81a645c1f5 100644 --- a/packages/common/src/eips.ts +++ b/packages/common/src/eips.ts @@ -6,18 +6,13 @@ type EIPsDict = { [key: string]: EIPConfig } -enum Status { - Stagnant = 'stagnant', - Draft = 'draft', - Review = 'review', - Final = 'final', -} - export const EIPs: EIPsDict = { + /** + * Description : Transient storage opcodes + * URL : https://eips.ethereum.org/EIPS/eip-1153 + * Status : Final + */ 1153: { - comment: 'Transient storage opcodes', - url: 'https://eips.ethereum.org/EIPS/eip-1153', - status: Status.Review, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], gasPrices: { @@ -25,10 +20,12 @@ export const EIPs: EIPsDict = { tload: 100, // Base fee of the TLOAD opcode }, }, + /** + * Description : Fee market change for ETH 1.0 chain + * URL : https://eips.ethereum.org/EIPS/eip-1559 + * Status : Final + */ 1559: { - comment: 'Fee market change for ETH 1.0 chain', - url: 'https://eips.ethereum.org/EIPS/eip-1559', - status: Status.Final, minimumHardfork: Hardfork.Berlin, requiredEIPs: [2930], gasConfig: { @@ -37,20 +34,24 @@ export const EIPs: EIPsDict = { initialBaseFee: 1000000000, // Initial base fee on first EIP1559 block }, }, + /** + * Description : ModExp gas cost + * URL : https://eips.ethereum.org/EIPS/eip-2565 + * Status : Final + */ 2565: { - comment: 'ModExp gas cost', - url: 'https://eips.ethereum.org/EIPS/eip-2565', - status: Status.Final, minimumHardfork: Hardfork.Byzantium, requiredEIPs: [], gasPrices: { modexpGquaddivisor: 3, // Gquaddivisor from modexp precompile for gas calculation }, }, + /** + * Description : BLS12-381 precompiles + * URL : https://eips.ethereum.org/EIPS/eip-2537 + * Status : Review + */ 2537: { - comment: 'BLS12-381 precompiles', - url: 'https://eips.ethereum.org/EIPS/eip-2537', - status: 'Draft', minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], gasConfig: {}, @@ -67,17 +68,21 @@ export const EIPs: EIPsDict = { vm: {}, pow: {}, }, + /** + * Description : Typed Transaction Envelope + * URL : https://eips.ethereum.org/EIPS/eip-2718 + * Status : Final + */ 2718: { - comment: 'Typed Transaction Envelope', - url: 'https://eips.ethereum.org/EIPS/eip-2718', - status: Status.Final, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], }, + /** + * Description : Gas cost increases for state access opcodes + * URL : https://eips.ethereum.org/EIPS/eip-2929 + * Status : Final + */ 2929: { - comment: 'Gas cost increases for state access opcodes', - url: 'https://eips.ethereum.org/EIPS/eip-2929', - status: Status.Final, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], gasPrices: { @@ -101,10 +106,12 @@ export const EIPs: EIPsDict = { sstore: 0, // Base fee of the SSTORE opcode }, }, + /** + * Description : Optional access lists + * URL : https://eips.ethereum.org/EIPS/eip-2930 + * Status : Final + */ 2930: { - comment: 'Optional access lists', - url: 'https://eips.ethereum.org/EIPS/eip-2930', - status: Status.Final, minimumHardfork: Hardfork.Istanbul, requiredEIPs: [2718, 2929], gasPrices: { @@ -112,10 +119,12 @@ export const EIPs: EIPsDict = { accessListAddressCost: 2400, // Gas cost per storage key in an Access List transaction }, }, + /** + * Description : Save historical block hashes in state (Verkle related usage, UNSTABLE) + * URL : https://github.com/gballet/EIPs/pull/3/commits/2e9ac09a142b0d9fb4db0b8d4609f92e5d9990c5 + * Status : Draft + */ 2935: { - comment: 'Save historical block hashes in state (Verkle related usage, UNSTABLE)', - url: 'https://github.com/gballet/EIPs/pull/3/commits/2e9ac09a142b0d9fb4db0b8d4609f92e5d9990c5', - status: Status.Draft, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], vm: { @@ -123,10 +132,12 @@ export const EIPs: EIPsDict = { historyServeWindow: BigInt(8192), // The amount of blocks to be served by the historical blockhash contract }, }, + /** + * Description : AUTH and AUTHCALL opcodes + * URL : https://github.com/ethereum/EIPs/commit/eca4416ff3c025fcb6ec8cd4eac481e74e108481 + * Status : Review + */ 3074: { - comment: 'AUTH and AUTHCALL opcodes', - url: 'https://github.com/ethereum/EIPs/commit/eca4416ff3c025fcb6ec8cd4eac481e74e108481', - status: Status.Review, minimumHardfork: Hardfork.London, requiredEIPs: [], gasPrices: { @@ -135,20 +146,24 @@ export const EIPs: EIPsDict = { authcallValueTransfer: 6700, // Paid for CALL when the value transfer is non-zero }, }, + /** + * Description : BASEFEE opcode + * URL : https://eips.ethereum.org/EIPS/eip-3198 + * Status : Final + */ 3198: { - comment: 'BASEFEE opcode', - url: 'https://eips.ethereum.org/EIPS/eip-3198', - status: Status.Final, minimumHardfork: Hardfork.London, requiredEIPs: [], gasPrices: { basefee: 2, // Gas cost of the BASEFEE opcode }, }, + /** + * Description : Reduction in refunds + * URL : https://eips.ethereum.org/EIPS/eip-3529 + * Status : Final + */ 3529: { - comment: 'Reduction in refunds', - url: 'https://eips.ethereum.org/EIPS/eip-3529', - status: Status.Final, minimumHardfork: Hardfork.Berlin, requiredEIPs: [2929], gasConfig: { @@ -159,76 +174,90 @@ export const EIPs: EIPsDict = { sstoreClearRefundEIP2200: 4800, // Once per SSTORE operation for clearing an originally existing storage slot }, }, + /** + * Description : EVM Object Format (EOF) v1 + * URL : https://eips.ethereum.org/EIPS/eip-3540 + * Status : Review + */ 3540: { - comment: 'EVM Object Format (EOF) v1', - url: 'https://eips.ethereum.org/EIPS/eip-3540', - status: Status.Review, minimumHardfork: Hardfork.London, requiredEIPs: [3541], }, + /** + * Description : Reject new contracts starting with the 0xEF byte + * URL : https://eips.ethereum.org/EIPS/eip-3541 + * Status : Final + */ 3541: { - comment: 'Reject new contracts starting with the 0xEF byte', - url: 'https://eips.ethereum.org/EIPS/eip-3541', - status: Status.Final, minimumHardfork: Hardfork.Berlin, requiredEIPs: [], }, + /** + * Description : Difficulty Bomb Delay to December 1st 2021 + * URL : https://eips.ethereum.org/EIPS/eip-3554 + * Status : Final + */ 3554: { - comment: 'Difficulty Bomb Delay to December 1st 2021', - url: 'https://eips.ethereum.org/EIPS/eip-3554', - status: Status.Final, minimumHardfork: Hardfork.MuirGlacier, requiredEIPs: [], pow: { difficultyBombDelay: 9500000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description : Reject transactions from senders with deployed code + * URL : https://eips.ethereum.org/EIPS/eip-3607 + * Status : Final + */ 3607: { - comment: 'Reject transactions from senders with deployed code', - url: 'https://eips.ethereum.org/EIPS/eip-3607', - status: Status.Final, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], }, + /** + * Description : Warm COINBASE + * URL : https://eips.ethereum.org/EIPS/eip-3651 + * Status : Final + */ 3651: { - comment: 'Warm COINBASE', - url: 'https://eips.ethereum.org/EIPS/eip-3651', - status: Status.Review, minimumHardfork: Hardfork.London, requiredEIPs: [2929], }, + /** + * Description : EOF - Code Validation + * URL : https://eips.ethereum.org/EIPS/eip-3670 + * Status : Review + */ 3670: { - comment: 'EOF - Code Validation', - url: 'https://eips.ethereum.org/EIPS/eip-3670', - status: 'Review', minimumHardfork: Hardfork.London, requiredEIPs: [3540], - gasConfig: {}, - gasPrices: {}, - vm: {}, - pow: {}, }, + /** + * Description : Upgrade consensus to Proof-of-Stake + * URL : https://eips.ethereum.org/EIPS/eip-3675 + * Status : Final + */ 3675: { - comment: 'Upgrade consensus to Proof-of-Stake', - url: 'https://eips.ethereum.org/EIPS/eip-3675', - status: Status.Final, minimumHardfork: Hardfork.London, requiredEIPs: [], }, + /** + * Description : PUSH0 instruction + * URL : https://eips.ethereum.org/EIPS/eip-3855 + * Status : Final + */ 3855: { - comment: 'PUSH0 instruction', - url: 'https://eips.ethereum.org/EIPS/eip-3855', - status: Status.Review, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], gasPrices: { push0: 2, // Base fee of the PUSH0 opcode }, }, + /** + * Description : Limit and meter initcode + * URL : https://eips.ethereum.org/EIPS/eip-3860 + * Status : Final + */ 3860: { - comment: 'Limit and meter initcode', - url: 'https://eips.ethereum.org/EIPS/eip-3860', - status: Status.Review, minimumHardfork: Hardfork.SpuriousDragon, requiredEIPs: [], gasPrices: { @@ -238,30 +267,36 @@ export const EIPs: EIPsDict = { maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract }, }, + /** + * Description : Difficulty Bomb Delay to June 2022 + * URL : https://eips.ethereum.org/EIPS/eip-4345 + * Status : Final + */ 4345: { - comment: 'Difficulty Bomb Delay to June 2022', - url: 'https://eips.ethereum.org/EIPS/eip-4345', - status: Status.Final, minimumHardfork: Hardfork.London, requiredEIPs: [], pow: { difficultyBombDelay: 10700000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description : Supplant DIFFICULTY opcode with PREVRANDAO + * URL : https://eips.ethereum.org/EIPS/eip-4399 + * Status : Final + */ 4399: { - comment: 'Supplant DIFFICULTY opcode with PREVRANDAO', - url: 'https://eips.ethereum.org/EIPS/eip-4399', - status: Status.Review, minimumHardfork: Hardfork.London, requiredEIPs: [], gasPrices: { prevrandao: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) }, }, + /** + * Description : Beacon block root in the EVM + * URL : https://eips.ethereum.org/EIPS/eip-4788 + * Status : Final + */ 4788: { - comment: 'Beacon block root in the EVM', - url: 'https://eips.ethereum.org/EIPS/eip-4788', - status: Status.Draft, minimumHardfork: Hardfork.Cancun, requiredEIPs: [], gasPrices: {}, @@ -269,10 +304,12 @@ export const EIPs: EIPsDict = { historicalRootsLength: 8191, // The modulo parameter of the beaconroot ring buffer in the beaconroot statefull precompile }, }, + /** + * Description : Shard Blob Transactions + * URL : https://eips.ethereum.org/EIPS/eip-4844 + * Status : Final + */ 4844: { - comment: 'Shard Blob Transactions', - url: 'https://eips.ethereum.org/EIPS/eip-4844', - status: Status.Draft, minimumHardfork: Hardfork.Paris, requiredEIPs: [1559, 2718, 2930, 4895], gasConfig: { @@ -292,51 +329,63 @@ export const EIPs: EIPsDict = { fieldElementsPerBlob: 4096, // The number of field elements allowed per blob }, }, + /** + * Description : Beacon chain push withdrawals as operations + * URL : https://eips.ethereum.org/EIPS/eip-4895 + * Status : Final + */ 4895: { - comment: 'Beacon chain push withdrawals as operations', - url: 'https://eips.ethereum.org/EIPS/eip-4895', - status: Status.Review, minimumHardfork: Hardfork.Paris, requiredEIPs: [], }, + /** + * Description : Delaying Difficulty Bomb to mid-September 2022 + * URL : https://eips.ethereum.org/EIPS/eip-5133 + * Status : Final + */ 5133: { - comment: 'Delaying Difficulty Bomb to mid-September 2022', - url: 'https://eips.ethereum.org/EIPS/eip-5133', - status: Status.Draft, minimumHardfork: Hardfork.GrayGlacier, requiredEIPs: [], pow: { difficultyBombDelay: 11400000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description : MCOPY - Memory copying instruction + * URL : https://eips.ethereum.org/EIPS/eip-5656 + * Status : Final + */ 5656: { - comment: 'MCOPY - Memory copying instruction', - url: 'https://eips.ethereum.org/EIPS/eip-5656', - status: Status.Draft, minimumHardfork: Hardfork.Shanghai, requiredEIPs: [], gasPrices: { mcopy: 3, // Base fee of the MCOPY opcode }, }, + /** + * Description : Supply validator deposits on chain + * URL : https://eips.ethereum.org/EIPS/eip-6110 + * Status : Review + */ 6110: { - comment: 'Supply validator deposits on chain', - url: 'https://eips.ethereum.org/EIPS/eip-6110', - status: Status.Draft, minimumHardfork: Hardfork.Cancun, requiredEIPs: [7685], }, + /** + * Description : SELFDESTRUCT only in same transaction + * URL : https://eips.ethereum.org/EIPS/eip-6780 + * Status : Final + */ 6780: { - comment: 'SELFDESTRUCT only in same transaction', - url: 'https://eips.ethereum.org/EIPS/eip-6780', - status: Status.Draft, minimumHardfork: Hardfork.London, requiredEIPs: [], }, + /** + * Description : Ethereum state using a unified verkle tree (experimental) + * URL : https://github.com/ethereum/EIPs/pull/6800 + * Status : Draft + */ 6800: { - comment: 'Ethereum state using a unified verkle tree (experimental)', - url: 'https://github.com/ethereum/EIPs/pull/6800', - status: Status.Draft, minimumHardfork: Hardfork.London, requiredEIPs: [], gasPrices: { @@ -349,10 +398,12 @@ export const EIPs: EIPsDict = { historyStorageAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The address where the historical blockhashes are stored }, }, + /** + * Description : Execution layer triggerable withdrawals (experimental) + * URL : https://github.com/ethereum/EIPs/blob/3b5fcad6b35782f8aaeba7d4ac26004e8fbd720f/EIPS/eip-7002.md + * Status : Review + */ 7002: { - comment: 'Execution layer triggerable withdrawals (experimental)', - url: 'https://github.com/ethereum/EIPs/blob/3b5fcad6b35782f8aaeba7d4ac26004e8fbd720f/EIPS/eip-7002.md', - status: Status.Draft, minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], vm: { @@ -370,10 +421,12 @@ export const EIPs: EIPsDict = { withdrawalRequestPredeployAddress: BigInt('0x00A3ca265EBcb825B45F985A16CEFB49958cE017'), // Address of the validator excess address }, }, + /** + * Description : Increase the MAX_EFFECTIVE_BALANCE -> Execution layer triggered consolidations (experimental) + * URL : https://eips.ethereum.org/EIPS/eip-7251 + * Status : Draft + */ 7251: { - comment: 'Execution layer triggered consolidations (experimental)', - url: 'https://eips.ethereum.org/EIPS/eip-7251', - status: Status.Draft, minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], vm: { @@ -382,29 +435,35 @@ export const EIPs: EIPsDict = { consolidationRequestPredeployAddress: BigInt('0x00b42dbF2194e931E80326D950320f7d9Dbeac02'), // Address of the consolidations contract }, }, + /** + * Description : BLOBBASEFEE opcode + * URL : https://eips.ethereum.org/EIPS/eip-7516 + * Status : Final + */ 7516: { - comment: 'BLOBBASEFEE opcode', - url: 'https://eips.ethereum.org/EIPS/eip-7516', - status: Status.Draft, minimumHardfork: Hardfork.Paris, requiredEIPs: [4844], gasPrices: { blobbasefee: 2, // Gas cost of the BLOBBASEFEE opcode }, }, + /** + * Description : General purpose execution layer requests + * URL : https://eips.ethereum.org/EIPS/eip-7685 + * Status : Review + */ 7685: { - comment: 'General purpose execution layer requests', - url: 'https://eips.ethereum.org/EIPS/eip-7685', - status: Status.Draft, // TODO: Set correct minimum hardfork minimumHardfork: Hardfork.Cancun, requiredEIPs: [3675], gasPrices: {}, }, + /** + * Description : Set EOA account code for one transaction + * URL : https://github.com/ethereum/EIPs/blob/62419ca3f45375db00b04a368ea37c0bfb05386a/EIPS/eip-7702.md + * Status : Review + */ 7702: { - comment: 'Set EOA account code for one transaction', - url: 'https://github.com/ethereum/EIPs/blob/62419ca3f45375db00b04a368ea37c0bfb05386a/EIPS/eip-7702.md', - status: Status.Review, // TODO: Set correct minimum hardfork minimumHardfork: Hardfork.Cancun, requiredEIPs: [2718, 2929, 2930], @@ -412,10 +471,12 @@ export const EIPs: EIPsDict = { perAuthBaseCost: 2500, // Gas cost of each authority item }, }, + /** + * Description : Use historical block hashes saved in state for BLOCKHASH + * URL : https://eips.ethereum.org/EIPS/eip-7709 + * Status : Final + */ 7709: { - comment: 'Use historical block hashes saved in state for BLOCKHASH', - url: 'https://eips.ethereum.org/EIPS/eip-7709', - status: Status.Draft, minimumHardfork: Hardfork.Chainstart, requiredEIPs: [2935], }, diff --git a/packages/common/src/hardforks.ts b/packages/common/src/hardforks.ts index 43d509f122..f10edd52aa 100644 --- a/packages/common/src/hardforks.ts +++ b/packages/common/src/hardforks.ts @@ -1,17 +1,13 @@ import type { HardforksDict } from './types.js' -export enum Status { - Draft = 'draft', - Review = 'review', - Final = 'final', -} - export const hardforks: HardforksDict = { + /** + * Description: Start of the Ethereum main chain + * URL : - + * Status : Final + */ chainstart: { name: 'chainstart', - comment: 'Start of the Ethereum main chain', - url: '', - status: Status.Final, gasConfig: { minGasLimit: 5000, // Minimum the gas limit may ever be gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations @@ -126,26 +122,32 @@ export const hardforks: HardforksDict = { difficultyBombDelay: 0, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description: Homestead hardfork with protocol and network changes + * URL : https://eips.ethereum.org/EIPS/eip-606 + * Status : Final + */ homestead: { name: 'homestead', - comment: 'Homestead hardfork with protocol and network changes', - url: 'https://eips.ethereum.org/EIPS/eip-606', - status: Status.Final, gasPrices: { delegatecall: 40, // Base fee of the DELEGATECALL opcode }, }, + /** + * Description: DAO rescue hardfork + * URL : https://eips.ethereum.org/EIPS/eip-779 + * Status : Final + */ dao: { name: 'dao', - comment: 'DAO rescue hardfork', - url: 'https://eips.ethereum.org/EIPS/eip-779', - status: Status.Final, }, + /** + * Description: Hardfork with gas cost changes for IO-heavy operations + * URL : https://eips.ethereum.org/EIPS/eip-608 + * Status : Final + */ tangerineWhistle: { name: 'tangerineWhistle', - comment: 'Hardfork with gas cost changes for IO-heavy operations', - url: 'https://eips.ethereum.org/EIPS/eip-608', - status: Status.Final, gasPrices: { sload: 200, // Once per SLOAD operation call: 700, // Once per CALL operation & message call transaction @@ -157,12 +159,13 @@ export const hardforks: HardforksDict = { selfdestruct: 5000, // Base fee of the SELFDESTRUCT opcode }, }, + /** + * Description: HF with EIPs for simple replay attack protection, EXP cost increase, state trie clearing, contract code size limit + * URL : https://eips.ethereum.org/EIPS/eip-607 + * Status : Final + */ spuriousDragon: { name: 'spuriousDragon', - comment: - 'HF with EIPs for simple replay attack protection, EXP cost increase, state trie clearing, contract code size limit', - url: 'https://eips.ethereum.org/EIPS/eip-607', - status: Status.Final, gasPrices: { expByte: 50, // Times ceil(log256(exponent)) for the EXP instruction }, @@ -170,11 +173,13 @@ export const hardforks: HardforksDict = { maxCodeSize: 24576, // Maximum length of contract code }, }, + /** + * Description: Hardfork with new precompiles, instructions and other protocol changes + * URL : https://eips.ethereum.org/EIPS/eip-609 + * Status : Final + */ byzantium: { name: 'byzantium', - comment: 'Hardfork with new precompiles, instructions and other protocol changes', - url: 'https://eips.ethereum.org/EIPS/eip-609', - status: Status.Final, gasPrices: { modexpGquaddivisor: 20, // Gquaddivisor from modexp precompile for gas calculation ecAdd: 500, // Gas costs for curve addition precompile @@ -191,11 +196,13 @@ export const hardforks: HardforksDict = { difficultyBombDelay: 3000000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description: Postponed hardfork including EIP-1283 (SSTORE gas metering changes) + * URL : https://eips.ethereum.org/EIPS/eip-1013 + * Status : Final + */ constantinople: { name: 'constantinople', - comment: 'Postponed hardfork including EIP-1283 (SSTORE gas metering changes)', - url: 'https://eips.ethereum.org/EIPS/eip-1013', - status: Status.Final, gasPrices: { netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero @@ -215,12 +222,13 @@ export const hardforks: HardforksDict = { difficultyBombDelay: 5000000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description: Aka constantinopleFix, removes EIP-1283, activate together with or after constantinople + * URL : https://eips.ethereum.org/EIPS/eip-1716 + * Status : Final + */ petersburg: { name: 'petersburg', - comment: - 'Aka constantinopleFix, removes EIP-1283, activate together with or after constantinople', - url: 'https://eips.ethereum.org/EIPS/eip-1716', - status: Status.Final, gasPrices: { netSstoreNoopGas: null, // Removed along EIP-1283 netSstoreInitGas: null, // Removed along EIP-1283 @@ -231,11 +239,13 @@ export const hardforks: HardforksDict = { netSstoreResetClearRefund: null, // Removed along EIP-1283 }, }, + /** + * Description: HF targeted for December 2019 following the Constantinople/Petersburg HF + * URL : https://eips.ethereum.org/EIPS/eip-1679 + * Status : Final + */ istanbul: { name: 'istanbul', - comment: 'HF targeted for December 2019 following the Constantinople/Petersburg HF', - url: 'https://eips.ethereum.org/EIPS/eip-1679', - status: Status.Final, gasConfig: {}, gasPrices: { blake2Round: 1, // Gas cost per round for the Blake2 F precompile @@ -259,48 +269,60 @@ export const hardforks: HardforksDict = { sload: 800, // Base fee of the SLOAD opcode }, }, + /** + * Description: HF to delay the difficulty bomb + * URL : https://eips.ethereum.org/EIPS/eip-2384 + * Status : Final + */ muirGlacier: { name: 'muirGlacier', - comment: 'HF to delay the difficulty bomb', - url: 'https://eips.ethereum.org/EIPS/eip-2384', - status: Status.Final, pow: { difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description: HF targeted for July 2020 following the Muir Glacier HF + * URL : https://eips.ethereum.org/EIPS/eip-2070 + * Status : Final + */ berlin: { name: 'berlin', - comment: 'HF targeted for July 2020 following the Muir Glacier HF', - url: 'https://eips.ethereum.org/EIPS/eip-2070', - status: Status.Final, eips: [2565, 2929, 2718, 2930], }, + /** + * Description: HF targeted for July 2021 following the Berlin fork + * URL : https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md + * Status : Final + */ london: { name: 'london', - comment: 'HF targeted for July 2021 following the Berlin fork', - url: 'https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md', - status: Status.Final, eips: [1559, 3198, 3529, 3541], }, + /** + * Description: HF to delay the difficulty bomb + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md + * Status : Final + */ arrowGlacier: { name: 'arrowGlacier', - comment: 'HF to delay the difficulty bomb', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md', - status: Status.Final, eips: [4345], }, + /** + * Description: Delaying the difficulty bomb to Mid September 2022 + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md + * Status : Final + */ grayGlacier: { name: 'grayGlacier', - comment: 'Delaying the difficulty bomb to Mid September 2022', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md', - status: Status.Final, eips: [5133], }, + /** + * Description: Hardfork to upgrade the consensus mechanism to Proof-of-Stake + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/merge.md + * Status : Final + */ paris: { name: 'paris', - comment: 'Hardfork to upgrade the consensus mechanism to Proof-of-Stake', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/merge.md', - status: Status.Final, consensus: { type: 'pos', algorithm: 'casper', @@ -308,43 +330,51 @@ export const hardforks: HardforksDict = { }, eips: [3675, 4399], }, + /** + * Description: Pre-merge hardfork to fork off non-upgraded clients + * URL : https://eips.ethereum.org/EIPS/eip-3675 + * Status : Final + */ mergeForkIdTransition: { name: 'mergeForkIdTransition', - comment: 'Pre-merge hardfork to fork off non-upgraded clients', - url: 'https://eips.ethereum.org/EIPS/eip-3675', - status: Status.Final, eips: [], }, + /** + * Description: Next feature hardfork after the merge hardfork having withdrawals, warm coinbase, push0, limit/meter initcode + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md + * Status : Final + */ shanghai: { name: 'shanghai', - comment: - 'Next feature hardfork after the merge hardfork having withdrawals, warm coinbase, push0, limit/meter initcode', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md', - status: Status.Final, eips: [3651, 3855, 3860, 4895], }, + /** + * Description: Next feature hardfork after shanghai, includes proto-danksharding EIP 4844 blobs + * (still WIP hence not for production use), transient storage opcodes, parent beacon block root + * availability in EVM, selfdestruct only in same transaction, and blob base fee opcode + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md + * Status : Final + */ cancun: { name: 'cancun', - comment: - 'Next feature hardfork after shanghai, includes proto-danksharding EIP 4844 blobs (still WIP hence not for production use), transient storage opcodes, parent beacon block root availability in EVM, selfdestruct only in same transaction, and blob base fee opcode', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md', - status: Status.Final, eips: [1153, 4844, 4788, 5656, 6780, 7516], }, + /** + * Description: Next feature hardfork after cancun, internally used for pectra testing/implementation (incomplete/experimental) + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/prague.md + * Status : Final + */ prague: { name: 'prague', - comment: - 'Next feature hardfork after cancun, internally used for pectra testing/implementation (incomplete/experimental)', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/prague.md', - status: Status.Draft, eips: [2537, 2935, 6110, 7002, 7251, 7685, 7702], }, + /** + * Description: Next feature hardfork after prague, internally used for verkle testing/implementation (incomplete/experimental) + * URL : https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/osaka.md + * Status : Final + */ osaka: { name: 'osaka', - comment: - 'Next feature hardfork after prague, internally used for verkle testing/implementation (incomplete/experimental)', - url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/osaka.md', - status: Status.Draft, eips: [2935, 6800], }, } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 8569e3cb80..a17d6b3d98 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -165,9 +165,6 @@ export interface HardforkByOpts { } export type EIPOrHFConfig = { - comment: string - url: string - status: string gasConfig?: { [key: string]: number | bigint | null } diff --git a/packages/common/test/customChains.spec.ts b/packages/common/test/customChains.spec.ts index 55b04a35c0..5efa8a83aa 100644 --- a/packages/common/test/customChains.spec.ts +++ b/packages/common/test/customChains.spec.ts @@ -1,7 +1,6 @@ import { BIGINT_0 } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { Status } from '../src/hardforks.js' import { Chain, Common, @@ -182,11 +181,9 @@ describe('[Common]: Custom chains', () => { it('customHardforks parameter: initialization and transition tests', () => { const c = createCustomCommon({ customHardforks: { + // Hardfork to test EIP 2935 testEIP2935Hardfork: { name: 'testEIP2935Hardfork', - comment: 'Hardfork to test EIP 2935', - url: '', - status: Status.Final, eips: [2935], }, }, @@ -234,11 +231,9 @@ describe('[Common]: Custom chains', () => { it('customHardforks: override params', () => { const c = createCustomCommon({ customHardforks: { + // Hardfork which changes the gas of STOP from 0 to 10 stop10Gas: { name: 'stop10Gas', - comment: 'Hardfork which changes the gas of STOP from 0 to 10', - url: '', - status: Status.Final, eips: [2935], vm: { stop: BigInt(10), From a9d4f0df86e9f49d87230371360a7fb1fa5a6cf1 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Thu, 18 Jul 2024 09:07:19 +0200 Subject: [PATCH 05/58] Tx: remove static TransactionFactory methods (#3514) * tx: remove TransactionFactory * tx: explicitly export methods * block: fix build * vm: fix tests * client: fix build / tests * apply changes to tests / examples * lint block package --------- Co-authored-by: ScottyPoi --- packages/block/src/constructors.ts | 21 +- packages/block/src/from-rpc.ts | 5 +- .../client/src/net/protocol/ethprotocol.ts | 7 +- packages/client/src/rpc/modules/eth.ts | 11 +- .../test/net/protocol/ethprotocol.spec.ts | 12 +- .../test/rpc/debug/storageRangeAt.spec.ts | 8 +- .../client/test/rpc/debug/traceCall.spec.ts | 4 +- .../test/rpc/debug/traceTransaction.spec.ts | 10 +- .../engine/getPayloadBodiesByHashV1.spec.ts | 10 +- .../engine/getPayloadBodiesByRangeV1.spec.ts | 10 +- .../test/rpc/engine/getPayloadV3.spec.ts | 4 +- .../test/rpc/engine/newPayloadV4.spec.ts | 4 +- .../client/test/rpc/engine/preimages.spec.ts | 4 +- .../client/test/rpc/eth/blobBaseFee.spec.ts | 4 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 6 +- .../test/rpc/eth/getTransactionCount.spec.ts | 4 +- .../client/test/rpc/txpool/content.spec.ts | 4 +- .../test/service/fullethereumservice.spec.ts | 12 +- packages/client/test/sim/4844-devnet.spec.ts | 4 +- .../devp2p/examples/peer-communication.ts | 4 +- .../statemanager/test/rpcStateManager.spec.ts | 4 +- .../test/statelessVerkleStateManager.spec.ts | 4 +- packages/tx/examples/txFactory.ts | 4 +- packages/tx/src/index.ts | 8 +- packages/tx/src/transactionFactory.ts | 213 +++++++++--------- packages/tx/test/eip3860.spec.ts | 19 +- packages/tx/test/eip4844.spec.ts | 4 +- packages/tx/test/fromRpc.spec.ts | 17 +- packages/tx/test/inputValue.spec.ts | 8 +- packages/tx/test/transactionFactory.spec.ts | 22 +- packages/tx/test/transactionRunner.spec.ts | 4 +- .../test/api/EIPs/eip-4788-beaconroot.spec.ts | 5 +- packages/vm/test/api/EIPs/eip-6110.spec.ts | 6 +- .../vm/test/api/EIPs/eip-6800-verkle.spec.ts | 4 +- packages/vm/test/api/customChain.spec.ts | 4 +- packages/vm/test/api/runTx.spec.ts | 6 +- packages/vm/test/api/utils.ts | 4 +- .../vm/test/retesteth/transition-child.cts | 4 +- .../tester/runners/BlockchainTestsRunner.ts | 4 +- 39 files changed, 250 insertions(+), 242 deletions(-) diff --git a/packages/block/src/constructors.ts b/packages/block/src/constructors.ts index f06fbc359e..bf409c6ec5 100644 --- a/packages/block/src/constructors.ts +++ b/packages/block/src/constructors.ts @@ -1,6 +1,11 @@ import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { TransactionFactory } from '@ethereumjs/tx' +import { + type TxOptions, + createTxFromBlockBodyData, + createTxFromSerializedData, + createTxFromTxData, +} from '@ethereumjs/tx' import { CLRequestFactory, ConsolidationRequest, @@ -35,7 +40,6 @@ import type { RequestsBytes, WithdrawalsBytes, } from './types.js' -import type { TxOptions } from '@ethereumjs/tx' import type { CLRequest, CLRequestType, @@ -66,7 +70,7 @@ export function createBlockFromBlockData(blockData: BlockData = {}, opts?: Block // parse transactions const transactions = [] for (const txData of txsData ?? []) { - const tx = TransactionFactory.fromTxData(txData, { + const tx = createTxFromTxData(txData, { ...opts, // Use header common in case of setHardfork being activated common: header.common, @@ -165,7 +169,7 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio const transactions = [] for (const txData of txsData ?? []) { transactions.push( - TransactionFactory.fromBlockBodyData(txData, { + createTxFromBlockBodyData(txData, { ...opts, // Use header common in case of setHardfork being activated common: header.common, @@ -345,12 +349,9 @@ export async function createBlockFromExecutionPayload( const txs = [] for (const [index, serializedTx] of transactions.entries()) { try { - const tx = TransactionFactory.fromSerializedData( - hexToBytes(serializedTx as PrefixedHexString), - { - common: opts?.common, - } - ) + const tx = createTxFromSerializedData(hexToBytes(serializedTx as PrefixedHexString), { + common: opts?.common, + }) txs.push(tx) } catch (error) { const validationError = `Invalid tx at index ${index}: ${error}` diff --git a/packages/block/src/from-rpc.ts b/packages/block/src/from-rpc.ts index 20ec9cfc5c..c0105afac9 100644 --- a/packages/block/src/from-rpc.ts +++ b/packages/block/src/from-rpc.ts @@ -1,4 +1,4 @@ -import { TransactionFactory } from '@ethereumjs/tx' +import { type TypedTransaction, createTxFromTxData } from '@ethereumjs/tx' import { CLRequestFactory, TypeOutput, @@ -12,7 +12,6 @@ import { createBlockFromBlockData } from './constructors.js' import { blockHeaderFromRpc } from './header-from-rpc.js' import type { BlockOptions, JsonRpcBlock } from './index.js' -import type { TypedTransaction } from '@ethereumjs/tx' import type { PrefixedHexString } from '@ethereumjs/util' function normalizeTxParams(_txParams: any) { @@ -55,7 +54,7 @@ export function createBlockFromRpc( const opts = { common: header.common } for (const _txParams of blockParams.transactions ?? []) { const txParams = normalizeTxParams(_txParams) - const tx = TransactionFactory.fromTxData(txParams, opts) + const tx = createTxFromTxData(txParams, opts) transactions.push(tx) } diff --git a/packages/client/src/net/protocol/ethprotocol.ts b/packages/client/src/net/protocol/ethprotocol.ts index 681091c691..2c9d0ac0d5 100644 --- a/packages/client/src/net/protocol/ethprotocol.ts +++ b/packages/client/src/net/protocol/ethprotocol.ts @@ -8,7 +8,8 @@ import { Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { BlobEIP4844Transaction, - TransactionFactory, + createTxFromBlockBodyData, + createTxFromSerializedData, isAccessListEIP2930Tx, isBlobEIP4844Tx, isEOACodeEIP7702Tx, @@ -132,7 +133,7 @@ export class EthProtocol extends Protocol { BIGINT_0, // Use chainstart, timestamp: this.chain.headers.latest?.timestamp ?? Math.floor(Date.now() / 1000), }) - return txs.map((txData) => TransactionFactory.fromSerializedData(txData, { common })) + return txs.map((txData) => createTxFromSerializedData(txData, { common })) }, }, { @@ -296,7 +297,7 @@ export class EthProtocol extends Protocol { if (txData[0] === 3) { return BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txData, { common }) } else { - return TransactionFactory.fromBlockBodyData(txData, { common }) + return createTxFromBlockBodyData(txData, { common }) } }), ] diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 26519f9f0b..9716195041 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -1,6 +1,11 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' -import { BlobEIP4844Transaction, Capability, TransactionFactory } from '@ethereumjs/tx' +import { + BlobEIP4844Transaction, + Capability, + createTxFromSerializedData, + createTxFromTxData, +} from '@ethereumjs/tx' import { Address, BIGINT_0, @@ -597,7 +602,7 @@ export class Eth { blockNumber: blockToRunOn.header.number, }) - const tx = TransactionFactory.fromTxData(txData, { common: vm.common, freeze: false }) + const tx = createTxFromTxData(txData, { common: vm.common, freeze: false }) // set from address const from = @@ -1168,7 +1173,7 @@ export class Eth { ) } } else { - tx = TransactionFactory.fromSerializedData(txBuf, { common }) + tx = createTxFromSerializedData(txBuf, { common }) } } catch (e: any) { throw { diff --git a/packages/client/test/net/protocol/ethprotocol.spec.ts b/packages/client/test/net/protocol/ethprotocol.spec.ts index 5801a62a05..930aa794d0 100644 --- a/packages/client/test/net/protocol/ethprotocol.spec.ts +++ b/packages/client/test/net/protocol/ethprotocol.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' -import { FeeMarketEIP1559Transaction, TransactionFactory, TransactionType } from '@ethereumjs/tx' +import { FeeMarketEIP1559Transaction, TransactionType, createTxFromTxData } from '@ethereumjs/tx' import { Address, bigIntToBytes, bytesToBigInt, hexToBytes, randomBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -220,10 +220,10 @@ describe('[EthProtocol]', () => { const chain = await Chain.create({ config }) const p = new EthProtocol({ config, chain }) - const legacyTx = TransactionFactory.fromTxData({ type: 0 }, { common: config.chainCommon }) - const eip2929Tx = TransactionFactory.fromTxData({ type: 1 }, { common: config.chainCommon }) - const eip1559Tx = TransactionFactory.fromTxData({ type: 2 }, { common: config.chainCommon }) - const blobTx = TransactionFactory.fromTxData( + const legacyTx = createTxFromTxData({ type: 0 }, { common: config.chainCommon }) + const eip2929Tx = createTxFromTxData({ type: 1 }, { common: config.chainCommon }) + const eip1559Tx = createTxFromTxData({ type: 2 }, { common: config.chainCommon }) + const blobTx = createTxFromTxData( { type: 3, to: Address.zero(), blobVersionedHashes: [hexToBytes(`0x01${'00'.repeat(31)}`)] }, { common: config.chainCommon } ) @@ -255,7 +255,7 @@ describe('[EthProtocol]', () => { }) const chain = await Chain.create({ config }) const p = new EthProtocol({ config, chain }) - const fakeTx = TransactionFactory.fromTxData({}).sign(randomBytes(32)) + const fakeTx = createTxFromTxData({}).sign(randomBytes(32)) const fakeHash = fakeTx.hash() const encoded = p.encode( p.messages.filter((message) => message.name === 'NewPooledTransactionHashes')[0], diff --git a/packages/client/test/rpc/debug/storageRangeAt.spec.ts b/packages/client/test/rpc/debug/storageRangeAt.spec.ts index 6be7b12877..1f235a2e00 100644 --- a/packages/client/test/rpc/debug/storageRangeAt.spec.ts +++ b/packages/client/test/rpc/debug/storageRangeAt.spec.ts @@ -1,4 +1,4 @@ -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { bigIntToHex, bytesToBigInt, bytesToHex, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, beforeEach, describe, it } from 'vitest' @@ -88,7 +88,7 @@ describe(method, () => { txLookupLimit: 0, }) const rpc = getRpcClient(server) - const firstTx = TransactionFactory.fromTxData( + const firstTx = createTxFromTxData( { type: 0x2, gasLimit: 10000000, @@ -115,7 +115,7 @@ describe(method, () => { const result = await blockBuilder.addTransaction(firstTx, { skipHardForkValidation: true }) - const secondTx = TransactionFactory.fromTxData( + const secondTx = createTxFromTxData( { to: result.createdAddress, type: 0x2, @@ -131,7 +131,7 @@ describe(method, () => { await blockBuilder.addTransaction(secondTx, { skipHardForkValidation: true }) - const thirdTx = TransactionFactory.fromTxData( + const thirdTx = createTxFromTxData( { type: 0x2, gasLimit: 10000000, diff --git a/packages/client/test/rpc/debug/traceCall.spec.ts b/packages/client/test/rpc/debug/traceCall.spec.ts index 06ca9d8b13..23348f588b 100644 --- a/packages/client/test/rpc/debug/traceCall.spec.ts +++ b/packages/client/test/rpc/debug/traceCall.spec.ts @@ -1,5 +1,5 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' import { assert, describe, expect, expectTypeOf, it } from 'vitest' @@ -51,7 +51,7 @@ describe('trace a call', async () => { }) const rpc = getRpcClient(server) // construct block with tx - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x2, gasLimit: 0xfffff, diff --git a/packages/client/test/rpc/debug/traceTransaction.spec.ts b/packages/client/test/rpc/debug/traceTransaction.spec.ts index 135c43e584..024a20a276 100644 --- a/packages/client/test/rpc/debug/traceTransaction.spec.ts +++ b/packages/client/test/rpc/debug/traceTransaction.spec.ts @@ -1,5 +1,5 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -50,7 +50,7 @@ describe(method, () => { }) const rpc = getRpcClient(server) // construct block with tx - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x2, gasLimit: 0xfffff, @@ -79,7 +79,7 @@ describe(method, () => { }) const rpc = getRpcClient(server) // construct block with tx - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x2, gasLimit: 0xfffff, @@ -108,7 +108,7 @@ describe(method, () => { }) const rpc = getRpcClient(server) // construct block with tx - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x2, gasLimit: 0xfffff, @@ -141,7 +141,7 @@ describe(method, () => { }) const rpc = getRpcClient(server) // construct block with tx - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x2, gasLimit: 0xfffff, diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts index ff1644de20..182e2dca70 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts @@ -1,7 +1,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes, randomBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -45,7 +45,7 @@ describe(method, () => { account!.balance = 0xfffffffffffffffn await service.execution.vm.stateManager.putAccount(address, account!) - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -55,7 +55,7 @@ describe(method, () => { }, { common } ).sign(pkey) - const tx2 = TransactionFactory.fromTxData( + const tx2 = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -131,7 +131,7 @@ describe(method, () => { account!.balance = 0xfffffffffffffffn await service.execution.vm.stateManager.putAccount(address, account!) - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -141,7 +141,7 @@ describe(method, () => { }, { common } ).sign(pkey) - const tx2 = TransactionFactory.fromTxData( + const tx2 = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts index 466b891493..02384549d2 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts @@ -1,7 +1,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' @@ -47,7 +47,7 @@ describe(method, () => { account!.balance = 0xfffffffffffffffn await service.execution.vm.stateManager.putAccount(address, account!) - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -57,7 +57,7 @@ describe(method, () => { }, { common } ).sign(pkey) - const tx2 = TransactionFactory.fromTxData( + const tx2 = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -129,7 +129,7 @@ describe(method, () => { account!.balance = 0xfffffffffffffffn await service.execution.vm.stateManager.putAccount(address, account!) - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, @@ -139,7 +139,7 @@ describe(method, () => { }, { common } ).sign(pkey) - const tx2 = TransactionFactory.fromTxData( + const tx2 = createTxFromTxData( { type: 0x01, maxFeePerBlobGas: 1n, diff --git a/packages/client/test/rpc/engine/getPayloadV3.spec.ts b/packages/client/test/rpc/engine/getPayloadV3.spec.ts index 239eae1030..0edae358fa 100644 --- a/packages/client/test/rpc/engine/getPayloadV3.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadV3.spec.ts @@ -1,6 +1,6 @@ import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, @@ -93,7 +93,7 @@ describe(method, () => { const txVersionedHashes = commitmentsToVersionedHashes(txCommitments) const txProofs = blobsToProofs(kzg, txBlobs, txCommitments) - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0x03, blobVersionedHashes: txVersionedHashes, diff --git a/packages/client/test/rpc/engine/newPayloadV4.spec.ts b/packages/client/test/rpc/engine/newPayloadV4.spec.ts index a78e57bfe0..598dec3ca5 100644 --- a/packages/client/test/rpc/engine/newPayloadV4.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV4.spec.ts @@ -1,4 +1,4 @@ -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { bigIntToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -93,7 +93,7 @@ describe(`${method}: call with executionPayloadV4`, () => { // address 0x610adc49ecd66cbf176a8247ebd59096c031bd9f has been sufficiently funded in genesis const pk = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const depositTx = TransactionFactory.fromTxData({ + const depositTx = createTxFromTxData({ data: '0x22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001208cd4e5a69709cf8ee5b1b73d6efbf3f33bcac92fb7e4ce62b2467542fb50a72d0000000000000000000000000000000000000000000000000000000000000030ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030000000000000000000000000000000000000000000000000000000000000060a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d769', value: 32000000000000000000n, gasLimit: 30000000n, diff --git a/packages/client/test/rpc/engine/preimages.spec.ts b/packages/client/test/rpc/engine/preimages.spec.ts index 87a499866b..9081ccd97e 100644 --- a/packages/client/test/rpc/engine/preimages.spec.ts +++ b/packages/client/test/rpc/engine/preimages.spec.ts @@ -4,7 +4,7 @@ import { genTransactionsTrieRoot, genWithdrawalsTrieRoot, } from '@ethereumjs/block' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromSerializedData } from '@ethereumjs/tx' import { Withdrawal, bytesToHex, @@ -73,7 +73,7 @@ async function runBlock( const txs = [] for (const [index, serializedTx] of transactions.entries()) { try { - const tx = TransactionFactory.fromSerializedData(hexToBytes(serializedTx), { + const tx = createTxFromSerializedData(hexToBytes(serializedTx), { common, }) txs.push(tx) diff --git a/packages/client/test/rpc/eth/blobBaseFee.spec.ts b/packages/client/test/rpc/eth/blobBaseFee.spec.ts index f4e2a12b0f..3c61ed8fdd 100644 --- a/packages/client/test/rpc/eth/blobBaseFee.spec.ts +++ b/packages/client/test/rpc/eth/blobBaseFee.spec.ts @@ -1,5 +1,5 @@ import { Hardfork } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Address, BIGINT_0, @@ -61,7 +61,7 @@ const produceBlockWith4844Tx = async ( } } await blockBuilder.addTransaction( - TransactionFactory.fromTxData( + createTxFromTxData( { type: 3, gasLimit: 21000, diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index 0de524c748..926c13d76d 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -1,5 +1,5 @@ import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Address, BIGINT_0, @@ -89,7 +89,7 @@ const produceBlockWithTx = async ( const maxPriorityFeePerGas = maxPriorityFeesPerGas[i] const gasLimit = gasLimits[i] await blockBuilder.addTransaction( - TransactionFactory.fromTxData( + createTxFromTxData( { type: 2, gasLimit, @@ -155,7 +155,7 @@ const produceBlockWith4844Tx = async ( } } await blockBuilder.addTransaction( - TransactionFactory.fromTxData( + createTxFromTxData( { type: 3, gasLimit: 21000, diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 71b8eb29f8..65426552d1 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction, TransactionFactory } from '@ethereumjs/tx' +import { LegacyTransaction, createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, hexToBytes, randomBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -88,7 +88,7 @@ describe(method, () => { const account = await service.execution.vm.stateManager.getAccount(address) account!.balance = 0xffffffffffffffn await service.execution.vm.stateManager.putAccount(address, account!) - const tx = TransactionFactory.fromTxData({ + const tx = createTxFromTxData({ to: randomBytes(20), value: 1, maxFeePerGas: 0xffffff, diff --git a/packages/client/test/rpc/txpool/content.spec.ts b/packages/client/test/rpc/txpool/content.spec.ts index 4c7910a367..b653492104 100644 --- a/packages/client/test/rpc/txpool/content.spec.ts +++ b/packages/client/test/rpc/txpool/content.spec.ts @@ -2,7 +2,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { randomBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -72,7 +72,7 @@ describe(method, () => { await vm.runBlock({ block: londonBlock, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) ;(service.txPool as any).validate = () => {} - await service.txPool.add(TransactionFactory.fromTxData({ type: 2 }, {}).sign(randomBytes(32))) + await service.txPool.add(createTxFromTxData({ type: 2 }, {}).sign(randomBytes(32))) const res = await rpc.request(method, []) assert.equal( diff --git a/packages/client/test/service/fullethereumservice.spec.ts b/packages/client/test/service/fullethereumservice.spec.ts index 50041146ee..03336d3e68 100644 --- a/packages/client/test/service/fullethereumservice.spec.ts +++ b/packages/client/test/service/fullethereumservice.spec.ts @@ -1,5 +1,5 @@ import { Common, Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { TransactionFactory, TransactionType } from '@ethereumjs/tx' +import { TransactionType, createTxFromTxData } from '@ethereumjs/tx' import { equalsBytes, hexToBytes, randomBytes } from '@ethereumjs/util' import { assert, describe, expect, it, vi } from 'vitest' @@ -272,18 +272,14 @@ describe('should handle Transactions', async () => { const service = new FullEthereumService({ config, chain }) service.txPool.handleAnnouncedTxs = async (msg, _peer, _pool) => { it('should handle transaction message', () => { - assert.deepEqual( - msg[0], - TransactionFactory.fromTxData({ type: 2 }), - 'handled Transactions message' - ) + assert.deepEqual(msg[0], createTxFromTxData({ type: 2 }), 'handled Transactions message') }) } await service.handle( { name: 'Transactions', - data: [TransactionFactory.fromTxData({ type: 2 })], + data: [createTxFromTxData({ type: 2 })], }, 'eth', undefined as any @@ -320,7 +316,7 @@ describe('should handle GetPooledTransactions', async () => { const service = new FullEthereumService({ config, chain }) ;(service.txPool as any).validate = () => {} - const tx = TransactionFactory.fromTxData({ type: 2 }).sign(randomBytes(32)) + const tx = createTxFromTxData({ type: 2 }).sign(randomBytes(32)) await service.txPool.add(tx) await service.handle( diff --git a/packages/client/test/sim/4844-devnet.spec.ts b/packages/client/test/sim/4844-devnet.spec.ts index 4623c99c20..c0c4cf225d 100644 --- a/packages/client/test/sim/4844-devnet.spec.ts +++ b/packages/client/test/sim/4844-devnet.spec.ts @@ -1,5 +1,5 @@ import { createCommonFromGethGenesis } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { bytesToHex, hexToBytes, privateToAddress } from '@ethereumjs/util' import { Client } from 'jayson/promise' import { randomBytes } from 'node:crypto' @@ -187,7 +187,7 @@ describe('sharding/eip4844 hardfork tests', async () => { maxPriorityFeePerGas: 0xf, } - const tx = TransactionFactory.fromTxData({ type: 2, ...txData }, { common }).sign(pkey) + const tx = createTxFromTxData({ type: 2, ...txData }, { common }).sign(pkey) const txResult = await client.request( 'eth_sendRawTransaction', diff --git a/packages/devp2p/examples/peer-communication.ts b/packages/devp2p/examples/peer-communication.ts index df602d8c72..a6da6f7ce1 100644 --- a/packages/devp2p/examples/peer-communication.ts +++ b/packages/devp2p/examples/peer-communication.ts @@ -9,7 +9,7 @@ import { import { Block, BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { TransactionFactory, TypedTransaction } from '@ethereumjs/tx' +import { createTxFromBlockBodyData, TypedTransaction } from '@ethereumjs/tx' import chalk from 'chalk' import { LRUCache } from 'lru-cache' @@ -141,7 +141,7 @@ rlpx.events.on('peer:added', (peer) => { if (!forkVerified) break for (const item of payload) { - const tx = TransactionFactory.fromBlockBodyData(item) + const tx = createTxFromBlockBodyData(item) if (tx.isValid()) onNewTx(tx, peer) } diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index 843698196f..97b7105336 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromJsonRpcProvider, createBlockFromRPC } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { EVM, type EVMRunCallOpts } from '@ethereumjs/evm' -import { FeeMarketEIP1559Transaction, TransactionFactory } from '@ethereumjs/tx' +import { FeeMarketEIP1559Transaction, createTxFromRPC } from '@ethereumjs/tx' import { Account, Address, @@ -263,7 +263,7 @@ describe('runTx test: replay mainnet transactions', () => { const blockTag = 15496077n common.setHardforkBy({ blockNumber: blockTag }) - const tx = await TransactionFactory.fromRPC(txData as any, { common }) + const tx = await createTxFromRPC(txData as any, { common }) const state = new RPCStateManager({ provider, // Set the state manager to look at the state of the chain before the block has been executed diff --git a/packages/statemanager/test/statelessVerkleStateManager.spec.ts b/packages/statemanager/test/statelessVerkleStateManager.spec.ts index 7e4ca0f915..f11144c905 100644 --- a/packages/statemanager/test/statelessVerkleStateManager.spec.ts +++ b/packages/statemanager/test/statelessVerkleStateManager.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createCommonFromGethGenesis } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromSerializedData } from '@ethereumjs/tx' import { Account, Address, @@ -33,7 +33,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { eips: [2935, 4895, 6800], }) const decodedTxs = verkleBlockJSON.transactions.map((tx) => - TransactionFactory.fromSerializedData(hexToBytes(tx as PrefixedHexString)) + createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)) ) const block = createBlockFromBlockData( { ...verkleBlockJSON, transactions: decodedTxs } as BlockData, diff --git a/packages/tx/examples/txFactory.ts b/packages/tx/examples/txFactory.ts index 5e99b25fe7..dd967de644 100644 --- a/packages/tx/examples/txFactory.ts +++ b/packages/tx/examples/txFactory.ts @@ -1,10 +1,10 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Capability, EIP1559CompatibleTx, TransactionFactory } from '@ethereumjs/tx' +import { Capability, createTxFromTxData, EIP1559CompatibleTx } from '@ethereumjs/tx' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const txData = { type: 2, maxFeePerGas: BigInt(20) } // Creates an EIP-1559 compatible transac -const tx = TransactionFactory.fromTxData(txData, { common }) +const tx = createTxFromTxData(txData, { common }) if (tx.supports(Capability.EIP1559FeeMarket)) { console.log( diff --git a/packages/tx/src/index.ts b/packages/tx/src/index.ts index ff79af716d..7e3e2e4e97 100644 --- a/packages/tx/src/index.ts +++ b/packages/tx/src/index.ts @@ -3,5 +3,11 @@ export { AccessListEIP2930Transaction } from './eip2930Transaction.js' export { BlobEIP4844Transaction } from './eip4844Transaction.js' export { EOACodeEIP7702Transaction } from './eip7702Transaction.js' export { LegacyTransaction } from './legacyTransaction.js' -export { TransactionFactory } from './transactionFactory.js' +export { + createTxFromBlockBodyData, + createTxFromJsonRpcProvider, + createTxFromRPC, + createTxFromSerializedData, + createTxFromTxData, +} from './transactionFactory.js' export * from './types.js' diff --git a/packages/tx/src/transactionFactory.ts b/packages/tx/src/transactionFactory.ts index 4a91fe2e9c..31344eb8c2 100644 --- a/packages/tx/src/transactionFactory.ts +++ b/packages/tx/src/transactionFactory.ts @@ -17,124 +17,121 @@ import { import type { Transaction, TxData, TxOptions, TypedTxData } from './types.js' import type { EthersProvider } from '@ethereumjs/util' - -export class TransactionFactory { - // It is not possible to instantiate a TransactionFactory object. - private constructor() {} - - /** - * Create a transaction from a `txData` object - * - * @param txData - The transaction data. The `type` field will determine which transaction type is returned (if undefined, creates a legacy transaction) - * @param txOptions - Options to pass on to the constructor of the transaction - */ - public static fromTxData( - txData: TypedTxData, - txOptions: TxOptions = {} - ): Transaction[T] { - if (!('type' in txData) || txData.type === undefined) { - // Assume legacy transaction +/** + * Create a transaction from a `txData` object + * + * @param txData - The transaction data. The `type` field will determine which transaction type is returned (if undefined, creates a legacy transaction) + * @param txOptions - Options to pass on to the constructor of the transaction + */ +export function createTxFromTxData( + txData: TypedTxData, + txOptions: TxOptions = {} +): Transaction[T] { + if (!('type' in txData) || txData.type === undefined) { + // Assume legacy transaction + return LegacyTransaction.fromTxData(txData, txOptions) as Transaction[T] + } else { + if (isLegacyTxData(txData)) { return LegacyTransaction.fromTxData(txData, txOptions) as Transaction[T] + } else if (isAccessListEIP2930TxData(txData)) { + return AccessListEIP2930Transaction.fromTxData(txData, txOptions) as Transaction[T] + } else if (isFeeMarketEIP1559TxData(txData)) { + return FeeMarketEIP1559Transaction.fromTxData(txData, txOptions) as Transaction[T] + } else if (isBlobEIP4844TxData(txData)) { + return BlobEIP4844Transaction.fromTxData(txData, txOptions) as Transaction[T] + } else if (isEOACodeEIP7702TxData(txData)) { + return EOACodeEIP7702Transaction.fromTxData(txData, txOptions) as Transaction[T] } else { - if (isLegacyTxData(txData)) { - return LegacyTransaction.fromTxData(txData, txOptions) as Transaction[T] - } else if (isAccessListEIP2930TxData(txData)) { - return AccessListEIP2930Transaction.fromTxData(txData, txOptions) as Transaction[T] - } else if (isFeeMarketEIP1559TxData(txData)) { - return FeeMarketEIP1559Transaction.fromTxData(txData, txOptions) as Transaction[T] - } else if (isBlobEIP4844TxData(txData)) { - return BlobEIP4844Transaction.fromTxData(txData, txOptions) as Transaction[T] - } else if (isEOACodeEIP7702TxData(txData)) { - return EOACodeEIP7702Transaction.fromTxData(txData, txOptions) as Transaction[T] - } else { - throw new Error(`Tx instantiation with type ${(txData as TypedTxData)?.type} not supported`) - } + throw new Error(`Tx instantiation with type ${(txData as TypedTxData)?.type} not supported`) } } +} - /** - * This method tries to decode serialized data. - * - * @param data - The data Uint8Array - * @param txOptions - The transaction options - */ - public static fromSerializedData( - data: Uint8Array, - txOptions: TxOptions = {} - ): Transaction[T] { - if (data[0] <= 0x7f) { - // Determine the type. - switch (data[0]) { - case TransactionType.AccessListEIP2930: - return AccessListEIP2930Transaction.fromSerializedTx(data, txOptions) as Transaction[T] - case TransactionType.FeeMarketEIP1559: - return FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions) as Transaction[T] - case TransactionType.BlobEIP4844: - return BlobEIP4844Transaction.fromSerializedTx(data, txOptions) as Transaction[T] - case TransactionType.EOACodeEIP7702: - return EOACodeEIP7702Transaction.fromSerializedTx(data, txOptions) as Transaction[T] - default: - throw new Error(`TypedTransaction with ID ${data[0]} unknown`) - } - } else { - return LegacyTransaction.fromSerializedTx(data, txOptions) as Transaction[T] +/** + * This method tries to decode serialized data. + * + * @param data - The data Uint8Array + * @param txOptions - The transaction options + */ +export function createTxFromSerializedData( + data: Uint8Array, + txOptions: TxOptions = {} +): Transaction[T] { + if (data[0] <= 0x7f) { + // Determine the type. + switch (data[0]) { + case TransactionType.AccessListEIP2930: + return AccessListEIP2930Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + case TransactionType.FeeMarketEIP1559: + return FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + case TransactionType.BlobEIP4844: + return BlobEIP4844Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + case TransactionType.EOACodeEIP7702: + return EOACodeEIP7702Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + default: + throw new Error(`TypedTransaction with ID ${data[0]} unknown`) } + } else { + return LegacyTransaction.fromSerializedTx(data, txOptions) as Transaction[T] } +} - /** - * When decoding a BlockBody, in the transactions field, a field is either: - * A Uint8Array (a TypedTransaction - encoded as TransactionType || rlp(TransactionPayload)) - * A Uint8Array[] (Legacy Transaction) - * This method returns the right transaction. - * - * @param data - A Uint8Array or Uint8Array[] - * @param txOptions - The transaction options - */ - public static fromBlockBodyData(data: Uint8Array | Uint8Array[], txOptions: TxOptions = {}) { - if (data instanceof Uint8Array) { - return this.fromSerializedData(data, txOptions) - } else if (Array.isArray(data)) { - // It is a legacy transaction - return LegacyTransaction.fromValuesArray(data, txOptions) - } else { - throw new Error('Cannot decode transaction: unknown type input') - } +/** + * When decoding a BlockBody, in the transactions field, a field is either: + * A Uint8Array (a TypedTransaction - encoded as TransactionType || rlp(TransactionPayload)) + * A Uint8Array[] (Legacy Transaction) + * This method returns the right transaction. + * + * @param data - A Uint8Array or Uint8Array[] + * @param txOptions - The transaction options + */ +export function createTxFromBlockBodyData( + data: Uint8Array | Uint8Array[], + txOptions: TxOptions = {} +) { + if (data instanceof Uint8Array) { + return createTxFromSerializedData(data, txOptions) + } else if (Array.isArray(data)) { + // It is a legacy transaction + return LegacyTransaction.fromValuesArray(data, txOptions) + } else { + throw new Error('Cannot decode transaction: unknown type input') } +} - /** - * Method to retrieve a transaction from the provider - * @param provider - a url string for a JSON-RPC provider or an Ethers JsonRPCProvider object - * @param txHash - Transaction hash - * @param txOptions - The transaction options - * @returns the transaction specified by `txHash` - */ - public static async fromJsonRpcProvider( - provider: string | EthersProvider, - txHash: string, - txOptions?: TxOptions - ) { - const prov = getProvider(provider) - const txData = await fetchFromProvider(prov, { - method: 'eth_getTransactionByHash', - params: [txHash], - }) - if (txData === null) { - throw new Error('No data returned from provider') - } - return TransactionFactory.fromRPC(txData, txOptions) - } +/** + * Method to decode data retrieved from RPC, such as `eth_getTransactionByHash` + * Note that this normalizes some of the parameters + * @param txData The RPC-encoded data + * @param txOptions The transaction options + * @returns + */ +export async function createTxFromRPC( + txData: TxData[T], + txOptions: TxOptions = {} +): Promise { + return createTxFromTxData(normalizeTxParams(txData), txOptions) +} - /** - * Method to decode data retrieved from RPC, such as `eth_getTransactionByHash` - * Note that this normalizes some of the parameters - * @param txData The RPC-encoded data - * @param txOptions The transaction options - * @returns - */ - public static async fromRPC( - txData: TxData[T], - txOptions: TxOptions = {} - ): Promise { - return TransactionFactory.fromTxData(normalizeTxParams(txData), txOptions) +/** + * Method to retrieve a transaction from the provider + * @param provider - a url string for a JSON-RPC provider or an Ethers JsonRPCProvider object + * @param txHash - Transaction hash + * @param txOptions - The transaction options + * @returns the transaction specified by `txHash` + */ +export async function createTxFromJsonRpcProvider( + provider: string | EthersProvider, + txHash: string, + txOptions?: TxOptions +) { + const prov = getProvider(provider) + const txData = await fetchFromProvider(prov, { + method: 'eth_getTransactionByHash', + params: [txHash], + }) + if (txData === null) { + throw new Error('No data returned from provider') } + return createTxFromRPC(txData, txOptions) } diff --git a/packages/tx/test/eip3860.spec.ts b/packages/tx/test/eip3860.spec.ts index fd7c7edbb3..4125d39807 100644 --- a/packages/tx/test/eip3860.spec.ts +++ b/packages/tx/test/eip3860.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { TransactionFactory, TransactionType } from '../src/index.js' +import { TransactionType, createTxFromTxData } from '../src/index.js' const common = new Common({ chain: Chain.Mainnet, @@ -24,7 +24,7 @@ describe('[EIP3860 tests]', () => { const data = new Uint8Array(Number(maxInitCodeSize)) for (const txType of txTypes) { try { - TransactionFactory.fromTxData({ data, type: txType }, { common }) + createTxFromTxData({ data, type: txType }, { common }) assert.ok('Instantiated create tx with MAX_INITCODE_SIZE data') } catch (e) { assert.fail('Did not instantiate create tx with MAX_INITCODE_SIZE') @@ -36,7 +36,7 @@ describe('[EIP3860 tests]', () => { const data = new Uint8Array(Number(maxInitCodeSize)) for (const txType of txTypes) { try { - TransactionFactory.fromTxData({ data, type: txType, to: addressZero }, { common }) + createTxFromTxData({ data, type: txType, to: addressZero }, { common }) assert.ok('Instantiated tx with MAX_INITCODE_SIZE') } catch (e) { assert.fail('Did not instantiated tx with MAX_INITCODE_SIZE') @@ -48,7 +48,7 @@ describe('[EIP3860 tests]', () => { const data = new Uint8Array(Number(maxInitCodeSize) + 1) for (const txType of txTypes) { try { - TransactionFactory.fromTxData({ data, type: txType }, { common }) + createTxFromTxData({ data, type: txType }, { common }) assert.fail('Instantiated create tx with MAX_INITCODE_SIZE+1') } catch (e) { assert.ok('Did not instantiate create tx with MAX_INITCODE_SIZE+1') @@ -60,7 +60,7 @@ describe('[EIP3860 tests]', () => { const data = new Uint8Array(Number(maxInitCodeSize) + 1) for (const txType of txTypes) { try { - TransactionFactory.fromTxData({ data, type: txType, to: addressZero }, { common }) + createTxFromTxData({ data, type: txType, to: addressZero }, { common }) assert.ok('Instantiated tx with MAX_INITCODE_SIZE+1') } catch (e) { assert.fail('Did not instantiate tx with MAX_INITCODE_SIZE+1') @@ -73,10 +73,7 @@ describe('[EIP3860 tests]', () => { const data = new Uint8Array(Number(maxInitCodeSize) + 1) for (const txType of txTypes) { try { - TransactionFactory.fromTxData( - { data, type: txType }, - { common, allowUnlimitedInitCodeSize: true } - ) + createTxFromTxData({ data, type: txType }, { common, allowUnlimitedInitCodeSize: true }) assert.ok('Instantiated create tx with MAX_INITCODE_SIZE+1') } catch (e) { assert.fail('Did not instantiate tx with MAX_INITCODE_SIZE+1') @@ -89,11 +86,11 @@ describe('[EIP3860 tests]', () => { it('should work', () => { const data = new Uint8Array(Number(maxInitCodeSize)) for (const txType of txTypes) { - const eip3860ActiveTx = TransactionFactory.fromTxData( + const eip3860ActiveTx = createTxFromTxData( { data, type: txType }, { common, allowUnlimitedInitCodeSize: true } ) - const eip3860DeactivedTx = TransactionFactory.fromTxData( + const eip3860DeactivedTx = createTxFromTxData( { data, type: txType }, { common, allowUnlimitedInitCodeSize: false } ) diff --git a/packages/tx/test/eip4844.spec.ts b/packages/tx/test/eip4844.spec.ts index f3aca67c40..f97501f5b7 100644 --- a/packages/tx/test/eip4844.spec.ts +++ b/packages/tx/test/eip4844.spec.ts @@ -16,7 +16,7 @@ import { loadKZG } from 'kzg-wasm' import { assert, beforeAll, describe, it } from 'vitest' import gethGenesis from '../../block/test/testdata/4844-hardfork.json' -import { BlobEIP4844Transaction, TransactionFactory } from '../src/index.js' +import { BlobEIP4844Transaction, createTxFromTxData } from '../src/index.js' import blobTx from './json/serialized4844tx.json' @@ -108,7 +108,7 @@ describe('EIP4844 constructor tests - valid scenarios', () => { } const tx = BlobEIP4844Transaction.fromTxData(txData, { common }) assert.equal(tx.type, 3, 'successfully instantiated a blob transaction from txData') - const factoryTx = TransactionFactory.fromTxData(txData, { common }) + const factoryTx = createTxFromTxData(txData, { common }) assert.equal(factoryTx.type, 3, 'instantiated a blob transaction from the tx factory') const serializedTx = tx.serialize() diff --git a/packages/tx/test/fromRpc.spec.ts b/packages/tx/test/fromRpc.spec.ts index a0940408b8..171d7f14b5 100644 --- a/packages/tx/test/fromRpc.spec.ts +++ b/packages/tx/test/fromRpc.spec.ts @@ -3,7 +3,12 @@ import { bytesToHex, randomBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { normalizeTxParams } from '../src/fromRpc.js' -import { TransactionFactory, TransactionType } from '../src/index.js' +import { + TransactionType, + createTxFromJsonRpcProvider, + createTxFromRPC, + createTxFromTxData, +} from '../src/index.js' import optimismTx from './json/optimismTx.json' import rpcTx from './json/rpcTx.json' @@ -51,10 +56,10 @@ describe('[fromJsonRpcProvider]', () => { } const txHash = '0xed1960aa7d0d7b567c946d94331dddb37a1c67f51f30bf51f256ea40db88cfb0' - const tx = await TransactionFactory.fromJsonRpcProvider(provider, txHash, { common }) + const tx = await createTxFromJsonRpcProvider(provider, txHash, { common }) assert.equal(bytesToHex(tx.hash()), txHash, 'generated correct tx from transaction RPC data') try { - await TransactionFactory.fromJsonRpcProvider(provider, bytesToHex(randomBytes(32)), {}) + await createTxFromJsonRpcProvider(provider, bytesToHex(randomBytes(32)), {}) assert.fail('should throw') } catch (err: any) { assert.ok( @@ -69,7 +74,7 @@ describe('[fromJsonRpcProvider]', () => { describe('[normalizeTxParams]', () => { it('should work', () => { const normedTx = normalizeTxParams(rpcTx) - const tx = TransactionFactory.fromTxData(normedTx) + const tx = createTxFromTxData(normedTx) assert.equal(normedTx.gasLimit, 21000n, 'correctly converted "gas" to "gasLimit"') assert.equal(bytesToHex(tx.hash()), rpcTx.hash, 'converted normed tx data to transaction objec') }) @@ -79,7 +84,7 @@ describe('fromRPC: interpret v/r/s vals of 0x0 as undefined for Optimism system it('should work', async () => { for (const txType of txTypes) { ;(optimismTx as any).type = txType - const tx = await TransactionFactory.fromRPC(optimismTx as TypedTxData) + const tx = await createTxFromRPC(optimismTx as TypedTxData) assert.ok(tx.v === undefined) assert.ok(tx.s === undefined) assert.ok(tx.r === undefined) @@ -98,7 +103,7 @@ describe('fromRPC: ensure `v="0x0"` is correctly decoded for signed txs', () => continue } ;(v0Tx as any).type = txType - const tx = await TransactionFactory.fromRPC(v0Tx as TypedTxData) + const tx = await createTxFromRPC(v0Tx as TypedTxData) assert.ok(tx.isSigned()) } }) diff --git a/packages/tx/test/inputValue.spec.ts b/packages/tx/test/inputValue.spec.ts index b5f3aaf53f..2feac7f6f4 100644 --- a/packages/tx/test/inputValue.spec.ts +++ b/packages/tx/test/inputValue.spec.ts @@ -6,8 +6,8 @@ import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction, LegacyTransaction, - TransactionFactory, TransactionType, + createTxFromTxData, } from '../src/index.js' import type { TxValuesArray } from '../src/index.js' @@ -151,7 +151,7 @@ describe('[Invalid Array Input values]', () => { ] for (const signed of [false, true]) { for (const txType of txTypes) { - let tx = TransactionFactory.fromTxData({ type: txType }) + let tx = createTxFromTxData({ type: txType }) if (signed) { tx = tx.sign(hexToBytes(`0x${'42'.repeat(32)}`)) } @@ -217,7 +217,7 @@ describe('[Invalid Access Lists]', () => { for (const invalidAccessListItem of invalidAccessLists) { let tx: any try { - tx = TransactionFactory.fromTxData({ + tx = createTxFromTxData({ type: txType, accessList: invalidAccessListItem, }) @@ -227,7 +227,7 @@ describe('[Invalid Access Lists]', () => { assert.fail('did not fail on `fromTxData`') } catch (e: any) { assert.ok(true, 'failed ok on decoding in `fromTxData`') - tx = TransactionFactory.fromTxData({ type: txType }) + tx = createTxFromTxData({ type: txType }) if (signed) { tx = tx.sign(hexToBytes(`0x${'42'.repeat(32)}`)) } diff --git a/packages/tx/test/transactionFactory.spec.ts b/packages/tx/test/transactionFactory.spec.ts index a7764f5358..c66d1fe456 100644 --- a/packages/tx/test/transactionFactory.spec.ts +++ b/packages/tx/test/transactionFactory.spec.ts @@ -6,8 +6,10 @@ import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction, LegacyTransaction, - TransactionFactory, TransactionType, + createTxFromBlockBodyData, + createTxFromSerializedData, + createTxFromTxData, } from '../src/index.js' const common = new Common({ @@ -59,7 +61,7 @@ describe('[TransactionFactory]: Basic functions', () => { it('fromSerializedData() -> success cases', () => { for (const txType of txTypes) { const serialized = txType.unsigned.serialize() - const factoryTx = TransactionFactory.fromSerializedData(serialized, { common }) + const factoryTx = createTxFromSerializedData(serialized, { common }) assert.equal( factoryTx.constructor.name, txType.class.name, @@ -74,7 +76,7 @@ describe('[TransactionFactory]: Basic functions', () => { const unsupportedCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) assert.throws( () => { - TransactionFactory.fromSerializedData(txType.unsigned.serialize(), { + createTxFromSerializedData(txType.unsigned.serialize(), { common: unsupportedCommon, }) }, @@ -87,7 +89,7 @@ describe('[TransactionFactory]: Basic functions', () => { () => { const serialized = txType.unsigned.serialize() serialized[0] = 99 // edit the transaction type - TransactionFactory.fromSerializedData(serialized, { common }) + createTxFromSerializedData(serialized, { common }) }, undefined, undefined, @@ -105,7 +107,7 @@ describe('[TransactionFactory]: Basic functions', () => { } else { rawTx = txType.signed.raw() as Uint8Array[] } - const tx = TransactionFactory.fromBlockBodyData(rawTx, { common }) + const tx = createTxFromBlockBodyData(rawTx, { common }) assert.equal( tx.constructor.name, txType.name, @@ -129,14 +131,14 @@ describe('[TransactionFactory]: Basic functions', () => { it('fromTxData() -> success cases', () => { for (const txType of txTypes) { - const tx = TransactionFactory.fromTxData({ type: txType.type }, { common }) + const tx = createTxFromTxData({ type: txType.type }, { common }) assert.equal( tx.constructor.name, txType.class.name, `should return the right type (${txType.name})` ) if (!txType.eip2718) { - const tx = TransactionFactory.fromTxData({}) + const tx = createTxFromTxData({}) assert.equal( tx.constructor.name, txType.class.name, @@ -149,15 +151,15 @@ describe('[TransactionFactory]: Basic functions', () => { it('fromTxData() -> error cases', () => { const unsupportedCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) assert.throws(() => { - TransactionFactory.fromTxData({ type: 1 }, { common: unsupportedCommon }) + createTxFromTxData({ type: 1 }, { common: unsupportedCommon }) }) assert.throws(() => { - TransactionFactory.fromTxData({ type: 999 }) + createTxFromTxData({ type: 999 }) }) assert.throws(() => { - TransactionFactory.fromTxData({ value: BigInt('-100') }) + createTxFromTxData({ value: BigInt('-100') }) }) }) }) diff --git a/packages/tx/test/transactionRunner.spec.ts b/packages/tx/test/transactionRunner.spec.ts index 24bdc3dfcd..ac0a458161 100644 --- a/packages/tx/test/transactionRunner.spec.ts +++ b/packages/tx/test/transactionRunner.spec.ts @@ -3,7 +3,7 @@ import { bytesToHex, hexToBytes } from '@ethereumjs/util' import minimist from 'minimist' import { assert, describe, it } from 'vitest' -import { TransactionFactory } from '../src/index.js' +import { createTxFromSerializedData } from '../src/transactionFactory.js' import { getTests } from './testLoader.js' @@ -70,7 +70,7 @@ describe('TransactionTests', async () => { if (activateEIPs !== undefined) { common.setEIPs(activateEIPs) } - const tx = TransactionFactory.fromSerializedData(rawTx, { common }) + const tx = createTxFromSerializedData(rawTx, { common }) const sender = tx.getSenderAddress().toString() const hash = bytesToHex(tx.hash()) const txIsValid = tx.isValid() diff --git a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts index c39117a4bc..f654211127 100644 --- a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts @@ -11,7 +11,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { type TransactionType, type TxData, createTxFromTxData } from '@ethereumjs/tx' import { Address, bigIntToBytes, @@ -26,7 +26,6 @@ import { assert, describe, it } from 'vitest' import { VM } from '../../../src' import type { Block } from '@ethereumjs/block' -import type { TransactionType, TxData } from '@ethereumjs/tx' import type { BigIntLike, PrefixedHexString } from '@ethereumjs/util' const common = new Common({ @@ -46,7 +45,7 @@ function beaconrootBlock( const newTxData = [] for (const txData of transactions) { - const tx = TransactionFactory.fromTxData({ + const tx = createTxFromTxData({ gasPrice: 7, gasLimit: 100000, ...txData, diff --git a/packages/vm/test/api/EIPs/eip-6110.spec.ts b/packages/vm/test/api/EIPs/eip-6110.spec.ts index 5e2a065c70..4da632d9c3 100644 --- a/packages/vm/test/api/EIPs/eip-6110.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6110.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork, getInitializedChains } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes, randomBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' @@ -33,7 +33,7 @@ describe('EIP-6110 runBlock tests', () => { const vm = await setupVM({ common }) const pk = randomBytes(32) const sender = Address.fromPrivateKey(pk) - const depositTx = TransactionFactory.fromTxData({ + const depositTx = createTxFromTxData({ data: '0x22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001208cd4e5a69709cf8ee5b1b73d6efbf3f33bcac92fb7e4ce62b2467542fb50a72d0000000000000000000000000000000000000000000000000000000000000030ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030000000000000000000000000000000000000000000000000000000000000060a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d769', value: 32000000000000000000n, gasLimit: 0xffffffffn, @@ -69,7 +69,7 @@ describe('EIP-7685 buildBlock tests', () => { const vm = await setupVM({ common }) const pk = randomBytes(32) const sender = Address.fromPrivateKey(pk) - const depositTx = TransactionFactory.fromTxData({ + const depositTx = createTxFromTxData({ data: '0x22895118000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001208cd4e5a69709cf8ee5b1b73d6efbf3f33bcac92fb7e4ce62b2467542fb50a72d0000000000000000000000000000000000000000000000000000000000000030ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030000000000000000000000000000000000000000000000000000000000000060a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d769', value: 32000000000000000000n, gasLimit: 0xffffffffn, diff --git a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts index a13cd32fc9..bbc4ea0dac 100644 --- a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork, createCustomCommon } from '@ethereumjs/common' import { EVM } from '@ethereumjs/evm' import { StatelessVerkleStateManager } from '@ethereumjs/statemanager' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromSerializedData } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' import { loadVerkleCrypto } from 'verkle-cryptography-wasm' import { describe, it } from 'vitest' @@ -19,7 +19,7 @@ const common = createCustomCommon(customChainParams, { eips: [2935, 4895, 6800], }) const decodedTxs = verkleBlockJSON.transactions.map((tx) => - TransactionFactory.fromSerializedData(hexToBytes(tx as PrefixedHexString)) + createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)) ) const parentStateRoot = hexToBytes( diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index d95f78d2d7..1c86fa56ea 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Common, Hardfork } from '@ethereumjs/common' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromTxData } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { Interface } from '@ethersproject/abi' import { assert, describe, it } from 'vitest' @@ -67,7 +67,7 @@ describe('VM initialized with custom state', () => { const vm = await VM.create({ blockchain, common, genesisState }) const to = '0x00000000000000000000000000000000000000ff' - const tx = TransactionFactory.fromTxData( + const tx = createTxFromTxData( { type: 0, to, diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index a8c05dc32a..824bcaa8d9 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -5,8 +5,8 @@ import { BlobEIP4844Transaction, FeeMarketEIP1559Transaction, LegacyTransaction, - TransactionFactory, TransactionType, + createTxFromTxData, } from '@ethereumjs/tx' import { Account, @@ -212,7 +212,7 @@ describe('runTx() -> successful API parameter usage', async () => { ) const transferCost = 21000 - const unsignedTx = TransactionFactory.fromTxData( + const unsignedTx = createTxFromTxData( { to: address, gasLimit: transferCost, @@ -479,7 +479,7 @@ describe('runTx() -> runtime behavior', () => { txParams['accessList'] = [] txParams['type'] = txType.type } - const tx = TransactionFactory.fromTxData(txParams, { common }).sign(privateKey) + const tx = createTxFromTxData(txParams, { common }).sign(privateKey) await vm.stateManager.putAccount(tx.getSenderAddress(), createAccount()) diff --git a/packages/vm/test/api/utils.ts b/packages/vm/test/api/utils.ts index 4f138b97bb..5262c6eb8a 100644 --- a/packages/vm/test/api/utils.ts +++ b/packages/vm/test/api/utils.ts @@ -1,5 +1,5 @@ import { createBlockchain } from '@ethereumjs/blockchain' -import { TransactionFactory, TransactionType } from '@ethereumjs/tx' +import { TransactionType, createTxFromTxData } from '@ethereumjs/tx' import { Account, blobsToCommitments, @@ -113,7 +113,7 @@ export function getTransaction( ) } - const tx = TransactionFactory.fromTxData(txParams, { common, freeze: false }) + const tx = createTxFromTxData(txParams, { common, freeze: false }) if (sign) { const privateKey = hexToBytes( diff --git a/packages/vm/test/retesteth/transition-child.cts b/packages/vm/test/retesteth/transition-child.cts index f123db829e..8f77a71bec 100644 --- a/packages/vm/test/retesteth/transition-child.cts +++ b/packages/vm/test/retesteth/transition-child.cts @@ -1,7 +1,7 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { RLP } from '@ethereumjs/rlp' -import { LegacyTransaction, TransactionFactory } from '@ethereumjs/tx' +import { createTxFromSerializedData, LegacyTransaction } from '@ethereumjs/tx' import { Account, bytesToHex, unprefixedHexToBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import { readFileSync, writeFileSync } from 'fs' @@ -107,7 +107,7 @@ async function runTransition(argsIn: any) { try { let tx: TypedTransaction if (txData instanceof Uint8Array) { - tx = TransactionFactory.fromSerializedData(txData as Uint8Array, { common }) + tx = createTxFromSerializedData(txData as Uint8Array, { common }) } else { tx = LegacyTransaction.fromValuesArray(txData as Uint8Array[], { common }) } diff --git a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts index 48d911100c..9e6bcf5ed7 100644 --- a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts +++ b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts @@ -5,7 +5,7 @@ import { Ethash } from '@ethereumjs/ethash' import { RLP } from '@ethereumjs/rlp' import { DefaultStateManager } from '@ethereumjs/statemanager' import { Trie } from '@ethereumjs/trie' -import { TransactionFactory } from '@ethereumjs/tx' +import { createTxFromSerializedData } from '@ethereumjs/tx' import { MapDB, bytesToBigInt, @@ -175,7 +175,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes const shouldFail = txData.valid === 'false' try { const txRLP = hexToBytes(txData.rawBytes as PrefixedHexString) - const tx = TransactionFactory.fromSerializedData(txRLP, { common }) + const tx = createTxFromSerializedData(txRLP, { common }) await blockBuilder.addTransaction(tx) if (shouldFail) { t.fail('tx should fail, but did not fail') From f325b62456592005d7ac9f5ae80e15026a66d02f Mon Sep 17 00:00:00 2001 From: Scotty <66335769+ScottyPoi@users.noreply.github.com> Date: Thu, 18 Jul 2024 01:56:45 -0600 Subject: [PATCH 06/58] Trie: replace static methods (#3515) * Trie: extract static methods * update downstream * delete trie.create * trie: update test --------- Co-authored-by: Holger Drewes --- packages/client/src/execution/vmexecution.ts | 5 +- .../client/src/sync/fetcher/accountfetcher.ts | 7 +- .../client/src/sync/fetcher/storagefetcher.ts | 8 +- .../test/net/protocol/snapprotocol.spec.ts | 6 +- .../test/sync/fetcher/accountfetcher.spec.ts | 4 +- .../test/sync/fetcher/storagefetcher.spec.ts | 4 +- packages/statemanager/src/rpcStateManager.ts | 4 +- packages/statemanager/src/stateManager.ts | 8 +- .../test/proofStateManager.spec.ts | 4 +- .../statemanager/test/stateManager.spec.ts | 6 +- packages/trie/examples/basicUsage.ts | 4 +- packages/trie/examples/createFromProof.ts | 4 +- packages/trie/examples/rootPersistence.ts | 4 +- packages/trie/examples/trieWalking.ts | 4 +- packages/trie/src/constructors.ts | 70 +++++++++ packages/trie/src/index.ts | 1 + packages/trie/src/proof/index.ts | 66 ++++++++ packages/trie/src/proof/range.ts | 5 +- packages/trie/src/trie.ts | 141 +----------------- packages/trie/test/proof.spec.ts | 42 +++--- packages/trie/test/trie/checkpoint.spec.ts | 4 +- packages/trie/test/trie/prune.spec.ts | 4 +- packages/trie/test/trie/secure.spec.ts | 4 +- packages/trie/test/trie/trie.spec.ts | 46 +++--- packages/trie/test/util/asyncWalk.spec.ts | 6 +- 25 files changed, 232 insertions(+), 229 deletions(-) create mode 100644 packages/trie/src/constructors.ts diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index d845f190b6..db8cef9f07 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -12,7 +12,7 @@ import { DefaultStateManager, StatelessVerkleStateManager, } from '@ethereumjs/statemanager' -import { Trie } from '@ethereumjs/trie' +import { createTrie } from '@ethereumjs/trie' import { BIGINT_0, BIGINT_1, @@ -38,6 +38,7 @@ import { ReceiptsManager } from './receipt.js' import type { ExecutionOptions } from './execution.js' import type { Block } from '@ethereumjs/block' +import type { Trie } from '@ethereumjs/trie' import type { PrefixedHexString } from '@ethereumjs/util' import type { RunBlockOpts, TxReceipt } from '@ethereumjs/vm' @@ -145,7 +146,7 @@ export class VMExecution extends Execution { if (this.merkleVM !== undefined) { return } - const trie = await Trie.create({ + const trie = await createTrie({ db: new LevelDB(this.stateDB), useKeyHashing: true, common: this.config.chainCommon, diff --git a/packages/client/src/sync/fetcher/accountfetcher.ts b/packages/client/src/sync/fetcher/accountfetcher.ts index 7a5e888443..3baf8e965b 100644 --- a/packages/client/src/sync/fetcher/accountfetcher.ts +++ b/packages/client/src/sync/fetcher/accountfetcher.ts @@ -1,5 +1,5 @@ import { DefaultStateManager } from '@ethereumjs/statemanager' -import { Trie } from '@ethereumjs/trie' +import { verifyTrieRangeProof } from '@ethereumjs/trie' import { BIGINT_0, BIGINT_1, @@ -33,6 +33,7 @@ import type { AccountData } from '../../net/protocol/snapprotocol.js' import type { FetcherOptions } from './fetcher.js' import type { StorageRequest } from './storagefetcher.js' import type { Job, SnapFetcherDoneFlags } from './types.js' +import type { Trie } from '@ethereumjs/trie' import type { Debugger } from 'debug' type AccountDataResponse = AccountData[] & { completed?: boolean } @@ -321,7 +322,7 @@ export class AccountFetcher extends Fetcher const keys = accounts.map((acc: any) => acc.hash) const values = accounts.map((acc: any) => accountBodyToRLP(acc.body)) // convert the request to the right values - return Trie.verifyRangeProof(stateRoot, origin, keys[keys.length - 1], keys, values, proof, { + return verifyTrieRangeProof(stateRoot, origin, keys[keys.length - 1], keys, values, proof, { common: this.config.chainCommon, useKeyHashingFunction: this.config.chainCommon?.customCrypto?.keccak256 ?? keccak256, }) @@ -402,7 +403,7 @@ export class AccountFetcher extends Fetcher // check zero-element proof if (rangeResult.proof.length > 0) { try { - const isMissingRightRange = await Trie.verifyRangeProof( + const isMissingRightRange = await verifyTrieRangeProof( this.root, origin, null, diff --git a/packages/client/src/sync/fetcher/storagefetcher.ts b/packages/client/src/sync/fetcher/storagefetcher.ts index 6602785af8..6b19fb9b1b 100644 --- a/packages/client/src/sync/fetcher/storagefetcher.ts +++ b/packages/client/src/sync/fetcher/storagefetcher.ts @@ -1,5 +1,5 @@ import { DefaultStateManager } from '@ethereumjs/statemanager' -import { Trie } from '@ethereumjs/trie' +import { verifyTrieRangeProof } from '@ethereumjs/trie' import { BIGINT_0, BIGINT_1, @@ -126,7 +126,7 @@ export class StorageFetcher extends Fetcher slot.hash) const values = slots.map((slot: any) => slot.body) - return await Trie.verifyRangeProof( + return await verifyTrieRangeProof( stateRoot, origin, keys[keys.length - 1], @@ -276,7 +276,7 @@ export class StorageFetcher extends Fetcher 0) { try { - const isMissingRightRange = await Trie.verifyRangeProof( + const isMissingRightRange = await verifyTrieRangeProof( task.storageRequests[0].storageRoot, origin, null, @@ -333,7 +333,7 @@ export class StorageFetcher extends Fetcher { try { const keys = accounts.map((acc: any) => acc.hash) const values = accounts.map((acc: any) => accountBodyToRLP(acc.body)) - await Trie.verifyRangeProof(stateRoot, keys[0], keys[keys.length - 1], keys, values, proof, { + await verifyTrieRangeProof(stateRoot, keys[0], keys[keys.length - 1], keys, values, proof, { useKeyHashingFunction: keccak256, }) } catch (e) { @@ -324,7 +324,7 @@ describe('[SnapProtocol]', () => { try { const keys = lastAccountSlots.map((acc: any) => acc.hash) const values = lastAccountSlots.map((acc: any) => acc.body) - await Trie.verifyRangeProof( + await verifyTrieRangeProof( lastAccountStorageRoot, keys[0], keys[keys.length - 1], diff --git a/packages/client/test/sync/fetcher/accountfetcher.spec.ts b/packages/client/test/sync/fetcher/accountfetcher.spec.ts index bff9ba88a5..949262c9ff 100644 --- a/packages/client/test/sync/fetcher/accountfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/accountfetcher.spec.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { Trie } from '@ethereumjs/trie' +import { createTrieFromProof } from '@ethereumjs/trie' import { bytesToBigInt, hexToBytes } from '@ethereumjs/util' import * as td from 'testdouble' import { assert, describe, it, vi } from 'vitest' @@ -289,7 +289,7 @@ describe('[AccountFetcher]', async () => { const pool = new PeerPool() as any // calculate new root with a key all the way to the right of the trie - const trie = await Trie.createFromProof(_zeroElementProof) + const trie = await createTrieFromProof(_zeroElementProof) await trie.put(hexToBytes(`0x${'F'.repeat(32)}`), hexToBytes('0x123'), true) const newRoot = trie.root() diff --git a/packages/client/test/sync/fetcher/storagefetcher.spec.ts b/packages/client/test/sync/fetcher/storagefetcher.spec.ts index 53437d50e8..ef4a920095 100644 --- a/packages/client/test/sync/fetcher/storagefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/storagefetcher.spec.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { Trie } from '@ethereumjs/trie' +import { createTrieFromProof } from '@ethereumjs/trie' import { hexToBytes } from '@ethereumjs/util' import { utf8ToBytes } from 'ethereum-cryptography/utils' import { assert, describe, it, vi } from 'vitest' @@ -362,7 +362,7 @@ describe('[StorageFetcher]', async () => { const pool = new PeerPool() as any // calculate new root with a key all the way to the right of the trie - const trie = await Trie.createFromProof(_zeroElementProof) + const trie = await createTrieFromProof(_zeroElementProof) await trie.put(hexToBytes(`0x${'F'.repeat(32)}`), hexToBytes('0x123'), true) const newRoot = trie.root() diff --git a/packages/statemanager/src/rpcStateManager.ts b/packages/statemanager/src/rpcStateManager.ts index 2935088ced..6aae3469af 100644 --- a/packages/statemanager/src/rpcStateManager.ts +++ b/packages/statemanager/src/rpcStateManager.ts @@ -1,6 +1,6 @@ import { Chain, Common } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { Trie } from '@ethereumjs/trie' +import { verifyTrieProof } from '@ethereumjs/trie' import { Account, bigIntToHex, @@ -243,7 +243,7 @@ export class RPCStateManager implements EVMStateManagerInterface { const proofBuf = proof.accountProof.map((proofNode: PrefixedHexString) => toBytes(proofNode)) - const verified = await Trie.verifyProof(address.bytes, proofBuf, { + const verified = await verifyTrieProof(address.bytes, proofBuf, { useKeyHashing: true, }) // if not verified (i.e. verifyProof returns null), account does not exist diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 24769b8320..6ba58ebfd7 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -1,6 +1,6 @@ import { Chain, Common } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { Trie } from '@ethereumjs/trie' +import { Trie, createTrieFromProof, verifyTrieProof } from '@ethereumjs/trie' import { Account, Address, @@ -792,7 +792,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { } else { const trie = opts.trie ?? - (await Trie.createFromProof( + (await createTrieFromProof( proof[0].accountProof.map((e) => hexToBytes(e)), { useKeyHashing: true } )) @@ -871,7 +871,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { // This returns the account if the proof is valid. // Verify that it matches the reported account. - const value = await Trie.verifyProof(key, accountProof, { + const value = await verifyTrieProof(key, accountProof, { useKeyHashing: true, }) @@ -917,7 +917,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { const storageProof = stProof.proof.map((value: PrefixedHexString) => hexToBytes(value)) const storageValue = setLengthLeft(hexToBytes(stProof.value), 32) const storageKey = hexToBytes(stProof.key) - const proofValue = await Trie.verifyProof(storageKey, storageProof, { + const proofValue = await verifyTrieProof(storageKey, storageProof, { useKeyHashing: true, }) const reportedValue = setLengthLeft( diff --git a/packages/statemanager/test/proofStateManager.spec.ts b/packages/statemanager/test/proofStateManager.spec.ts index ab83ce1fca..1be393a655 100644 --- a/packages/statemanager/test/proofStateManager.spec.ts +++ b/packages/statemanager/test/proofStateManager.spec.ts @@ -1,4 +1,4 @@ -import { Trie } from '@ethereumjs/trie' +import { Trie, createTrie } from '@ethereumjs/trie' import { Account, Address, @@ -111,7 +111,7 @@ describe('ProofStateManager', () => { // Account: 0xc626553e7c821d0f8308c28d56c60e3c15f8d55a // Storage slots: empty list const address = Address.fromString('0xc626553e7c821d0f8308c28d56c60e3c15f8d55a') - const trie = await Trie.create({ useKeyHashing: true }) + const trie = await createTrie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB let stateRoot: Uint8Array | undefined diff --git a/packages/statemanager/test/stateManager.spec.ts b/packages/statemanager/test/stateManager.spec.ts index c39e61f052..bd8cf6dc4d 100644 --- a/packages/statemanager/test/stateManager.spec.ts +++ b/packages/statemanager/test/stateManager.spec.ts @@ -1,4 +1,4 @@ -import { Trie } from '@ethereumjs/trie' +import { Trie, createTrie, createTrieFromProof } from '@ethereumjs/trie' import { Account, Address, @@ -289,7 +289,7 @@ describe('StateManager -> General', () => { it.skipIf(isBrowser() === true)( 'should create a statemanager fromProof with opts preserved', async () => { - const trie = await Trie.create({ useKeyHashing: false }) + const trie = await createTrie({ useKeyHashing: false }) const sm = new DefaultStateManager({ trie }) const pk = hexToBytes('0x9f12aab647a25a81f821a5a0beec3330cd057b2346af4fb09d7a807e896701ea') const pk2 = hexToBytes('0x8724f27e2ce3714af01af3220478849db68a03c0f84edf1721d73d9a6139ad1c') @@ -307,7 +307,7 @@ describe('StateManager -> General', () => { keys.map((key) => hexToBytes(key)) ) const proof2 = await sm.getProof(address2) - const newTrie = await Trie.createFromProof( + const newTrie = await createTrieFromProof( proof.accountProof.map((e) => hexToBytes(e)), { useKeyHashing: false } ) diff --git a/packages/trie/examples/basicUsage.ts b/packages/trie/examples/basicUsage.ts index 9042c8b5cb..b669197bf9 100644 --- a/packages/trie/examples/basicUsage.ts +++ b/packages/trie/examples/basicUsage.ts @@ -1,8 +1,8 @@ -import { Trie } from '@ethereumjs/trie' +import { createTrie, Trie } from '@ethereumjs/trie' import { bytesToUtf8, MapDB, utf8ToBytes } from '@ethereumjs/util' async function test() { - const trie = await Trie.create({ db: new MapDB() }) + const trie = await createTrie({ db: new MapDB() }) await trie.put(utf8ToBytes('test'), utf8ToBytes('one')) const value = await trie.get(utf8ToBytes('test')) console.log(value ? bytesToUtf8(value) : 'not found') // 'one' diff --git a/packages/trie/examples/createFromProof.ts b/packages/trie/examples/createFromProof.ts index 7b41410c42..4b3cb284d5 100644 --- a/packages/trie/examples/createFromProof.ts +++ b/packages/trie/examples/createFromProof.ts @@ -1,4 +1,4 @@ -import { Trie } from '@ethereumjs/trie' +import { Trie, createTrieFromProof } from '@ethereumjs/trie' import { bytesToUtf8 } from '@ethereumjs/util' import { utf8ToBytes } from '@ethereumjs/util' @@ -11,7 +11,7 @@ async function main() { await someOtherTrie.put(k2, utf8ToBytes('valueTwo')) const proof = await someOtherTrie.createProof(k1) - const trie = await Trie.createFromProof(proof, { useKeyHashing: true }) + const trie = await createTrieFromProof(proof, { useKeyHashing: true }) const otherProof = await someOtherTrie.createProof(k2) // To add more proofs to the trie, use `updateFromProof` diff --git a/packages/trie/examples/rootPersistence.ts b/packages/trie/examples/rootPersistence.ts index 56a3c74d43..dadb55411d 100644 --- a/packages/trie/examples/rootPersistence.ts +++ b/packages/trie/examples/rootPersistence.ts @@ -1,8 +1,8 @@ -import { Trie } from '@ethereumjs/trie' +import { createTrie, Trie } from '@ethereumjs/trie' import { bytesToHex } from '@ethereumjs/util' async function main() { - const trie = await Trie.create({ + const trie = await createTrie({ useRootPersistence: true, }) diff --git a/packages/trie/examples/trieWalking.ts b/packages/trie/examples/trieWalking.ts index e99eb93543..7d63c26212 100644 --- a/packages/trie/examples/trieWalking.ts +++ b/packages/trie/examples/trieWalking.ts @@ -1,8 +1,8 @@ -import { Trie } from '@ethereumjs/trie' +import { createTrie, Trie } from '@ethereumjs/trie' import { utf8ToBytes } from '@ethereumjs/util' async function main() { - const trie = await Trie.create() + const trie = await createTrie() await trie.put(utf8ToBytes('key'), utf8ToBytes('val')) const walk = trie.walkTrieIterable(trie.root()) diff --git a/packages/trie/src/constructors.ts b/packages/trie/src/constructors.ts new file mode 100644 index 0000000000..c8fff50896 --- /dev/null +++ b/packages/trie/src/constructors.ts @@ -0,0 +1,70 @@ +import { + KeyEncoding, + ValueEncoding, + bytesToUnprefixedHex, + unprefixedHexToBytes, +} from '@ethereumjs/util' +import { keccak256 } from 'ethereum-cryptography/keccak' +import { concatBytes } from 'ethereum-cryptography/utils' + +import { ROOT_DB_KEY, Trie } from './index.js' + +import type { Proof, TrieOpts } from './index.js' + +export async function createTrie(opts?: TrieOpts) { + const keccakFunction = + opts?.common?.customCrypto.keccak256 ?? opts?.useKeyHashingFunction ?? keccak256 + let key = ROOT_DB_KEY + + const encoding = + opts?.valueEncoding === ValueEncoding.Bytes ? ValueEncoding.Bytes : ValueEncoding.String + + if (opts?.useKeyHashing === true) { + key = keccakFunction.call(undefined, ROOT_DB_KEY) as Uint8Array + } + if (opts?.keyPrefix !== undefined) { + key = concatBytes(opts.keyPrefix, key) + } + + if (opts?.db !== undefined && opts?.useRootPersistence === true) { + if (opts?.root === undefined) { + const root = await opts?.db.get(bytesToUnprefixedHex(key), { + keyEncoding: KeyEncoding.String, + valueEncoding: encoding, + }) + if (typeof root === 'string') { + opts.root = unprefixedHexToBytes(root) + } else { + opts.root = root + } + } else { + await opts?.db.put( + bytesToUnprefixedHex(key), + (encoding === ValueEncoding.Bytes ? opts.root : bytesToUnprefixedHex(opts.root)), + { + keyEncoding: KeyEncoding.String, + valueEncoding: encoding, + } + ) + } + } + + return new Trie(opts) +} + +/** + * Create a trie from a given (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof. A proof contains the encoded trie nodes + * from the root node to the leaf node storing state data. + * @param proof an EIP-1186 proof to create trie from + * @param shouldVerifyRoot If `true`, verifies that the root key of the proof matches the trie root. Throws if this is not the case. + * @param trieOpts trie opts to be applied to returned trie + * @returns new trie created from given proof + */ +export async function createTrieFromProof(proof: Proof, trieOpts?: TrieOpts) { + const shouldVerifyRoot = trieOpts?.root !== undefined + const trie = new Trie(trieOpts) + const root = await trie.updateFromProof(proof, shouldVerifyRoot) + trie.root(root) + await trie.persistRoot() + return trie +} diff --git a/packages/trie/src/index.ts b/packages/trie/src/index.ts index 3bde6e4903..ed566d8a3c 100644 --- a/packages/trie/src/index.ts +++ b/packages/trie/src/index.ts @@ -1,3 +1,4 @@ +export * from './constructors.js' export * from './db/index.js' export * from './node/index.js' export * from './proof/index.js' diff --git a/packages/trie/src/proof/index.ts b/packages/trie/src/proof/index.ts index 6f7de1df89..a789891216 100644 --- a/packages/trie/src/proof/index.ts +++ b/packages/trie/src/proof/index.ts @@ -1 +1,67 @@ +import { keccak256 } from 'ethereum-cryptography/keccak' + +import { createTrieFromProof } from '../constructors.js' +import { verifyRangeProof } from '../index.js' +import { bytesToNibbles } from '../util/nibbles.js' + +import type { Proof, TrieOpts } from '../index.js' + +/** + * Static version of verifyProof function with the same behavior. An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes + * from the root node to the leaf node storing state data. + * @param rootHash Root hash of the trie that this proof was created from and is being verified for + * @param key Key that is being verified and that the proof is created for + * @param proof An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes from the root node to the leaf node storing state data. + * @param opts optional, the opts may include a custom hashing function to use with the trie for proof verification + * @throws If proof is found to be invalid. + * @returns The value from the key, or null if valid proof of non-existence. + */ +export async function verifyTrieProof( + key: Uint8Array, + proof: Proof, + opts?: TrieOpts +): Promise { + try { + const proofTrie = await createTrieFromProof(proof, opts) + const value = await proofTrie.get(key, true) + return value + } catch (err: any) { + throw new Error('Invalid proof provided') + } +} + +// /** +// * A range proof is a proof that includes the encoded trie nodes from the root node to leaf node for one or more branches of a trie, +// * allowing an entire range of leaf nodes to be validated. This is useful in applications such as snap sync where contiguous ranges +// * of state trie data is received and validated for constructing world state, locally. Also see {@link verifyRangeProof}. A static +// * version of this function also exists. +// * @param rootHash - root hash of state trie this proof is being verified against. +// * @param firstKey - first key of range being proven. +// * @param lastKey - last key of range being proven. +// * @param keys - key list of leaf data being proven. +// * @param values - value list of leaf data being proven, one-to-one correspondence with keys. +// * @param proof - proof node list, if all-elements-proof where no proof is needed, proof should be null, and both `firstKey` and `lastKey` must be null as well +// * @param opts - optional, the opts may include a custom hashing function to use with the trie for proof verification +// * @returns a flag to indicate whether there exists more trie node in the trie +// */ +export function verifyTrieRangeProof( + rootHash: Uint8Array, + firstKey: Uint8Array | null, + lastKey: Uint8Array | null, + keys: Uint8Array[], + values: Uint8Array[], + proof: Uint8Array[] | null, + opts?: TrieOpts +): Promise { + return verifyRangeProof( + rootHash, + firstKey && bytesToNibbles(firstKey), + lastKey && bytesToNibbles(lastKey), + keys.map((k) => k).map(bytesToNibbles), + values, + proof, + opts?.useKeyHashingFunction ?? keccak256 + ) +} + export * from './range.js' diff --git a/packages/trie/src/proof/range.ts b/packages/trie/src/proof/range.ts index af7938269d..57aafdbd57 100644 --- a/packages/trie/src/proof/range.ts +++ b/packages/trie/src/proof/range.ts @@ -1,5 +1,6 @@ import { equalsBytes } from '@ethereumjs/util' +import { createTrieFromProof } from '../index.js' import { BranchNode, ExtensionNode, LeafNode } from '../node/index.js' import { Trie } from '../trie.js' import { nibblesCompare, nibblestoBytes } from '../util/nibbles.js' @@ -322,7 +323,7 @@ async function verifyProof( proof: Uint8Array[], useKeyHashingFunction: HashKeysFunction ): Promise<{ value: Uint8Array | null; trie: Trie }> { - const proofTrie = await Trie.fromProof(proof, { + const proofTrie = await createTrieFromProof(proof, { root: rootHash, useKeyHashingFunction, }) @@ -499,7 +500,7 @@ export async function verifyRangeProof( ) } - const trie = await Trie.fromProof(proof, { + const trie = await createTrieFromProof(proof, { useKeyHashingFunction, root: rootHash, }) diff --git a/packages/trie/src/trie.ts b/packages/trie/src/trie.ts index 582c4f5e06..4cb59f7afe 100644 --- a/packages/trie/src/trie.ts +++ b/packages/trie/src/trie.ts @@ -13,7 +13,6 @@ import { bytesToUtf8, concatBytes, equalsBytes, - unprefixedHexToBytes, } from '@ethereumjs/util' import debug from 'debug' import { keccak256 } from 'ethereum-cryptography/keccak.js' @@ -81,7 +80,7 @@ export class Trie { * Creates a new trie. * @param opts Options for instantiating the trie * - * Note: in most cases, the static {@link Trie.create} constructor should be used. It uses the same API but provides sensible defaults + * Note: in most cases, {@link createTrie} constructor should be used. It uses the same API but provides sensible defaults */ constructor(opts?: TrieOpts) { let valueEncoding: ValueEncoding @@ -134,101 +133,6 @@ export class Trie { || ----------------`) } - /** - * Create a trie from a given (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof. A proof contains the encoded trie nodes - * from the root node to the leaf node storing state data. - * @param proof an EIP-1186 proof to create trie from - * @param shouldVerifyRoot If `true`, verifies that the root key of the proof matches the trie root. Throws if this is not the case. - * @param trieOpts trie opts to be applied to returned trie - * @returns new trie created from given proof - */ - static async createFromProof( - proof: Proof, - trieOpts?: TrieOpts, - shouldVerifyRoot: boolean = false - ) { - const trie = new Trie(trieOpts) - const root = await trie.updateFromProof(proof, shouldVerifyRoot) - trie.root(root) - await trie.persistRoot() - return trie - } - - /** - * Static version of verifyProof function with the same behavior. An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes - * from the root node to the leaf node storing state data. - * @param rootHash Root hash of the trie that this proof was created from and is being verified for - * @param key Key that is being verified and that the proof is created for - * @param proof An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes from the root node to the leaf node storing state data. - * @param opts optional, the opts may include a custom hashing function to use with the trie for proof verification - * @throws If proof is found to be invalid. - * @returns The value from the key, or null if valid proof of non-existence. - */ - static async verifyProof( - key: Uint8Array, - proof: Proof, - opts?: TrieOpts - ): Promise { - try { - const proofTrie = await Trie.createFromProof(proof, opts) - const value = await proofTrie.get(key, true) - return value - } catch (err: any) { - throw new Error('Invalid proof provided') - } - } - - /** - * A range proof is a proof that includes the encoded trie nodes from the root node to leaf node for one or more branches of a trie, - * allowing an entire range of leaf nodes to be validated. This is useful in applications such as snap sync where contiguous ranges - * of state trie data is received and validated for constructing world state, locally. Also see {@link verifyRangeProof}. A static - * version of this function also exists. - * @param rootHash - root hash of state trie this proof is being verified against. - * @param firstKey - first key of range being proven. - * @param lastKey - last key of range being proven. - * @param keys - key list of leaf data being proven. - * @param values - value list of leaf data being proven, one-to-one correspondence with keys. - * @param proof - proof node list, if all-elements-proof where no proof is needed, proof should be null, and both `firstKey` and `lastKey` must be null as well - * @param opts - optional, the opts may include a custom hashing function to use with the trie for proof verification - * @returns a flag to indicate whether there exists more trie node in the trie - */ - static verifyRangeProof( - rootHash: Uint8Array, - firstKey: Uint8Array | null, - lastKey: Uint8Array | null, - keys: Uint8Array[], - values: Uint8Array[], - proof: Uint8Array[] | null, - opts?: TrieOpts - ): Promise { - return verifyRangeProof( - rootHash, - firstKey && bytesToNibbles(firstKey), - lastKey && bytesToNibbles(lastKey), - keys.map((k) => k).map(bytesToNibbles), - values, - proof, - opts?.useKeyHashingFunction ?? keccak256 - ) - } - - /** - * Static version of fromProof function. If a root is provided in the opts param, the proof will be checked to have the same expected root. An - * (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes from the root node to the leaf node storing state data. - * @param proof An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains the encoded trie nodes from the root node to the leaf node storing state data. - * @deprecated Use `createFromProof` - */ - static async fromProof(proof: Proof, opts?: TrieOpts): Promise { - const trie = await Trie.create(opts) - if (opts?.root && !equalsBytes(opts.root, trie.hash(proof[0]))) { - throw new Error('Invalid proof provided') - } - const root = await trie.updateFromProof(proof) - trie.root(root) - await trie.persistRoot() - return trie - } - /** * A range proof is a proof that includes the encoded trie nodes from the root node to leaf node for one or more branches of a trie, * allowing an entire range of leaf nodes to be validated. This is useful in applications such as snap sync where contiguous ranges @@ -262,7 +166,7 @@ export class Trie { } /** - * Creates a proof from a trie and key that can be verified using {@link Trie.verifyProof}. An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains + * Creates a proof from a trie and key that can be verified using {@link verifyTrieProof}. An (EIP-1186)[https://eips.ethereum.org/EIPS/eip-1186] proof contains * the encoded trie nodes from the root node to the leaf node storing state data. The returned proof will be in the format of an array that contains Uint8Arrays of * serialized branch, extension, and/or leaf nodes. * @param key key to create a proof for @@ -380,47 +284,6 @@ export class Trie { return } - static async create(opts?: TrieOpts) { - const keccakFunction = - opts?.common?.customCrypto.keccak256 ?? opts?.useKeyHashingFunction ?? keccak256 - let key = ROOT_DB_KEY - - const encoding = - opts?.valueEncoding === ValueEncoding.Bytes ? ValueEncoding.Bytes : ValueEncoding.String - - if (opts?.useKeyHashing === true) { - key = keccakFunction.call(undefined, ROOT_DB_KEY) as Uint8Array - } - if (opts?.keyPrefix !== undefined) { - key = concatBytes(opts.keyPrefix, key) - } - - if (opts?.db !== undefined && opts?.useRootPersistence === true) { - if (opts?.root === undefined) { - const root = await opts?.db.get(bytesToUnprefixedHex(key), { - keyEncoding: KeyEncoding.String, - valueEncoding: encoding, - }) - if (typeof root === 'string') { - opts.root = unprefixedHexToBytes(root) - } else { - opts.root = root - } - } else { - await opts?.db.put( - bytesToUnprefixedHex(key), - (encoding === ValueEncoding.Bytes ? opts.root : bytesToUnprefixedHex(opts.root)), - { - keyEncoding: KeyEncoding.String, - valueEncoding: encoding, - } - ) - } - } - - return new Trie(opts) - } - database(db?: DB, valueEncoding?: ValueEncoding) { if (db !== undefined) { if (db instanceof CheckpointDB) { diff --git a/packages/trie/test/proof.spec.ts b/packages/trie/test/proof.spec.ts index 3c30e2f992..e74313a367 100644 --- a/packages/trie/test/proof.spec.ts +++ b/packages/trie/test/proof.spec.ts @@ -2,7 +2,7 @@ import { RLP } from '@ethereumjs/rlp' import { bytesToUtf8, equalsBytes, setLengthLeft, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { Trie } from '../src/index.js' +import { Trie, createTrieFromProof, verifyTrieProof } from '../src/index.js' describe('simple merkle proofs generation and verification', () => { it('create a merkle proof and verify it', async () => { @@ -13,28 +13,28 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(utf8ToBytes('key3cc'), utf8ToBytes('aval3')) let proof = await trie.createProof(utf8ToBytes('key2bb')) - let val = await Trie.verifyProof(utf8ToBytes('key2bb'), proof) + let val = await verifyTrieProof(utf8ToBytes('key2bb'), proof) assert.equal(bytesToUtf8(val!), 'aval2') proof = await trie.createProof(utf8ToBytes('key1aa')) - val = await Trie.verifyProof(utf8ToBytes('key1aa'), proof) + val = await verifyTrieProof(utf8ToBytes('key1aa'), proof) assert.equal(bytesToUtf8(val!), '0123456789012345678901234567890123456789xx') proof = await trie.createProof(utf8ToBytes('key2bb')) - val = await Trie.verifyProof(utf8ToBytes('key2'), proof) + val = await verifyTrieProof(utf8ToBytes('key2'), proof) // In this case, the proof _happens_ to contain enough nodes to prove `key2` because // traversing into `key22` would touch all the same nodes as traversing into `key2` assert.equal(val, null, 'Expected value at a random key to be null') let myKey = utf8ToBytes('anyrandomkey') proof = await trie.createProof(myKey) - val = await Trie.verifyProof(myKey, proof) + val = await verifyTrieProof(myKey, proof) assert.equal(val, null, 'Expected value to be null') myKey = utf8ToBytes('anothergarbagekey') // should generate a valid proof of null proof = await trie.createProof(myKey) proof.push(utf8ToBytes('123456')) // extra nodes are just ignored - val = await Trie.verifyProof(myKey, proof) + val = await verifyTrieProof(myKey, proof) assert.equal(val, null, 'Expected value to be null') await trie.put(utf8ToBytes('another'), utf8ToBytes('3498h4riuhgwe')) @@ -43,7 +43,7 @@ describe('simple merkle proofs generation and verification', () => { proof = await trie.createProof(utf8ToBytes('another')) // and try to use that proof on another key try { - await Trie.verifyProof(utf8ToBytes('key1aa'), proof) + await verifyTrieProof(utf8ToBytes('key1aa'), proof) assert.fail('expected error: Invalid proof provided') } catch (e: any) { assert.equal(e.message, 'Invalid proof provided') @@ -53,7 +53,7 @@ describe('simple merkle proofs generation and verification', () => { proof = await trie.createProof(utf8ToBytes('key2bb')) proof[0].reverse() try { - await Trie.verifyProof(utf8ToBytes('key2bb'), proof) + await verifyTrieProof(utf8ToBytes('key2bb'), proof) assert.fail('expected error: Invalid proof provided') } catch (e: any) { assert.equal(e.message, 'Invalid proof provided') @@ -63,15 +63,15 @@ describe('simple merkle proofs generation and verification', () => { // a valid exclusion proof then making it non-null myKey = utf8ToBytes('anyrandomkey') proof = await trie.createProof(myKey) - val = await Trie.verifyProof(myKey, proof) + val = await verifyTrieProof(myKey, proof) assert.equal(val, null, 'Expected value to be null') // now make the key non-null so the exclusion proof becomes invalid await trie.put(myKey, utf8ToBytes('thisisavalue')) try { - await Trie.fromProof(proof, { root: trie.root() }) - assert.fail(`expected error: Invalid proof provided`) + await createTrieFromProof(proof, { root: trie.root() }) + assert.fail(`expected error: 'The provided proof does not have the expected trie root'`) } catch (e: any) { - assert.equal(e.message, 'Invalid proof provided') + assert.equal(e.message, 'The provided proof does not have the expected trie root') } }) @@ -81,7 +81,7 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(utf8ToBytes('key1aa'), utf8ToBytes('0123456789012345678901234567890123456789xx')) const proof = await trie.createProof(utf8ToBytes('key1aa')) - const val = await Trie.verifyProof(utf8ToBytes('key1aa'), proof) + const val = await verifyTrieProof(utf8ToBytes('key1aa'), proof) assert.equal(bytesToUtf8(val!), '0123456789012345678901234567890123456789xx') }) @@ -91,7 +91,7 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(utf8ToBytes('key1aa'), utf8ToBytes('01234')) const proof = await trie.createProof(utf8ToBytes('key1aa')) - const val = await Trie.verifyProof(utf8ToBytes('key1aa'), proof) + const val = await verifyTrieProof(utf8ToBytes('key1aa'), proof) assert.equal(bytesToUtf8(val!), '01234') }) @@ -112,15 +112,15 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(utf8ToBytes('key3'), utf8ToBytes('1234567890123456789012345678901')) let proof = await trie.createProof(utf8ToBytes('key1')) - let val = await Trie.verifyProof(utf8ToBytes('key1'), proof) + let val = await verifyTrieProof(utf8ToBytes('key1'), proof) assert.equal(bytesToUtf8(val!), '0123456789012345678901234567890123456789Very_Long') proof = await trie.createProof(utf8ToBytes('key2')) - val = await Trie.verifyProof(utf8ToBytes('key2'), proof) + val = await verifyTrieProof(utf8ToBytes('key2'), proof) assert.equal(bytesToUtf8(val!), 'short') proof = await trie.createProof(utf8ToBytes('key3')) - val = await Trie.verifyProof(utf8ToBytes('key3'), proof) + val = await verifyTrieProof(utf8ToBytes('key3'), proof) assert.equal(bytesToUtf8(val!), '1234567890123456789012345678901') }) @@ -132,15 +132,15 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(utf8ToBytes('c'), utf8ToBytes('c')) let proof = await trie.createProof(utf8ToBytes('a')) - let val = await Trie.verifyProof(utf8ToBytes('a'), proof) + let val = await verifyTrieProof(utf8ToBytes('a'), proof) assert.equal(bytesToUtf8(val!), 'a') proof = await trie.createProof(utf8ToBytes('b')) - val = await Trie.verifyProof(utf8ToBytes('b'), proof) + val = await verifyTrieProof(utf8ToBytes('b'), proof) assert.equal(bytesToUtf8(val!), 'b') proof = await trie.createProof(utf8ToBytes('c')) - val = await Trie.verifyProof(utf8ToBytes('c'), proof) + val = await verifyTrieProof(utf8ToBytes('c'), proof) assert.equal(bytesToUtf8(val!), 'c') }) @@ -161,7 +161,7 @@ describe('simple merkle proofs generation and verification', () => { await trie.put(key3, encodedValue3) const proof = await trie.createProof(key) - const newTrie = await Trie.createFromProof(proof, { useKeyHashing: true }) + const newTrie = await createTrieFromProof(proof, { useKeyHashing: true }) const trieValue = await newTrie.get(key) assert.ok(equalsBytes(trieValue!, encodedValue), 'trie value sucessfully copied') diff --git a/packages/trie/test/trie/checkpoint.spec.ts b/packages/trie/test/trie/checkpoint.spec.ts index 3e0d320b7e..c5ea661609 100644 --- a/packages/trie/test/trie/checkpoint.spec.ts +++ b/packages/trie/test/trie/checkpoint.spec.ts @@ -10,7 +10,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { sha256 } from 'ethereum-cryptography/sha256.js' import { assert, describe, it } from 'vitest' -import { ROOT_DB_KEY, Trie } from '../../src/index.js' +import { ROOT_DB_KEY, Trie, createTrie } from '../../src/index.js' import type { BatchDBOp } from '@ethereumjs/util' @@ -209,7 +209,7 @@ describe('testing checkpoints', () => { const KEY_ROOT = keccak256(ROOT_DB_KEY) // Initialise State - const CommittedState = await Trie.create({ + const CommittedState = await createTrie({ useKeyHashing: true, useNodePruning: true, useRootPersistence: true, diff --git a/packages/trie/test/trie/prune.spec.ts b/packages/trie/test/trie/prune.spec.ts index bee6d082bb..dc332a5420 100644 --- a/packages/trie/test/trie/prune.spec.ts +++ b/packages/trie/test/trie/prune.spec.ts @@ -1,7 +1,7 @@ import { KECCAK256_RLP, equalsBytes, hexToBytes, randomBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { Trie, isRawNode } from '../../src/index.js' +import { Trie, createTrie, isRawNode } from '../../src/index.js' import type { BranchNode } from '../../src/index.js' @@ -207,7 +207,7 @@ describe('Pruned trie tests', () => { it('should prune when keys are updated or deleted (with `useRootPersistence` enabled)', async () => { for (let testID = 0; testID < 1; testID++) { - const trie = await Trie.create({ useNodePruning: true, useRootPersistence: true }) + const trie = await createTrie({ useNodePruning: true, useRootPersistence: true }) const keys: Uint8Array[] = [] for (let i = 0; i < 100; i++) { keys.push(randomBytes(32)) diff --git a/packages/trie/test/trie/secure.spec.ts b/packages/trie/test/trie/secure.spec.ts index 7700b596ac..f6b46483e8 100644 --- a/packages/trie/test/trie/secure.spec.ts +++ b/packages/trie/test/trie/secure.spec.ts @@ -10,7 +10,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { sha256 } from 'ethereum-cryptography/sha256.js' import { assert, describe, it } from 'vitest' -import { ROOT_DB_KEY, Trie } from '../../src/index.js' +import { ROOT_DB_KEY, Trie, verifyTrieProof } from '../../src/index.js' import secureTrieTests from '../fixtures/trietest_secureTrie.json' describe('SecureTrie', () => { @@ -53,7 +53,7 @@ describe('SecureTrie proof', () => { await trie.put(utf8ToBytes('key1aa'), utf8ToBytes('01234')) const proof = await trie.createProof(utf8ToBytes('key1aa')) - const val = await Trie.verifyProof(utf8ToBytes('key1aa'), proof, { + const val = await verifyTrieProof(utf8ToBytes('key1aa'), proof, { useKeyHashing: true, }) assert.deepEqual(val, utf8ToBytes('01234')) diff --git a/packages/trie/test/trie/trie.spec.ts b/packages/trie/test/trie/trie.spec.ts index 879fd0fb65..9f06d99b08 100644 --- a/packages/trie/test/trie/trie.spec.ts +++ b/packages/trie/test/trie/trie.spec.ts @@ -11,7 +11,7 @@ import { import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' -import { ROOT_DB_KEY as BASE_DB_KEY, Trie } from '../../src/index.js' +import { ROOT_DB_KEY as BASE_DB_KEY, Trie, createTrie } from '../../src/index.js' for (const { constructor, defaults, title } of [ { @@ -43,18 +43,18 @@ for (const { constructor, defaults, title } of [ } describe(`${title} (Persistence)`, () => { - it('creates an instance via the static constructor `create` function and defaults to `false` with a database', async () => { + it('creates an instance via createTrie and defaults to `false` with a database', async () => { // TODO: check this test assert.isUndefined( - ((await constructor.create({ ...defaults, db: new MapDB() })) as any)._useRootPersistence + ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence ) }) - it('creates an instance via the static constructor `create` function and respects the `useRootPersistence` option with a database', async () => { + it('creates an instance via createTrie and respects the `useRootPersistence` option with a database', async () => { // TODO: check this test assert.isUndefined( ( - (await constructor.create({ + (await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: false, @@ -63,11 +63,11 @@ for (const { constructor, defaults, title } of [ ) }) - it('creates an instance via the static constructor `create` function and respects the `useRootPersistence` option with a database', async () => { + it('creates an instance via createTrie and respects the `useRootPersistence` option with a database', async () => { // TODO: check this test assert.isUndefined( ( - (await constructor.create({ + (await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: false, @@ -76,15 +76,15 @@ for (const { constructor, defaults, title } of [ ) }) - it('creates an instance via the static constructor `create` function and defaults to `false` without a database', async () => { + it('creates an instance via createTrie and defaults to `false` without a database', async () => { // TODO: check this test assert.isUndefined( - ((await constructor.create({ ...defaults, db: new MapDB() })) as any)._useRootPersistence + ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence ) }) it('persist the root if the `useRootPersistence` option is `true`', async () => { - const trie = await constructor.create({ + const trie = await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: true, @@ -98,7 +98,7 @@ for (const { constructor, defaults, title } of [ }) it('persist the root if the `root` option is given', async () => { - const trie = await constructor.create({ + const trie = await createTrie({ ...defaults, db: new MapDB(), root: KECCAK256_RLP, @@ -113,7 +113,7 @@ for (const { constructor, defaults, title } of [ }) it('does not persist the root if the `useRootPersistence` option is `false`', async () => { - const trie = await constructor.create({ + const trie = await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: false, @@ -127,7 +127,7 @@ for (const { constructor, defaults, title } of [ }) it('persists the root if the `db` option is not provided', async () => { - const trie = await constructor.create({ ...defaults, useRootPersistence: true }) + const trie = await createTrie({ ...defaults, useRootPersistence: true }) assert.equal(await trie['_db'].get(ROOT_DB_KEY), undefined) @@ -139,17 +139,17 @@ for (const { constructor, defaults, title } of [ it('persist and restore the root', async () => { const db = new MapDB() - const trie = await constructor.create({ ...defaults, db, useRootPersistence: true }) + const trie = await createTrie({ ...defaults, db, useRootPersistence: true }) assert.equal(await trie['_db'].get(ROOT_DB_KEY), undefined) await trie.put(utf8ToBytes('foo'), utf8ToBytes('bar')) assert.equal(bytesToHex((await trie['_db'].get(ROOT_DB_KEY))!), EXPECTED_ROOTS) // Using the same database as `trie` so we should have restored the root - const copy = await constructor.create({ ...defaults, db, useRootPersistence: true }) + const copy = await createTrie({ ...defaults, db, useRootPersistence: true }) assert.equal(bytesToHex((await copy['_db'].get(ROOT_DB_KEY))!), EXPECTED_ROOTS) // New trie with a new database so we shouldn't find a root to restore - const empty = await constructor.create({ + const empty = await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: true, @@ -175,7 +175,7 @@ for (const { constructor, defaults, title } of [ const value = randomBytes(10) return { key, value } }) - const trie = await constructor.create({ + const trie = await createTrie({ ...defaults, db: new MapDB(), }) @@ -199,7 +199,7 @@ for (const { constructor, defaults, title } of [ } }) it('should return false for all keys if trie is empty', async () => { - const emptyTrie = await constructor.create({ + const emptyTrie = await createTrie({ ...defaults, db: new MapDB(), }) @@ -220,7 +220,7 @@ for (const { constructor, defaults, title } of [ } }) it('Should throw on unrelated errors', async () => { - const emptyTrie = await constructor.create({ + const emptyTrie = await createTrie({ ...defaults, db: new MapDB(), useRootPersistence: true, @@ -252,8 +252,8 @@ describe('keyHashingFunction', async () => { }, } - const trieWithHashFunction = await Trie.create({ useKeyHashingFunction: keyHashingFunction }) - const trieWithCommon = await Trie.create({ common: c }) + const trieWithHashFunction = await createTrie({ useKeyHashingFunction: keyHashingFunction }) + const trieWithCommon = await createTrie({ common: c }) assert.equal( bytesToHex(trieWithHashFunction.root()), @@ -273,9 +273,9 @@ describe('keyHashingFunction', async () => { }, } - const trieWithHashFunction = await Trie.create({ useKeyHashingFunction: keyHashingFunction }) + const trieWithHashFunction = await createTrie({ useKeyHashingFunction: keyHashingFunction }) const trieWithHashFunctionCopy = trieWithHashFunction.shallowCopy() - const trieWithCommon = await Trie.create({ common: c }) + const trieWithCommon = await createTrie({ common: c }) const trieWithCommonCopy = trieWithCommon.shallowCopy() assert.equal( diff --git a/packages/trie/test/util/asyncWalk.spec.ts b/packages/trie/test/util/asyncWalk.spec.ts index e2bf4b9088..51fefddc9f 100644 --- a/packages/trie/test/util/asyncWalk.spec.ts +++ b/packages/trie/test/util/asyncWalk.spec.ts @@ -1,7 +1,7 @@ import { bytesToHex, equalsBytes, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { LeafNode, Trie } from '../../src/index.js' +import { LeafNode, Trie, createTrieFromProof, verifyTrieProof } from '../../src/index.js' import { _walkTrie } from '../../src/util/asyncWalk.js' import { bytesToNibbles } from '../../src/util/nibbles.js' import trieTests from '../fixtures/trietest.json' @@ -79,10 +79,10 @@ describe('walk a sparse trie', async () => { // Generate a proof for inputs[0] const proofKey = inputs[0][0] const proof = await trie.createProof(proofKey) - assert.ok(await Trie.verifyProof(proofKey, proof)) + assert.ok(await verifyTrieProof(proofKey, proof)) // Build a sparse trie from the proof - const fromProof = await Trie.fromProof(proof, { root: trie.root() }) + const fromProof = await createTrieFromProof(proof, { root: trie.root() }) // Walk the sparse trie const walker = fromProof.walkTrieIterable(fromProof.root()) From 10e74b9289b15f5348fa8a8eef6eb8cc113b1fa9 Mon Sep 17 00:00:00 2001 From: Scotty <66335769+ScottyPoi@users.noreply.github.com> Date: Thu, 18 Jul 2024 02:17:01 -0600 Subject: [PATCH 07/58] EVM: replace static constructor (#3516) * EVM: replace static constructor * update downstream * update in tests --------- Co-authored-by: Holger Drewes --- packages/evm/examples/eips.ts | 4 +- packages/evm/examples/runCode.ts | 4 +- packages/evm/examples/simple.ts | 4 +- packages/evm/examples/withBlockchain.ts | 4 +- packages/evm/src/constructors.ts | 38 ++++++++++++++++ packages/evm/src/evm.ts | 40 ++--------------- packages/evm/src/index.ts | 2 + packages/evm/src/types.ts | 2 +- packages/evm/test/asyncEvents.spec.ts | 5 ++- packages/evm/test/blobVersionedHashes.spec.ts | 8 ++-- packages/evm/test/customCrypto.spec.ts | 7 ++- packages/evm/test/customOpcodes.spec.ts | 14 +++--- packages/evm/test/customPrecompiles.spec.ts | 19 ++++---- packages/evm/test/eips/eip-3860.spec.ts | 18 ++++---- packages/evm/test/eips/eip-5656.spec.ts | 4 +- packages/evm/test/opcodes.spec.ts | 14 +++--- .../evm/test/precompiles/01-ecrecover.spec.ts | 4 +- .../evm/test/precompiles/03-ripemd160.spec.ts | 4 +- .../evm/test/precompiles/05-modexp.spec.ts | 5 ++- .../evm/test/precompiles/06-ecadd.spec.ts | 4 +- .../evm/test/precompiles/07-ecmul.spec.ts | 4 +- .../evm/test/precompiles/08-ecpairing.spec.ts | 4 +- .../evm/test/precompiles/09-blake2f.spec.ts | 5 ++- .../precompiles/0a-pointevaluation.spec.ts | 4 +- .../evm/test/precompiles/eip-2537-bls.spec.ts | 6 +-- .../evm/test/precompiles/hardfork.spec.ts | 8 ++-- packages/evm/test/runCall.spec.ts | 44 +++++++++---------- packages/evm/test/runCode.spec.ts | 10 ++--- packages/evm/test/stack.spec.ts | 4 +- packages/statemanager/examples/evm.ts | 4 +- .../statemanager/test/rpcStateManager.spec.ts | 4 +- packages/vm/src/vm.ts | 6 +-- .../vm/test/api/EIPs/eip-6800-verkle.spec.ts | 4 +- packages/vm/test/api/index.spec.ts | 4 +- 34 files changed, 162 insertions(+), 153 deletions(-) create mode 100644 packages/evm/src/constructors.ts diff --git a/packages/evm/examples/eips.ts b/packages/evm/examples/eips.ts index 91c15891d0..09b0986e1c 100644 --- a/packages/evm/examples/eips.ts +++ b/packages/evm/examples/eips.ts @@ -1,9 +1,9 @@ import { Chain, Common } from '@ethereumjs/common' -import { EVM } from '@ethereumjs/evm' +import { createEVM, EVM } from '@ethereumjs/evm' const main = async () => { const common = new Common({ chain: Chain.Mainnet, eips: [3074] }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) console.log(`EIP 3074 is active - ${evm.common.isActivatedEIP(3074)}`) } diff --git a/packages/evm/examples/runCode.ts b/packages/evm/examples/runCode.ts index d442043e37..901cf97c80 100644 --- a/packages/evm/examples/runCode.ts +++ b/packages/evm/examples/runCode.ts @@ -1,13 +1,13 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { EVM } from '@ethereumjs/evm' +import { createEVM, EVM } from '@ethereumjs/evm' import { bytesToHex, hexToBytes } from '@ethereumjs/util' const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const blockchain = await createBlockchain() - const evm = await EVM.create({ + const evm = await createEVM({ common, blockchain, }) diff --git a/packages/evm/examples/simple.ts b/packages/evm/examples/simple.ts index 06bc94176f..9600f3b5e7 100644 --- a/packages/evm/examples/simple.ts +++ b/packages/evm/examples/simple.ts @@ -1,8 +1,8 @@ import { hexToBytes } from '@ethereumjs/util' -import { EVM } from '@ethereumjs/evm' +import { createEVM, EVM } from '@ethereumjs/evm' const main = async () => { - const evm = await EVM.create() + const evm = await createEVM() const res = await evm.runCode({ code: hexToBytes('0x6001') }) // PUSH1 01 -- simple bytecode to push 1 onto the stack console.log(res.executionGasUsed) // 3n } diff --git a/packages/evm/examples/withBlockchain.ts b/packages/evm/examples/withBlockchain.ts index f7ba32049e..6b046cd466 100644 --- a/packages/evm/examples/withBlockchain.ts +++ b/packages/evm/examples/withBlockchain.ts @@ -1,6 +1,6 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { EVM } from '@ethereumjs/evm' +import { createEVM, EVM } from '@ethereumjs/evm' import { DefaultStateManager } from '@ethereumjs/statemanager' import { bytesToHex } from '@ethereumjs/util' @@ -9,7 +9,7 @@ const main = async () => { const stateManager = new DefaultStateManager() const blockchain = await createBlockchain() - const evm = await EVM.create({ + const evm = await createEVM({ common, stateManager, blockchain, diff --git a/packages/evm/src/constructors.ts b/packages/evm/src/constructors.ts new file mode 100644 index 0000000000..f19cc0ba76 --- /dev/null +++ b/packages/evm/src/constructors.ts @@ -0,0 +1,38 @@ +import { Chain, Common } from '@ethereumjs/common' +import { SimpleStateManager } from '@ethereumjs/statemanager' +import { initRustBN } from 'rustbn-wasm' + +import { DefaultBlockchain } from './types.js' + +import { EVM } from './index.js' + +import type { EVMOpts, bn128 } from './index.js' + +let initializedRustBN: bn128 | undefined = undefined + +/** + * Use this async static constructor for the initialization + * of an EVM object + * + * @param createOpts The EVM options + * @returns A new EVM + */ +export async function createEVM(createOpts?: EVMOpts) { + const opts = createOpts ?? ({} as EVMOpts) + const bn128 = initializedRustBN ?? ((await initRustBN()) as bn128) + initializedRustBN = bn128 + + if (opts.common === undefined) { + opts.common = new Common({ chain: Chain.Mainnet }) + } + + if (opts.blockchain === undefined) { + opts.blockchain = new DefaultBlockchain() + } + + if (opts.stateManager === undefined) { + opts.stateManager = new SimpleStateManager() + } + + return new EVM(opts, bn128) +} diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index 9cb4b6611c..6e3d677284 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -1,5 +1,4 @@ -import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { SimpleStateManager } from '@ethereumjs/statemanager' +import { Hardfork } from '@ethereumjs/common' import { Account, Address, @@ -18,7 +17,6 @@ import { zeros, } from '@ethereumjs/util' import debugDefault from 'debug' -import { initRustBN } from 'rustbn-wasm' import { EOF, getEOFCode } from './eof.js' import { ERROR, EvmError } from './exceptions.js' @@ -29,7 +27,6 @@ import { Message } from './message.js' import { getOpcodesForHF } from './opcodes/index.js' import { NobleBLS, getActivePrecompiles, getPrecompileName } from './precompiles/index.js' import { TransientStorage } from './transientStorage.js' -import { DefaultBlockchain } from './types.js' import type { InterpreterOpts } from './interpreter.js' import type { Timer } from './logger.js' @@ -51,14 +48,12 @@ import type { ExecResult, bn128, } from './types.js' -import type { EVMStateManagerInterface } from '@ethereumjs/common' +import type { Common, EVMStateManagerInterface } from '@ethereumjs/common' const debug = debugDefault('evm:evm') const debugGas = debugDefault('evm:gas') const debugPrecompiles = debugDefault('evm:precompiles') -let initializedRustBN: bn128 | undefined = undefined - /** * EVM is responsible for executing an EVM message fully * (including any nested calls and creates), processing the results @@ -147,45 +142,18 @@ export class EVM implements EVMInterface { private _bn128: bn128 - /** - * Use this async static constructor for the initialization - * of an EVM object - * - * @param createOpts The EVM options - * @returns A new EVM - */ - static async create(createOpts?: EVMOpts) { - const opts = createOpts ?? ({} as EVMOpts) - const bn128 = initializedRustBN ?? ((await initRustBN()) as bn128) - initializedRustBN = bn128 - - if (opts.common === undefined) { - opts.common = new Common({ chain: Chain.Mainnet }) - } - - if (opts.blockchain === undefined) { - opts.blockchain = new DefaultBlockchain() - } - - if (opts.stateManager === undefined) { - opts.stateManager = new SimpleStateManager() - } - - return new EVM(opts, bn128) - } - /** * * Creates new EVM object * * @deprecated The direct usage of this constructor is replaced since * non-finalized async initialization lead to side effects. Please - * use the async {@link EVM.create} constructor instead (same API). + * use the async {@link createEVM} constructor instead (same API). * * @param opts The EVM options * @param bn128 Initialized bn128 WASM object for precompile usage (internal) */ - protected constructor(opts: EVMOpts, bn128: bn128) { + constructor(opts: EVMOpts, bn128: bn128) { this.common = opts.common! this.blockchain = opts.blockchain! this.stateManager = opts.stateManager! diff --git a/packages/evm/src/index.ts b/packages/evm/src/index.ts index 3c2303d301..e1636497ee 100644 --- a/packages/evm/src/index.ts +++ b/packages/evm/src/index.ts @@ -47,3 +47,5 @@ export { Message, NobleBLS, } + +export * from './constructors.js' diff --git a/packages/evm/src/types.ts b/packages/evm/src/types.ts index fa420aa964..ce787f5c1a 100644 --- a/packages/evm/src/types.ts +++ b/packages/evm/src/types.ts @@ -273,7 +273,7 @@ export interface EVMOpts { * import * as mcl from 'mcl-wasm' * * await mcl.init(mcl.BLS12_381) - * const evm = await EVM.create({ bls: new MCLBLS(mcl) }) + * const evm = await createEVM({ bls: new MCLBLS(mcl) }) * ``` */ bls?: EVMBLSInterface diff --git a/packages/evm/test/asyncEvents.spec.ts b/packages/evm/test/asyncEvents.spec.ts index 88972a567e..ca5582f22f 100644 --- a/packages/evm/test/asyncEvents.spec.ts +++ b/packages/evm/test/asyncEvents.spec.ts @@ -2,12 +2,13 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' + describe('async events', () => { it('should work', async () => { const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) evm.events.on('step', async (event, next) => { diff --git a/packages/evm/test/blobVersionedHashes.spec.ts b/packages/evm/test/blobVersionedHashes.spec.ts index 4608c571a6..7bc20dcb7f 100644 --- a/packages/evm/test/blobVersionedHashes.spec.ts +++ b/packages/evm/test/blobVersionedHashes.spec.ts @@ -2,7 +2,7 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' import { Account, Address, bytesToHex, hexToBytes, unpadBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' import type { EVMRunCallOpts } from '../src/types.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -15,7 +15,7 @@ describe('BLOBHASH / access blobVersionedHashes in calldata', () => { chain: 'custom', hardfork: Hardfork.Cancun, }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) @@ -45,7 +45,7 @@ describe(`BLOBHASH: access blobVersionedHashes within contract calls`, () => { chain: 'custom', hardfork: Hardfork.Cancun, }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) @@ -95,7 +95,7 @@ describe(`BLOBHASH: access blobVersionedHashes in a CREATE/CREATE2 frame`, () => chain: 'custom', hardfork: Hardfork.Cancun, }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) diff --git a/packages/evm/test/customCrypto.spec.ts b/packages/evm/test/customCrypto.spec.ts index 43a3a5a5d1..7f75682f1b 100644 --- a/packages/evm/test/customCrypto.spec.ts +++ b/packages/evm/test/customCrypto.spec.ts @@ -9,8 +9,7 @@ import { } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/evm.js' -import { getActivePrecompiles } from '../src/index.js' +import { createEVM, getActivePrecompiles } from '../src/index.js' describe('custom crypto', () => { it('should use custom sha256 function', async () => { @@ -23,7 +22,7 @@ describe('custom crypto', () => { } const msg = Uint8Array.from([0, 1, 2, 3]) const common = new Common({ chain: Chain.Mainnet, customCrypto }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const addressStr = '0000000000000000000000000000000000000002' const SHA256 = getActivePrecompiles(common).get(addressStr)! const result = await SHA256({ @@ -46,7 +45,7 @@ describe('custom crypto', () => { } const msg = concatBytes(randomBytes(32), setLengthLeft(intToBytes(27), 32), randomBytes(32)) const common = new Common({ chain: Chain.Mainnet, customCrypto }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const addressStr = '0000000000000000000000000000000000000001' const ECRECOVER = getActivePrecompiles(common).get(addressStr)! const result = await ECRECOVER({ diff --git a/packages/evm/test/customOpcodes.spec.ts b/packages/evm/test/customOpcodes.spec.ts index 52a5551c4f..807be3c29e 100644 --- a/packages/evm/test/customOpcodes.spec.ts +++ b/packages/evm/test/customOpcodes.spec.ts @@ -1,7 +1,7 @@ import { equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/evm.js' +import { createEVM } from '../src/index.js' import type { InterpreterStep, RunState } from '../src/interpreter.js' import type { AddOpcode } from '../src/types.js' @@ -25,7 +25,7 @@ describe('VM: custom opcodes', () => { } it('should add custom opcodes to the EVM', async () => { - const evm = await EVM.create({ customOpcodes: [testOpcode] }) + const evm = await createEVM({ customOpcodes: [testOpcode] }) const gas = 123456 let correctOpcodeName = false evm.events.on('step', (e: InterpreterStep) => { @@ -43,7 +43,7 @@ describe('VM: custom opcodes', () => { }) it('should delete opcodes from the EVM', async () => { - const evm = await EVM.create({ + const evm = await createEVM({ customOpcodes: [{ opcode: 0x20 }], // deletes KECCAK opcode }) const gas = BigInt(123456) @@ -57,7 +57,7 @@ describe('VM: custom opcodes', () => { it('should not override default opcodes', async () => { // This test ensures that always the original opcode map is used // Thus, each time you recreate a EVM, it is in a clean state - const evm = await EVM.create({ + const evm = await createEVM({ customOpcodes: [{ opcode: 0x01 }], // deletes ADD opcode }) const gas = BigInt(123456) @@ -67,7 +67,7 @@ describe('VM: custom opcodes', () => { }) assert.ok(res.executionGasUsed === gas, 'successfully deleted opcode') - const evmDefault = await EVM.create() + const evmDefault = await createEVM() // PUSH 04 // PUSH 01 @@ -86,7 +86,7 @@ describe('VM: custom opcodes', () => { it('should override opcodes in the EVM', async () => { testOpcode.opcode = 0x20 // Overrides KECCAK - const evm = await EVM.create({ customOpcodes: [testOpcode] }) + const evm = await createEVM({ customOpcodes: [testOpcode] }) const gas = 123456 const res = await evm.runCode({ code: hexToBytes('0x20'), @@ -109,7 +109,7 @@ describe('VM: custom opcodes', () => { }, } - const evm = await EVM.create({ customOpcodes: [testOpcode] }) + const evm = await createEVM({ customOpcodes: [testOpcode] }) evm.events.on('beforeMessage', () => {}) evm.events.on('beforeMessage', () => {}) const evmCopy = evm.shallowCopy() diff --git a/packages/evm/test/customPrecompiles.spec.ts b/packages/evm/test/customPrecompiles.spec.ts index 244e0d6442..2dd614ce68 100644 --- a/packages/evm/test/customPrecompiles.spec.ts +++ b/packages/evm/test/customPrecompiles.spec.ts @@ -1,9 +1,8 @@ import { Address, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/evm.js' +import { type PrecompileInput, createEVM } from '../src/index.js' -import type { PrecompileInput } from '../src/index.js' import type { ExecResult } from '../src/types.js' const sender = new Address(hexToBytes(`0x${'44'.repeat(20)}`)) @@ -28,7 +27,7 @@ function customPrecompileNoInput(): ExecResult { describe('EVM -> custom precompiles', () => { it('should work on precompiles without input arguments', async () => { - const EVMOverride = await EVM.create({ + const EVMOverride = await createEVM({ customPrecompiles: [ { address: Address.zero(), @@ -47,7 +46,7 @@ describe('EVM -> custom precompiles', () => { assert.equal(result.execResult.executionGasUsed, expectedGas, 'gas used is correct') }) it('should override existing precompiles', async () => { - const EVMOverride = await EVM.create({ + const EVMOverride = await createEVM({ customPrecompiles: [ { address: shaAddress, @@ -67,7 +66,7 @@ describe('EVM -> custom precompiles', () => { }) it('should delete existing precompiles', async () => { - const EVMOverride = await EVM.create({ + const EVMOverride = await createEVM({ customPrecompiles: [ { address: shaAddress, @@ -85,7 +84,7 @@ describe('EVM -> custom precompiles', () => { }) it('should add precompiles', async () => { - const EVMOverride = await EVM.create({ + const EVMOverride = await createEVM({ customPrecompiles: [ { address: newPrecompile, @@ -104,14 +103,14 @@ describe('EVM -> custom precompiles', () => { }) it('should not persist changes to precompiles', async () => { - let EVMSha = await EVM.create() + let EVMSha = await createEVM() const shaResult = await EVMSha.runCall({ to: shaAddress, gasLimit: BigInt(30000), data: hexToBytes('0x'), caller: sender, }) - const EVMOverride = await EVM.create({ + const EVMOverride = await createEVM({ customPrecompiles: [ { address: shaAddress, @@ -128,7 +127,7 @@ describe('EVM -> custom precompiles', () => { // sanity: check we have overridden assert.deepEqual(result.execResult.returnValue, expectedReturn, 'return value is correct') assert.ok(result.execResult.executionGasUsed === expectedGas, 'gas used is correct') - EVMSha = await EVM.create() + EVMSha = await createEVM() const shaResult2 = await EVMSha.runCall({ to: shaAddress, gasLimit: BigInt(30000), @@ -147,7 +146,7 @@ describe('EVM -> custom precompiles', () => { ) }) it('shold copy custom precompiles', async () => { - const evm = await EVM.create({ + const evm = await createEVM({ customPrecompiles: [ { address: shaAddress, diff --git a/packages/evm/test/eips/eip-3860.spec.ts b/packages/evm/test/eips/eip-3860.spec.ts index e46a3bd6d0..bb3b82f5da 100644 --- a/packages/evm/test/eips/eip-3860.spec.ts +++ b/packages/evm/test/eips/eip-3860.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, concatBytes, equalsBytes, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../../src/index.js' +import { createEVM } from '../../src/index.js' const pkey = hexToBytes(`0x${'20'.repeat(32)}`) const sender = new Address(privateToAddress(pkey)) @@ -14,7 +14,7 @@ describe('EIP 3860 tests', () => { hardfork: Hardfork.London, eips: [3860], }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) @@ -54,10 +54,10 @@ describe('EIP 3860 tests', () => { eips: [], }) const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') - const evm = await EVM.create({ + const evm = await createEVM({ common: commonWith3860, }) - const evmWithout3860 = await EVM.create({ + const evmWithout3860 = await createEVM({ common: commonWithout3860, }) const contractFactory = Address.fromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') @@ -98,10 +98,10 @@ describe('EIP 3860 tests', () => { eips: [], }) const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') - const evm = await EVM.create({ + const evm = await createEVM({ common: commonWith3860, }) - const evmWithout3860 = await EVM.create({ + const evmWithout3860 = await createEVM({ common: commonWithout3860, }) const contractFactory = Address.fromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') @@ -135,7 +135,7 @@ describe('EIP 3860 tests', () => { hardfork: Hardfork.London, eips: [3860], }) - const evm = await EVM.create({ + const evm = await createEVM({ common, allowUnlimitedInitCodeSize: true, }) @@ -169,12 +169,12 @@ describe('EIP 3860 tests', () => { }) const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') for (const code of ['F0', 'F5']) { - const evm = await EVM.create({ + const evm = await createEVM({ common: commonWith3860, allowUnlimitedInitCodeSize: true, }) - const evmDisabled = await EVM.create({ + const evmDisabled = await createEVM({ common: commonWith3860, allowUnlimitedInitCodeSize: false, }) diff --git a/packages/evm/test/eips/eip-5656.spec.ts b/packages/evm/test/eips/eip-5656.spec.ts index cccb2639d1..3f66c928c2 100644 --- a/packages/evm/test/eips/eip-5656.spec.ts +++ b/packages/evm/test/eips/eip-5656.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../../src/index.js' +import { createEVM } from '../../src/index.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -85,7 +85,7 @@ describe('should test mcopy', () => { eips: [5656], }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) diff --git a/packages/evm/test/opcodes.spec.ts b/packages/evm/test/opcodes.spec.ts index 3c09aef358..a18b3fa916 100644 --- a/packages/evm/test/opcodes.spec.ts +++ b/packages/evm/test/opcodes.spec.ts @@ -1,7 +1,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' describe('EVM -> getActiveOpcodes()', () => { const DIFFICULTY_PREVRANDAO = 0x44 @@ -9,7 +9,7 @@ describe('EVM -> getActiveOpcodes()', () => { it('should not expose opcodes from a follow-up HF (istanbul -> petersburg)', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) assert.equal( evm.getActiveOpcodes().get(CHAINID), undefined, @@ -19,7 +19,7 @@ describe('EVM -> getActiveOpcodes()', () => { it('should expose opcodes when HF is active (>= istanbul)', async () => { let common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - let evm = await EVM.create({ common }) + let evm = await createEVM({ common }) assert.equal( evm.getActiveOpcodes().get(CHAINID)!.name, 'CHAINID', @@ -27,7 +27,7 @@ describe('EVM -> getActiveOpcodes()', () => { ) common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.MuirGlacier }) - evm = await EVM.create({ common }) + evm = await createEVM({ common }) assert.equal( evm.getActiveOpcodes().get(CHAINID)!.name, 'CHAINID', @@ -37,7 +37,7 @@ describe('EVM -> getActiveOpcodes()', () => { it('should switch DIFFICULTY opcode name to PREVRANDAO when >= Merge HF', async () => { let common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - let evm = await EVM.create({ common }) + let evm = await createEVM({ common }) assert.equal( evm.getActiveOpcodes().get(DIFFICULTY_PREVRANDAO)!.name, 'DIFFICULTY', @@ -45,7 +45,7 @@ describe('EVM -> getActiveOpcodes()', () => { ) common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Paris }) - evm = await EVM.create({ common }) + evm = await createEVM({ common }) assert.equal( evm.getActiveOpcodes().get(DIFFICULTY_PREVRANDAO)!.name, 'PREVRANDAO', @@ -55,7 +55,7 @@ describe('EVM -> getActiveOpcodes()', () => { it('should update opcodes on a hardfork change', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) common.setHardfork(Hardfork.Byzantium) assert.equal( diff --git a/packages/evm/test/precompiles/01-ecrecover.spec.ts b/packages/evm/test/precompiles/01-ecrecover.spec.ts index 977d205ff1..1665f66963 100644 --- a/packages/evm/test/precompiles/01-ecrecover.spec.ts +++ b/packages/evm/test/precompiles/01-ecrecover.spec.ts @@ -3,7 +3,7 @@ import { bytesToHex, bytesToUnprefixedHex, hexToBytes, utf8ToBytes } from '@ethe import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' const prefix = bytesToUnprefixedHex(utf8ToBytes('\x19Ethereum Signed Message:\n32')) const _hash = '852daa74cc3c31fe64542bb9b8764cfb91cc30f9acf9389071ffb44a9eefde46' @@ -17,7 +17,7 @@ describe('Precompiles: ECRECOVER', () => { // Test reference: https://github.com/ethereum/go-ethereum/issues/3731#issuecomment-293866868 const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const addressStr = '0000000000000000000000000000000000000001' diff --git a/packages/evm/test/precompiles/03-ripemd160.spec.ts b/packages/evm/test/precompiles/03-ripemd160.spec.ts index 96859bd65e..8ce317e014 100644 --- a/packages/evm/test/precompiles/03-ripemd160.spec.ts +++ b/packages/evm/test/precompiles/03-ripemd160.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' const input = '38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02' @@ -13,7 +13,7 @@ describe('Precompiles: RIPEMD160', () => { // Test reference: https://github.com/ethereum/go-ethereum/blob/e206d3f8975bd98cc86d14055dca40f996bacc60/core/vm/contracts_test.go#L217 const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const addressStr = '0000000000000000000000000000000000000003' diff --git a/packages/evm/test/precompiles/05-modexp.spec.ts b/packages/evm/test/precompiles/05-modexp.spec.ts index 2e975064d7..fc65b2c0ff 100644 --- a/packages/evm/test/precompiles/05-modexp.spec.ts +++ b/packages/evm/test/precompiles/05-modexp.spec.ts @@ -2,10 +2,11 @@ import { Chain, Common } from '@ethereumjs/common' import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, beforeAll, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' import fuzzer from './modexp-testdata.json' +import type { EVM } from '../../src/index.js' import type { PrecompileFunc } from '../../src/precompiles/types.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -17,7 +18,7 @@ describe('Precompiles: MODEXP', () => { let MODEXP: PrecompileFunc beforeAll(async () => { common = new Common({ chain: Chain.Mainnet }) - evm = await EVM.create({ + evm = await createEVM({ common, }) addressStr = '0000000000000000000000000000000000000005' diff --git a/packages/evm/test/precompiles/06-ecadd.spec.ts b/packages/evm/test/precompiles/06-ecadd.spec.ts index 0a7b597311..44b22293e6 100644 --- a/packages/evm/test/precompiles/06-ecadd.spec.ts +++ b/packages/evm/test/precompiles/06-ecadd.spec.ts @@ -1,12 +1,12 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' describe('Precompiles: ECADD', () => { it('ECADD', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const addressStr = '0000000000000000000000000000000000000006' diff --git a/packages/evm/test/precompiles/07-ecmul.spec.ts b/packages/evm/test/precompiles/07-ecmul.spec.ts index 4e4f088f5e..73d356e981 100644 --- a/packages/evm/test/precompiles/07-ecmul.spec.ts +++ b/packages/evm/test/precompiles/07-ecmul.spec.ts @@ -1,12 +1,12 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' describe('Precompiles: ECMUL', () => { it('ECMUL', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const ECMUL = getActivePrecompiles(common).get('0000000000000000000000000000000000000007')! diff --git a/packages/evm/test/precompiles/08-ecpairing.spec.ts b/packages/evm/test/precompiles/08-ecpairing.spec.ts index a5163d0d5f..d74c3b7e95 100644 --- a/packages/evm/test/precompiles/08-ecpairing.spec.ts +++ b/packages/evm/test/precompiles/08-ecpairing.spec.ts @@ -2,12 +2,12 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' describe('Precompiles: ECPAIRING', () => { it('ECPAIRING', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const addressStr = '0000000000000000000000000000000000000008' diff --git a/packages/evm/test/precompiles/09-blake2f.spec.ts b/packages/evm/test/precompiles/09-blake2f.spec.ts index e9a39c2edf..0f4e410b66 100644 --- a/packages/evm/test/precompiles/09-blake2f.spec.ts +++ b/packages/evm/test/precompiles/09-blake2f.spec.ts @@ -2,8 +2,9 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, beforeAll, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' +import type { EVM } from '../../src/index.js' import type { PrecompileFunc } from '../../src/precompiles/types.js' const validCases = [ @@ -85,7 +86,7 @@ describe('Precompiles: BLAKE2F', () => { // Test references: https://github.com/ethereum/go-ethereum/blob/e206d3f8975bd98cc86d14055dca40f996bacc60/core/vm/testdata/precompiles/blake2F.json // https://github.com/ethereum/go-ethereum/blob/e206d3f8975bd98cc86d14055dca40f996bacc60/core/vm/contracts_test.go#L73 - evm = await EVM.create({ + evm = await createEVM({ common, }) addressStr = '0000000000000000000000000000000000000009' diff --git a/packages/evm/test/precompiles/0a-pointevaluation.spec.ts b/packages/evm/test/precompiles/0a-pointevaluation.spec.ts index f9ab7c4825..67bfd4801f 100644 --- a/packages/evm/test/precompiles/0a-pointevaluation.spec.ts +++ b/packages/evm/test/precompiles/0a-pointevaluation.spec.ts @@ -9,7 +9,7 @@ import { import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' import type { PrecompileInput } from '../../src/index.js' @@ -29,7 +29,7 @@ describe('Precompiles: point evaluation', () => { customCrypto: { kzg }, }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) const addressStr = '000000000000000000000000000000000000000a' diff --git a/packages/evm/test/precompiles/eip-2537-bls.spec.ts b/packages/evm/test/precompiles/eip-2537-bls.spec.ts index b4d0c0c2f9..be698084e9 100644 --- a/packages/evm/test/precompiles/eip-2537-bls.spec.ts +++ b/packages/evm/test/precompiles/eip-2537-bls.spec.ts @@ -4,7 +4,7 @@ import { readFileSync, readdirSync } from 'fs' import * as mcl from 'mcl-wasm' import { assert, describe, it } from 'vitest' -import { EVM, MCLBLS, getActivePrecompiles } from '../../src/index.js' +import { MCLBLS, createEVM, getActivePrecompiles } from '../../src/index.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -52,7 +52,7 @@ for (const bls of [undefined, mclbls]) { describe(`Precompiles: ${fname}`, () => { for (const data of parsedJSON) { it(`${data.Name}`, async () => { - const evm = await EVM.create({ + const evm = await createEVM({ common, bls, }) @@ -104,7 +104,7 @@ for (let address = precompileAddressStart; address <= precompileAddressEnd; addr describe('EIP-2537 BLS precompile availability tests', () => { it('BLS precompiles should not be available if EIP not activated', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.MuirGlacier }) - const evm = await EVM.create({ + const evm = await createEVM({ common, }) diff --git a/packages/evm/test/precompiles/hardfork.spec.ts b/packages/evm/test/precompiles/hardfork.spec.ts index c617bf988c..1b46c97f94 100644 --- a/packages/evm/test/precompiles/hardfork.spec.ts +++ b/packages/evm/test/precompiles/hardfork.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM, getActivePrecompiles } from '../../src/index.js' +import { createEVM, getActivePrecompiles } from '../../src/index.js' describe('Precompiles: hardfork availability', () => { it('Test ECPAIRING availability', async () => { @@ -20,7 +20,7 @@ describe('Precompiles: hardfork availability', () => { assert.ok(true, 'ECPAIRING available in petersburg') } - let evm = await EVM.create({ + let evm = await createEVM({ common: commonByzantium, }) let result = await evm.runCall({ @@ -41,7 +41,7 @@ describe('Precompiles: hardfork availability', () => { assert.ok(true, 'ECPAIRING available in petersburg') } - evm = await EVM.create({ + evm = await createEVM({ common: commonPetersburg, }) result = await evm.runCall({ @@ -63,7 +63,7 @@ describe('Precompiles: hardfork availability', () => { assert.ok(true, 'ECPAIRING not available in homestead') } - evm = await EVM.create({ + evm = await createEVM({ common: commonHomestead, }) diff --git a/packages/evm/test/runCall.spec.ts b/packages/evm/test/runCall.spec.ts index ebdc7513b3..d42a63b5cb 100644 --- a/packages/evm/test/runCall.spec.ts +++ b/packages/evm/test/runCall.spec.ts @@ -17,7 +17,7 @@ import { assert, describe, it } from 'vitest' import * as genesisJSON from '../../client/test/testdata/geth-genesis/eip4844.json' import { defaultBlock } from '../src/evm.js' import { ERROR } from '../src/exceptions.js' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' import type { EVMRunCallOpts } from '../src/types.js' @@ -31,7 +31,7 @@ function create2address(sourceAddress: Address, codeHash: Uint8Array, salt: Uint describe('RunCall tests', () => { it('Create where FROM account nonce is 0', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const res = await evm.runCall({ to: undefined }) assert.equal( res.createdAddress?.toString(), @@ -54,7 +54,7 @@ describe('RunCall tests', () => { const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // contract address // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const code = '0x3460008080F560005260206000F3' /* code: remarks: (top of the stack is at the zero index) @@ -107,10 +107,10 @@ describe('RunCall tests', () => { const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) // caller address const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // contract address // setup the evm - const evmByzantium = await EVM.create({ + const evmByzantium = await createEVM({ common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }), }) - const evmConstantinople = await EVM.create({ + const evmConstantinople = await createEVM({ common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople }), }) const code = '0x600160011B00' @@ -151,7 +151,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const code = '0x61000260005561000160005500' /* idea: store the original value in the storage slot, except it is now a 1-length Uint8Array instead of a 32-length Uint8Array @@ -200,7 +200,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // push 1 push 0 sstore stop const code = '0x600160015500' @@ -225,7 +225,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Homestead }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // code to call 0x00..00dd, which does not exist const code = '0x6000600060006000600060DD61FFFF5A03F100' @@ -252,7 +252,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Homestead }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // code to call back into the calling account (0x00..00EE), // but using too much memory const code = '0x61FFFF60FF60006000600060EE6000F200' @@ -279,7 +279,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.TangerineWhistle }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // code to call 0x00..00fe, with the GAS opcode used as gas // this cannot be paid, since we also have to pay for CALL (40 gas) // this should thus go OOG @@ -307,7 +307,7 @@ describe('RunCall tests', () => { const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // code to call 0x00..00fe, with the GAS opcode used as gas // this cannot be paid, since we also have to pay for CALL (40 gas) // this should thus go OOG @@ -374,7 +374,7 @@ describe('RunCall tests', () => { const emptyBytes = hexToBytes('0x') // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const code = '0x60008080F060005500' /* This simple code tries to create an empty contract and then stores the address of the contract in the zero slot. @@ -426,7 +426,7 @@ describe('RunCall tests', () => { const caller = new Address(hexToBytes('0x1a02a619e51cc5f8a2a61d2a60f6c80476ee8ead')) // caller address // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const code = '0x3034526020600760203460045afa602034343e604034f3' const account = new Account() @@ -455,7 +455,7 @@ describe('RunCall tests', () => { it('Throws on negative call value', async () => { // setup the vm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // setup the call arguments const runCallArgs = { @@ -476,7 +476,7 @@ describe('RunCall tests', () => { it('runCall() -> skipBalance behavior', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // runCall against a contract to reach `_reduceSenderBalance` const contractCode = hexToBytes('0x00') // 00: STOP @@ -520,7 +520,7 @@ describe('RunCall tests', () => { const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) // caller address // setup the evm const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // setup the call arguments const runCallArgs = { @@ -545,7 +545,7 @@ describe('RunCall tests', () => { chain: 'custom', hardfork: Hardfork.Cancun, }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // setup the call arguments const runCallArgs: EVMRunCallOpts = { @@ -582,7 +582,7 @@ describe('RunCall tests', () => { chain: 'custom', hardfork: Hardfork.Cancun, }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const BLOBBASEFEE_OPCODE = 0x4a assert.equal( @@ -612,7 +612,7 @@ describe('RunCall tests', () => { it('step event: ensure EVM memory and not internal memory gets reported', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) const contractCode = hexToBytes('0x600060405200') // PUSH 0 PUSH 40 MSTORE STOP const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') @@ -637,7 +637,7 @@ describe('RunCall tests', () => { it('ensure code deposit errors are logged correctly (>= Homestead)', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // Create a contract which is too large const runCallArgs = { @@ -660,7 +660,7 @@ describe('RunCall tests', () => { it('ensure code deposit errors are logged correctly (Frontier)', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) // Create a contract which cannot pay the code deposit fee const runCallArgs = { @@ -684,7 +684,7 @@ describe('RunCall tests', () => { it('ensure call and callcode handle gas stipend correctly', async () => { // See: https://github.com/ethereumjs/ethereumjs-monorepo/issues/3194 const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) - const evm = await EVM.create({ common }) + const evm = await createEVM({ common }) for (const [opcode, gas, expectedOutput] of [ ['f1', 36600, '0x'], // 36600 is CALL fee diff --git a/packages/evm/test/runCode.spec.ts b/packages/evm/test/runCode.spec.ts index 791654dc1c..f49596a310 100644 --- a/packages/evm/test/runCode.spec.ts +++ b/packages/evm/test/runCode.spec.ts @@ -1,7 +1,7 @@ import { Account, Address, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' const PUSH1 = '60' const STOP = '00' @@ -21,7 +21,7 @@ const testCases = [ describe('VM.runCode: initial program counter', () => { it('should work', async () => { - const evm = await EVM.create() + const evm = await createEVM() for (const [i, testData] of testCases.entries()) { const runCodeArgs = { @@ -57,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 () => { - const evm = await EVM.create() + const evm = await createEVM() const INVALID_opcode = 'fe' const runCodeArgs = { @@ -76,7 +76,7 @@ describe('VM.runCode: interpreter', () => { }) it('should throw on non-EvmError', async () => { - const evm = await EVM.create() + const evm = await createEVM() // NOTE: due to now throwing on `getContractStorage` if account does not exist // this now means that if `runCode` is called and the address it runs on (default: zero address) // does not exist, then if SSTORE/SLOAD is used, the runCode will immediately fail because StateManager now throws @@ -105,7 +105,7 @@ describe('VM.runCode: interpreter', () => { describe('VM.runCode: RunCodeOptions', () => { it('should throw on negative value args', async () => { - const evm = await EVM.create() + const evm = await createEVM() const runCodeArgs = { value: BigInt(-10), diff --git a/packages/evm/test/stack.spec.ts b/packages/evm/test/stack.spec.ts index 1d6b79523d..4e0fe7e6f0 100644 --- a/packages/evm/test/stack.spec.ts +++ b/packages/evm/test/stack.spec.ts @@ -1,7 +1,7 @@ import { Account, Address, bigIntToBytes, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EVM } from '../src/index.js' +import { createEVM } from '../src/index.js' import { Stack } from '../src/stack.js' import { createAccount } from './utils.js' @@ -99,7 +99,7 @@ describe('Stack', () => { it('stack items should not change if they are DUPed', async () => { const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) const addr = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) - const evm = await EVM.create() + const evm = await createEVM() const account = createAccount(BigInt(0), BigInt(0)) const code = '0x60008080808060013382F15060005260206000F3' const expectedReturnValue = setLengthLeft(bigIntToBytes(BigInt(0)), 32) diff --git a/packages/statemanager/examples/evm.ts b/packages/statemanager/examples/evm.ts index e9f98df61a..bc804f6525 100644 --- a/packages/statemanager/examples/evm.ts +++ b/packages/statemanager/examples/evm.ts @@ -1,5 +1,5 @@ import { RPCStateManager, RPCBlockChain } from '@ethereumjs/statemanager' -import { EVM } from '@ethereumjs/evm' +import { createEVM, EVM } from '@ethereumjs/evm' const main = async () => { try { @@ -7,7 +7,7 @@ const main = async () => { const blockchain = new RPCBlockChain(provider) const blockTag = 1n const state = new RPCStateManager({ provider, blockTag }) - const evm = await EVM.create({ blockchain, stateManager: state }) // note that evm is ready to run BLOCKHASH opcodes (over RPC) + const evm = await createEVM({ blockchain, stateManager: state }) // note that evm is ready to run BLOCKHASH opcodes (over RPC) } catch (e) { console.log(e.message) // fetch would fail because provider url is not real. please replace provider with a valid rpc url string. } diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index 97b7105336..bd1061fd33 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromJsonRpcProvider, createBlockFromRPC } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { EVM, type EVMRunCallOpts } from '@ethereumjs/evm' +import { type EVMRunCallOpts, createEVM } from '@ethereumjs/evm' import { FeeMarketEIP1559Transaction, createTxFromRPC } from '@ethereumjs/tx' import { Account, @@ -318,7 +318,7 @@ describe('blockchain', () => const blockchain = new RPCBlockChain(provider) const blockTag = 1n const state = new RPCStateManager({ provider, blockTag }) - const evm = await EVM.create({ blockchain, stateManager: state }) + const evm = await createEVM({ blockchain, stateManager: state }) // Bytecode for returning the blockhash of the block previous to `blockTag` const code = '0x600143034060005260206000F3' const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index 6d30a9f101..c4d0cefa5a 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -1,6 +1,6 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common } from '@ethereumjs/common' -import { EVM, getActivePrecompiles } from '@ethereumjs/evm' +import { createEVM, getActivePrecompiles } from '@ethereumjs/evm' import { DefaultStateManager } from '@ethereumjs/statemanager' import { Account, Address, AsyncEventEmitter, unprefixedHexToBytes } from '@ethereumjs/util' @@ -121,7 +121,7 @@ export class VM { enableProfiler = true } const evmOpts = opts.evmOpts ?? {} - opts.evm = await EVM.create({ + opts.evm = await createEVM({ common: opts.common, stateManager: opts.stateManager, blockchain: opts.blockchain, @@ -250,7 +250,7 @@ export class VM { blockchain: this._opts.evmOpts?.blockchain?.shallowCopy() ?? blockchain, stateManager: this._opts.evmOpts?.stateManager?.shallowCopy(downlevelCaches) ?? stateManager, } - const evmCopy = await EVM.create(evmOpts) // TODO fixme (should copy the EVMInterface, not default EVM) + const evmCopy = await createEVM(evmOpts) // TODO fixme (should copy the EVMInterface, not default EVM) return VM.create({ stateManager, blockchain: this.blockchain, diff --git a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts index bbc4ea0dac..8e4213ada6 100644 --- a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork, createCustomCommon } from '@ethereumjs/common' -import { EVM } from '@ethereumjs/evm' +import { createEVM } from '@ethereumjs/evm' import { StatelessVerkleStateManager } from '@ethereumjs/statemanager' import { createTxFromSerializedData } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' @@ -37,7 +37,7 @@ describe('EIP 6800 tests', () => { it('successfully run transactions statelessly using the block witness', async () => { const verkleCrypto = await loadVerkleCrypto() const verkleStateManager = new StatelessVerkleStateManager({ common, verkleCrypto }) - const evm = await EVM.create({ common, stateManager: verkleStateManager }) + const evm = await createEVM({ common, stateManager: verkleStateManager }) const vm = await VM.create({ common, evm, diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index f83380be60..f35e792fe5 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork, createCustomCommon } from '@ethereumjs/common' -import { EVM } from '@ethereumjs/evm' +import { EVM, createEVM } from '@ethereumjs/evm' import { Account, Address, KECCAK256_RLP, hexToBytes } from '@ethereumjs/util' import * as util from 'util' // eslint-disable-line @typescript-eslint/no-unused-vars import { assert, describe, it } from 'vitest' @@ -60,7 +60,7 @@ describe('VM -> Default EVM / Custom EVM Opts', () => { it('should throw if evm and evmOpts are both used', async () => { try { - await VM.create({ evmOpts: {}, evm: await EVM.create() }) + await VM.create({ evmOpts: {}, evm: await createEVM() }) assert.fail('should throw') } catch (e: any) { assert.ok('correctly thrown') From 3bd1847c0900d765419a4ab3dd9a7774a52783d2 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Thu, 18 Jul 2024 10:37:30 +0200 Subject: [PATCH 08/58] Common/Monorepo: Remove NetworkId (#3513) * Remove networkId in Common * Killing off networkId in everything except client and devp2p * Fully remove from devp2p and client * docs: adjust readme * Update packages/client/bin/cli.ts Co-authored-by: Gabriel Rocheleau * Update packages/client/bin/cli.ts Co-authored-by: Scotty <66335769+ScottyPoi@users.noreply.github.com> --------- Co-authored-by: Gabriel Rocheleau Co-authored-by: Scotty <66335769+ScottyPoi@users.noreply.github.com> --- packages/block/test/testdata/testnetMerge.json | 1 - packages/blockchain/test/testdata/testnet.json | 1 - packages/client/bin/cli.ts | 13 +++++++++++-- packages/client/examples/private-geth-network.md | 2 +- packages/client/src/blockchain/chain.ts | 6 +++--- packages/client/src/net/protocol/ethprotocol.ts | 4 ++-- packages/client/src/net/protocol/lesprotocol.ts | 4 ++-- packages/client/src/rpc/modules/admin.ts | 2 +- packages/client/src/types.ts | 2 ++ packages/client/test/blockchain/chain.spec.ts | 2 +- packages/client/test/cli/cli.spec.ts | 7 +++---- .../client/test/net/protocol/ethprotocol.spec.ts | 8 ++++---- .../client/test/net/protocol/lesprotocol.spec.ts | 8 ++++---- packages/client/test/rpc/eth/getProof.spec.ts | 1 - packages/client/test/sim/beaconsync.spec.ts | 2 +- packages/client/test/sim/snapsync.spec.ts | 2 +- packages/client/test/testdata/common/testnet.json | 1 - packages/common/examples/genesisData/testnet.json | 1 - packages/common/examples/genesisData/testnet2.json | 1 - packages/common/src/chains.ts | 5 ----- packages/common/src/common.ts | 10 +--------- packages/common/src/constructors.ts | 6 ------ packages/common/src/types.ts | 1 - packages/common/src/utils.ts | 1 - packages/common/test/chains.spec.ts | 2 -- packages/common/test/customChains.spec.ts | 9 +++------ packages/common/test/customCrypto.spec.ts | 2 +- packages/common/test/data/merge/testnetMerge.json | 1 - packages/common/test/data/merge/testnetPOS.json | 1 - packages/common/test/data/testnet.json | 1 - packages/common/test/data/testnet2.json | 1 - packages/common/test/data/testnet3.json | 1 - packages/devp2p/src/protocol/eth.ts | 4 ++-- packages/devp2p/src/protocol/les.ts | 10 +++++----- packages/tx/examples/custom-chain-tx.ts | 4 +--- packages/tx/src/baseTransaction.ts | 1 - packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts | 2 +- packages/vm/test/api/index.spec.ts | 2 +- packages/vm/test/api/runBlock.spec.ts | 2 +- packages/vm/test/api/testdata/testnet.json | 1 - packages/vm/test/api/testdata/testnet2.json | 1 - packages/vm/test/api/testdata/testnetMerge.json | 1 - 42 files changed, 52 insertions(+), 85 deletions(-) diff --git a/packages/block/test/testdata/testnetMerge.json b/packages/block/test/testdata/testnetMerge.json index 995d7b1d2a..e6698fa6b3 100644 --- a/packages/block/test/testdata/testnetMerge.json +++ b/packages/block/test/testdata/testnetMerge.json @@ -1,7 +1,6 @@ { "name": "testnetMerge", "chainId": 55555, - "networkId": 55555, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/blockchain/test/testdata/testnet.json b/packages/blockchain/test/testdata/testnet.json index 177e9b5baa..3bf8733743 100644 --- a/packages/blockchain/test/testdata/testnet.json +++ b/packages/blockchain/test/testdata/testnet.json @@ -1,7 +1,6 @@ { "name": "mainnet", "chainId": 1, - "networkId": 1, "defaultHardfork": "london", "consensus": { "type": "pow", diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 6e692ca1e9..ee1eccb7be 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -85,8 +85,16 @@ const args: ClientOpts = yargs choices: networks.map((n) => n[1]).filter((el) => isNaN(parseInt(el))), default: 'mainnet', }) + .option('chainId', { + describe: 'Chain ID', + choices: networks.map((n) => parseInt(n[0])).filter((el) => !isNaN(el)), + default: undefined, + conflicts: ['customChain', 'customGenesisState', 'gethGenesis'], // Disallows custom chain data and chainId + }) .option('networkId', { describe: 'Network ID', + deprecated: true, + deprecate: 'use --chainId instead', choices: networks.map((n) => parseInt(n[0])).filter((el) => !isNaN(el)), default: undefined, conflicts: ['customChain', 'customGenesisState', 'gethGenesis'], // Disallows custom chain data and networkId @@ -922,8 +930,9 @@ async function run() { // TODO sharding: Just initialize kzg library now, in future it can be optimized to be // loaded and initialized on the sharding hardfork activation - // Give network id precedence over network name - const chain = args.networkId ?? args.network ?? Chain.Mainnet + // Give chainId priority over networkId + // Give networkId precedence over network name + const chain = args.chainId ?? args.networkId ?? args.network ?? Chain.Mainnet const cryptoFunctions: CustomCrypto = {} const kzg = await loadKZG() diff --git a/packages/client/examples/private-geth-network.md b/packages/client/examples/private-geth-network.md index ab20204888..53eb07a96f 100644 --- a/packages/client/examples/private-geth-network.md +++ b/packages/client/examples/private-geth-network.md @@ -14,7 +14,7 @@ Second, get geth configured to use the genesis parameters file just updated. Now, let's run geth and ensure that its sealing blocks. Note, geth will prompt you for a password to unlock your signer account. -`geth --datadir data --nat extip:[your local ip address here] --networkid 15470 --unlock [the signer account you created] --mine --nodiscover` +`geth --datadir data --nat extip:[your local ip address here] --chainId 15470 --unlock [the signer account you created] --mine --nodiscover` You should start seeing logs like below: diff --git a/packages/client/src/blockchain/chain.ts b/packages/client/src/blockchain/chain.ts index b2adafd7b7..63f03235dd 100644 --- a/packages/client/src/blockchain/chain.ts +++ b/packages/client/src/blockchain/chain.ts @@ -226,10 +226,10 @@ export class Chain { } /** - * Network ID + * Chain ID */ - get networkId(): bigint { - return this.config.chainCommon.networkId() + get chainId(): bigint { + return this.config.chainCommon.chainId() } /** diff --git a/packages/client/src/net/protocol/ethprotocol.ts b/packages/client/src/net/protocol/ethprotocol.ts index 2c9d0ac0d5..bc94fec3dc 100644 --- a/packages/client/src/net/protocol/ethprotocol.ts +++ b/packages/client/src/net/protocol/ethprotocol.ts @@ -404,7 +404,7 @@ export class EthProtocol extends Protocol { */ encodeStatus(): any { return { - networkId: bigIntToUnpaddedBytes(this.chain.networkId), + chainId: bigIntToUnpaddedBytes(this.chain.chainId), td: bigIntToUnpaddedBytes(this.chain.blocks.td), bestHash: this.chain.blocks.latest!.hash(), genesisHash: this.chain.genesis.hash(), @@ -418,7 +418,7 @@ export class EthProtocol extends Protocol { */ decodeStatus(status: any): any { return { - networkId: bytesToBigInt(status.networkId), + chainId: bytesToBigInt(status.chainId), td: bytesToBigInt(status.td), bestHash: status.bestHash, genesisHash: status.genesisHash, diff --git a/packages/client/src/net/protocol/lesprotocol.ts b/packages/client/src/net/protocol/lesprotocol.ts index 97f4400cb9..b64324b774 100644 --- a/packages/client/src/net/protocol/lesprotocol.ts +++ b/packages/client/src/net/protocol/lesprotocol.ts @@ -194,7 +194,7 @@ export class LesProtocol extends Protocol { const forkID = [hexToBytes(forkHash), bigIntToUnpaddedBytes(nextFork ?? 0n)] return { - networkId: bigIntToUnpaddedBytes(this.chain.networkId), + chainId: bigIntToUnpaddedBytes(this.chain.chainId), headTd: bigIntToUnpaddedBytes(this.chain.headers.td), headHash: this.chain.headers.latest?.hash(), headNum: bigIntToUnpaddedBytes(this.chain.headers.height), @@ -223,7 +223,7 @@ export class LesProtocol extends Protocol { } } return { - networkId: bytesToBigInt(status.networkId), + chainId: bytesToBigInt(status.chainId), headTd: bytesToBigInt(status.headTd), headHash: status.headHash, headNum: bytesToBigInt(status.headNum), diff --git a/packages/client/src/rpc/modules/admin.ts b/packages/client/src/rpc/modules/admin.ts index 2da9a3c846..49a5c31234 100644 --- a/packages/client/src/rpc/modules/admin.ts +++ b/packages/client/src/rpc/modules/admin.ts @@ -45,7 +45,7 @@ export class Admin { const difficulty = latestHeader.difficulty.toString() const genesis = bytesToHex(this._chain.genesis.hash()) const head = bytesToHex(latestHeader.mixHash) - const network = this._chain.networkId.toString() + const network = this._chain.chainId.toString() const nodeInfo = { name: clientName, diff --git a/packages/client/src/types.ts b/packages/client/src/types.ts index bbebaabb05..0098d534f8 100644 --- a/packages/client/src/types.ts +++ b/packages/client/src/types.ts @@ -98,6 +98,8 @@ export type DnsNetwork = string export interface ClientOpts { network?: string + chainId?: number + // Deprecated, use chainId instead networkId?: number sync?: SyncMode lightServe?: boolean diff --git a/packages/client/test/blockchain/chain.spec.ts b/packages/client/test/blockchain/chain.spec.ts index 981573a9ab..2f6f945ca4 100644 --- a/packages/client/test/blockchain/chain.spec.ts +++ b/packages/client/test/blockchain/chain.spec.ts @@ -33,7 +33,7 @@ describe('[Chain]', () => { it('should retrieve chain properties', async () => { const chain = await Chain.create({ config }) await chain.open() - assert.equal(chain.networkId, BigInt(1), 'get chain.networkId') + assert.equal(chain.chainId, BigInt(1), 'get chain.chainId') assert.equal(chain.blocks.td.toString(10), '17179869184', 'get chain.blocks.td') assert.equal(chain.blocks.height.toString(10), '0', 'get chain.blocks.height') assert.equal( diff --git a/packages/client/test/cli/cli.spec.ts b/packages/client/test/cli/cli.spec.ts index 2fc1987eda..cabf9ee261 100644 --- a/packages/client/test/cli/cli.spec.ts +++ b/packages/client/test/cli/cli.spec.ts @@ -31,7 +31,7 @@ export function clientRunHelper( describe('[CLI]', () => { // chain network tests it('should successfully start client with a custom network and network id', async () => { - const cliArgs = ['--network=sepolia', '--networkId=11155111'] + const cliArgs = ['--network=sepolia', '--chainId=11155111'] const onData = (message: string, child: ChildProcessWithoutNullStreams, resolve: Function) => { if (message.includes('Initializing Ethereumjs client')) { assert.ok( @@ -648,7 +648,6 @@ describe('[CLI]', () => { const customChainJson = `{ "name": "customChain", "chainId": 11155111, - "networkId": 11155111, "defaultHardfork": "shanghai", "consensus": { "type": "pow", @@ -782,13 +781,13 @@ describe('[CLI]', () => { await clientRunHelper(cliArgs, onData, true) }, 5000) it('should not start client with conflicting parameters', async () => { - const cliArgs = ['--networkId', '--gethGenesis'] + const cliArgs = ['--chainId', '--gethGenesis'] const onData = async ( message: string, child: ChildProcessWithoutNullStreams, resolve: Function ) => { - if (message.includes('Arguments networkId and gethGenesis are mutually exclusive')) { + if (message.includes('Arguments chainId and gethGenesis are mutually exclusive')) { assert.ok(true, 'correctly errors on conflicting arguments') } child.kill(15) diff --git a/packages/client/test/net/protocol/ethprotocol.spec.ts b/packages/client/test/net/protocol/ethprotocol.spec.ts index 930aa794d0..82c423e52e 100644 --- a/packages/client/test/net/protocol/ethprotocol.spec.ts +++ b/packages/client/test/net/protocol/ethprotocol.spec.ts @@ -32,7 +32,7 @@ describe('[EthProtocol]', () => { const config = new Config({ accountCache: 10000, storageCache: 1000 }) const chain = await Chain.create({ config }) const p = new EthProtocol({ config, chain }) - Object.defineProperty(chain, 'networkId', { + Object.defineProperty(chain, 'chainId', { get: () => { return BigInt(1) }, @@ -53,7 +53,7 @@ describe('[EthProtocol]', () => { assert.deepEqual( p.encodeStatus(), { - networkId: hexToBytes('0x01'), + chainId: hexToBytes('0x01'), td: hexToBytes('0x64'), bestHash: '0xaa', genesisHash: '0xbb', @@ -62,13 +62,13 @@ describe('[EthProtocol]', () => { 'encode status' ) const status = p.decodeStatus({ - networkId: [0x01], + chainId: [0x01], td: hexToBytes('0x64'), bestHash: '0xaa', genesisHash: '0xbb', }) assert.ok( - status.networkId === BigInt(1) && + status.chainId === BigInt(1) && status.td === BigInt(100) && status.bestHash === '0xaa' && status.genesisHash === '0xbb', diff --git a/packages/client/test/net/protocol/lesprotocol.spec.ts b/packages/client/test/net/protocol/lesprotocol.spec.ts index 7d9719cb5a..e147f4b5b7 100644 --- a/packages/client/test/net/protocol/lesprotocol.spec.ts +++ b/packages/client/test/net/protocol/lesprotocol.spec.ts @@ -33,7 +33,7 @@ describe('[LesProtocol]', () => { mrc: { GetBlockHeaders: { base: 10, req: 10 } }, }) const p = new LesProtocol({ config, chain, flow }) - Object.defineProperty(chain, 'networkId', { + Object.defineProperty(chain, 'chainId', { get: () => { return BigInt(1) }, @@ -65,7 +65,7 @@ describe('[LesProtocol]', () => { }) let status = p.encodeStatus() assert.ok( - bytesToHex(status.networkId) === '0x01' && + bytesToHex(status.chainId) === '0x01' && bytesToHex(status.headTd) === '0x64' && status.headHash === '0xaa' && bytesToHex(status.headNum) === '0x64' && @@ -84,10 +84,10 @@ describe('[LesProtocol]', () => { bytesToHex(status['flowControl/MRC'][0][2]) === '0x0a', 'encode status' ) - status = { ...status, networkId: [0x01] } + status = { ...status, chainId: [0x01] } status = p.decodeStatus(status) assert.ok( - status.networkId === BigInt(1) && + status.chainId === BigInt(1) && status.headTd === BigInt(100) && status.headHash === '0xaa' && status.headNum === BigInt(100) && diff --git a/packages/client/test/rpc/eth/getProof.spec.ts b/packages/client/test/rpc/eth/getProof.spec.ts index 0c298ba2b7..9169ae06ce 100644 --- a/packages/client/test/rpc/eth/getProof.spec.ts +++ b/packages/client/test/rpc/eth/getProof.spec.ts @@ -42,7 +42,6 @@ const expectedProof = { const testnetData = { name: 'testnet2', chainId: 12345, - networkId: 12345, defaultHardfork: 'istanbul', consensus: { type: 'pow', diff --git a/packages/client/test/sim/beaconsync.spec.ts b/packages/client/test/sim/beaconsync.spec.ts index cbc46eb1e4..7611183123 100644 --- a/packages/client/test/sim/beaconsync.spec.ts +++ b/packages/client/test/sim/beaconsync.spec.ts @@ -51,7 +51,7 @@ describe('simple mainnet test run', async () => { } // Better add it as a option in startnetwork - process.env.NETWORKID = `${common.networkId()}` + process.env.NETWORKID = `${common.chainId()}` const { teardownCallBack, result } = await startNetwork(network, client, { filterKeywords, filterOutWords, diff --git a/packages/client/test/sim/snapsync.spec.ts b/packages/client/test/sim/snapsync.spec.ts index 81ab062c2f..e8aded7d90 100644 --- a/packages/client/test/sim/snapsync.spec.ts +++ b/packages/client/test/sim/snapsync.spec.ts @@ -58,7 +58,7 @@ describe('simple mainnet test run', async () => { process.env.EXTRA_CL_PARAMS = '--params.CAPELLA_FORK_EPOCH 0' } // Better add it as a option in startnetwork - process.env.NETWORKID = `${common.networkId()}` + process.env.NETWORKID = `${common.chainId()}` const { teardownCallBack, result } = await startNetwork(network, client, { filterKeywords, filterOutWords, diff --git a/packages/client/test/testdata/common/testnet.json b/packages/client/test/testdata/common/testnet.json index 0c7531e072..88e4a72ab5 100644 --- a/packages/client/test/testdata/common/testnet.json +++ b/packages/client/test/testdata/common/testnet.json @@ -1,7 +1,6 @@ { "name": "testnet", "chainId": 12345, - "networkId": 12345, "defaultHardfork": "byzantium", "consensus": { "type": "pow", diff --git a/packages/common/examples/genesisData/testnet.json b/packages/common/examples/genesisData/testnet.json index 1b208d2140..bfb6fe4974 100644 --- a/packages/common/examples/genesisData/testnet.json +++ b/packages/common/examples/genesisData/testnet.json @@ -1,7 +1,6 @@ { "name": "testnet1", "chainId": 22222, - "networkId": 22222, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/common/examples/genesisData/testnet2.json b/packages/common/examples/genesisData/testnet2.json index 2215fde86c..5eec2f59ce 100644 --- a/packages/common/examples/genesisData/testnet2.json +++ b/packages/common/examples/genesisData/testnet2.json @@ -1,7 +1,6 @@ { "name": "testnet2", "chainId": 33333, - "networkId": 33333, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/common/src/chains.ts b/packages/common/src/chains.ts index 946ed17c08..0443442b81 100644 --- a/packages/common/src/chains.ts +++ b/packages/common/src/chains.ts @@ -8,7 +8,6 @@ export const chains: ChainsDict = { mainnet: { name: 'mainnet', chainId: 1, - networkId: 1, defaultHardfork: 'shanghai', consensus: { type: 'pow', @@ -162,7 +161,6 @@ export const chains: ChainsDict = { goerli: { name: 'goerli', chainId: 5, - networkId: 5, defaultHardfork: 'shanghai', consensus: { type: 'poa', @@ -324,7 +322,6 @@ export const chains: ChainsDict = { sepolia: { name: 'sepolia', chainId: 11155111, - networkId: 11155111, defaultHardfork: 'shanghai', consensus: { type: 'pow', @@ -459,7 +456,6 @@ export const chains: ChainsDict = { holesky: { name: 'holesky', chainId: 17000, - networkId: 17000, defaultHardfork: 'paris', consensus: { type: 'pos', @@ -578,7 +574,6 @@ export const chains: ChainsDict = { kaustinen6: { name: 'kaustinen6', chainId: 69420, - networkId: 69420, defaultHardfork: 'osaka', consensus: { type: 'pos', diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index ddba7ecb36..33a0750450 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -106,7 +106,7 @@ export class Common { 'Chain must be a string, number, or bigint when initialized with customChains passed in' ) } - const required = ['networkId', 'genesis', 'hardforks', 'bootstrapNodes'] + const required = ['chainId', 'genesis', 'hardforks', 'bootstrapNodes'] for (const param of required) { if (!(param in chain)) { throw new Error(`Missing required chain parameter: ${param}`) @@ -847,14 +847,6 @@ export class Common { return this._chainParams.name } - /** - * Returns the Id of current network - * @returns network Id - */ - networkId(): bigint { - return BigInt(this._chainParams.networkId) - } - /** * Returns the additionally activated EIPs * (by using the `eips` constructor option) diff --git a/packages/common/src/constructors.ts b/packages/common/src/constructors.ts index 4fbb87208d..5ee817a7b5 100644 --- a/packages/common/src/constructors.ts +++ b/packages/common/src/constructors.ts @@ -48,7 +48,6 @@ export function createCustomCommon( { name: CustomChain.PolygonMainnet, chainId: 137, - networkId: 137, }, opts ) @@ -58,7 +57,6 @@ export function createCustomCommon( { name: CustomChain.PolygonMumbai, chainId: 80001, - networkId: 80001, }, opts ) @@ -68,7 +66,6 @@ export function createCustomCommon( { name: CustomChain.ArbitrumOne, chainId: 42161, - networkId: 42161, }, opts ) @@ -78,7 +75,6 @@ export function createCustomCommon( { name: CustomChain.xDaiChain, chainId: 100, - networkId: 100, }, opts ) @@ -89,7 +85,6 @@ export function createCustomCommon( { name: CustomChain.OptimisticKovan, chainId: 69, - networkId: 69, }, opts ) @@ -100,7 +95,6 @@ export function createCustomCommon( { name: CustomChain.OptimisticEthereum, chainId: 10, - networkId: 10, }, // Optimism has not implemented the London hardfork yet (targeting Q1.22) { hardfork: Hardfork.Berlin, ...opts } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index a17d6b3d98..88c28f96d2 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -28,7 +28,6 @@ type ConsensusConfig = { export interface ChainConfig { name: string chainId: number | bigint - networkId: number | bigint defaultHardfork?: string comment?: string url?: string diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index 91b6db3931..975a256c02 100644 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -88,7 +88,6 @@ function parseGethParams(json: any, mergeForkIdPostMerge: boolean = true) { const params = { name, chainId, - networkId: chainId, depositContractAddress, genesis: { timestamp, diff --git a/packages/common/test/chains.spec.ts b/packages/common/test/chains.spec.ts index 3a2da8caea..e0d25554b7 100644 --- a/packages/common/test/chains.spec.ts +++ b/packages/common/test/chains.spec.ts @@ -14,7 +14,6 @@ describe('[Common/Chains]: Initialization / Chain params', () => { let c = new Common({ chain: 'mainnet' }) assert.equal(c.chainName(), 'mainnet', 'should initialize with chain name') assert.equal(c.chainId(), BigInt(1), 'should return correct chain Id') - assert.equal(c.networkId(), BigInt(1), 'should return correct network Id') assert.equal(c.hardfork(), Hardfork.Shanghai, 'should set hardfork to current default hardfork') assert.equal( c.hardfork(), @@ -30,7 +29,6 @@ describe('[Common/Chains]: Initialization / Chain params', () => { const c = new Common({ chain: Chain.Mainnet }) assert.equal(c.chainName(), 'mainnet', 'should initialize with chain name') assert.equal(c.chainId(), BigInt(1), 'should return correct chain Id') - assert.equal(c.networkId(), BigInt(1), 'should return correct network Id') assert.equal(c.hardfork(), Hardfork.Shanghai, 'should set hardfork to current default hardfork') assert.equal( c.hardfork(), diff --git a/packages/common/test/customChains.spec.ts b/packages/common/test/customChains.spec.ts index 5efa8a83aa..71bdd0d9ae 100644 --- a/packages/common/test/customChains.spec.ts +++ b/packages/common/test/customChains.spec.ts @@ -21,7 +21,6 @@ describe('[Common]: Custom chains', () => { const c = new Common({ chain: testnet, hardfork: Hardfork.Byzantium }) assert.equal(c.chainName(), 'testnet', 'should initialize with chain name') assert.equal(c.chainId(), BigInt(12345), 'should return correct chain Id') - assert.equal(c.networkId(), BigInt(12345), 'should return correct network Id') assert.equal(c.hardforks()[3]['block'], 3, 'should return correct hardfork data') assert.equal(c.bootstrapNodes()[1].ip, '10.0.0.2', 'should return a bootstrap node array') }) @@ -42,7 +41,7 @@ describe('[Common]: Custom chains', () => { it('custom() -> base functionality', () => { const mainnetCommon = new Common({ chain: Chain.Mainnet }) - const customChainParams = { name: 'custom', chainId: 123, networkId: 678 } + const customChainParams = { name: 'custom', chainId: 123 } const customChainCommon = createCustomCommon(customChainParams, { hardfork: Hardfork.Byzantium, }) @@ -50,7 +49,6 @@ describe('[Common]: Custom chains', () => { // From custom chain params assert.equal(customChainCommon.chainName(), customChainParams.name) assert.equal(customChainCommon.chainId(), BigInt(customChainParams.chainId)) - assert.equal(customChainCommon.networkId(), BigInt(customChainParams.networkId)) // Fallback params from mainnet assert.equal(customChainCommon.genesis(), mainnetCommon.genesis()) @@ -63,12 +61,12 @@ describe('[Common]: Custom chains', () => { it('custom() -> behavior', () => { let common = createCustomCommon({ chainId: 123 }) - assert.deepEqual(common.networkId(), BigInt(1), 'should default to mainnet base chain') + assert.equal(common.consensusAlgorithm(), 'casper', 'should default to mainnet base chain') assert.equal(common.chainName(), 'custom-chain', 'should set default custom chain name') common = createCustomCommon(CustomChain.PolygonMumbai) assert.deepEqual( - common.networkId(), + common.chainId(), BigInt(80001), 'supported chain -> should initialize with correct chain ID' ) @@ -158,7 +156,6 @@ describe('[Common]: Custom chains', () => { const customChainParams: Partial = { name: 'custom', chainId: 123, - networkId: 678, depositContractAddress: '0x4242424242424242424242424242424242424242', } const customChainCommon = createCustomCommon(customChainParams, { diff --git a/packages/common/test/customCrypto.spec.ts b/packages/common/test/customCrypto.spec.ts index 0783026c84..7e5ae55f40 100644 --- a/packages/common/test/customCrypto.spec.ts +++ b/packages/common/test/customCrypto.spec.ts @@ -41,7 +41,7 @@ describe('[Common]: Custom Crypto', () => { msg = 'Should still work on a copied instance' assert.deepEqual(c.copy().customCrypto.keccak256!(value), new Uint8Array([2, 1]), msg) - const customChainParams = { name: 'custom', chainId: 123, networkId: 678 } + const customChainParams = { name: 'custom', chainId: 123 } c = createCustomCommon(customChainParams, { customCrypto }) msg = 'Should initialize with custom keccak256 function and use properly (custom() constructor)' assert.deepEqual(c.customCrypto.keccak256!(value), new Uint8Array([2, 1]), msg) diff --git a/packages/common/test/data/merge/testnetMerge.json b/packages/common/test/data/merge/testnetMerge.json index 995d7b1d2a..e6698fa6b3 100644 --- a/packages/common/test/data/merge/testnetMerge.json +++ b/packages/common/test/data/merge/testnetMerge.json @@ -1,7 +1,6 @@ { "name": "testnetMerge", "chainId": 55555, - "networkId": 55555, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/common/test/data/merge/testnetPOS.json b/packages/common/test/data/merge/testnetPOS.json index 549193be0b..325c973033 100644 --- a/packages/common/test/data/merge/testnetPOS.json +++ b/packages/common/test/data/merge/testnetPOS.json @@ -1,7 +1,6 @@ { "name": "testnetPOS", "chainId": 66666, - "networkId": 66666, "defaultHardfork": "chainstart", "consensus": { "type": "pos", diff --git a/packages/common/test/data/testnet.json b/packages/common/test/data/testnet.json index 0c7531e072..88e4a72ab5 100644 --- a/packages/common/test/data/testnet.json +++ b/packages/common/test/data/testnet.json @@ -1,7 +1,6 @@ { "name": "testnet", "chainId": 12345, - "networkId": 12345, "defaultHardfork": "byzantium", "consensus": { "type": "pow", diff --git a/packages/common/test/data/testnet2.json b/packages/common/test/data/testnet2.json index ddbb57107a..a76bc09f7c 100644 --- a/packages/common/test/data/testnet2.json +++ b/packages/common/test/data/testnet2.json @@ -1,7 +1,6 @@ { "name": "testnet2", "chainId": 22222, - "networkId": 22222, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/common/test/data/testnet3.json b/packages/common/test/data/testnet3.json index c8b59ac9f2..7a10962950 100644 --- a/packages/common/test/data/testnet3.json +++ b/packages/common/test/data/testnet3.json @@ -1,7 +1,6 @@ { "name": "testnet3", "chainId": 33333, - "networkId": 33333, "defaultHardfork": "istanbul", "consensus": { "type": "poa", diff --git a/packages/devp2p/src/protocol/eth.ts b/packages/devp2p/src/protocol/eth.ts index 4e4a6deeb1..c2dd7e0c92 100644 --- a/packages/devp2p/src/protocol/eth.ts +++ b/packages/devp2p/src/protocol/eth.ts @@ -203,13 +203,13 @@ export class ETH extends Protocol { ) const status: { - networkId: Uint8Array | Uint8Array[] + chainId: Uint8Array | Uint8Array[] td: Uint8Array bestHash: Uint8Array genesisHash: Uint8Array forkId?: Uint8Array | Uint8Array[] } = { - networkId: this._peerStatus[1], + chainId: this._peerStatus[1], td: this._peerStatus[2] as Uint8Array, bestHash: this._peerStatus[3] as Uint8Array, genesisHash: this._peerStatus[4] as Uint8Array, diff --git a/packages/devp2p/src/protocol/les.ts b/packages/devp2p/src/protocol/les.ts index 357c8d5c6d..a0950a7f17 100644 --- a/packages/devp2p/src/protocol/les.ts +++ b/packages/devp2p/src/protocol/les.ts @@ -127,8 +127,8 @@ export class LES extends Protocol { 'STATUS' ) assertEq( - this._status['networkId'], - this._peerStatus['networkId'], + this._status['chainId'], + this._peerStatus['chainId'], 'NetworkId mismatch', this.debug.bind(this), 'STATUS' @@ -153,7 +153,7 @@ export class LES extends Protocol { _getStatusString(status: LES.Status) { let sStr = `[V:${bytesToInt(status['protocolVersion'])}, ` - sStr += `NID:${bytesToInt(status['networkId'] as Uint8Array)}, HTD:${bytesToInt( + sStr += `NID:${bytesToInt(status['chainId'] as Uint8Array)}, HTD:${bytesToInt( status['headTd'] )}, ` sStr += `HeadH:${bytesToHex(status['headHash'])}, HeadN:${bytesToInt(status['headNum'])}, ` @@ -184,7 +184,7 @@ export class LES extends Protocol { status['announceType'] = intToBytes(DEFAULT_ANNOUNCE_TYPE) } status['protocolVersion'] = intToBytes(this._version) - status['networkId'] = bigIntToBytes(this._peer.common.chainId()) + status['chainId'] = bigIntToBytes(this._peer.common.chainId()) this._status = status @@ -284,7 +284,7 @@ export namespace LES { export interface Status { [key: string]: any protocolVersion: Uint8Array - networkId: Uint8Array + chainId: Uint8Array headTd: Uint8Array headHash: Uint8Array headNum: Uint8Array diff --git a/packages/tx/examples/custom-chain-tx.ts b/packages/tx/examples/custom-chain-tx.ts index b4f4c64a7c..8378dccf3a 100644 --- a/packages/tx/examples/custom-chain-tx.ts +++ b/packages/tx/examples/custom-chain-tx.ts @@ -6,12 +6,10 @@ import { hexToBytes } from '@ethereumjs/util' // In this example we create a transaction for a custom network. // This custom network has the same params as mainnet, -// except for name, chainId, and networkId, -// so we use the `Common.custom` method. +// except for name, chainId, so we use the `Common.custom` method. const customCommon = createCustomCommon( { name: 'my-network', - networkId: 123, chainId: 2134, }, { diff --git a/packages/tx/src/baseTransaction.ts b/packages/tx/src/baseTransaction.ts index 9f8c70f80d..2597dfa885 100644 --- a/packages/tx/src/baseTransaction.ts +++ b/packages/tx/src/baseTransaction.ts @@ -398,7 +398,6 @@ export abstract class BaseTransaction return createCustomCommon( { name: 'custom-chain', - networkId: chainIdBigInt, chainId: chainIdBigInt, }, { baseChain: this.DEFAULT_CHAIN } diff --git a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts index 8e4213ada6..86792cce4a 100644 --- a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts @@ -13,7 +13,7 @@ import { VM } from '../../../src' import type { BlockData } from '@ethereumjs/block' import type { PrefixedHexString } from '@ethereumjs/util' -const customChainParams = { name: 'custom', chainId: 69420, networkId: 678 } +const customChainParams = { name: 'custom', chainId: 69420 } const common = createCustomCommon(customChainParams, { hardfork: Hardfork.Cancun, eips: [2935, 4895, 6800], diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index f35e792fe5..7d824395cf 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -182,7 +182,7 @@ describe('VM -> common (chain, HFs, EIPs)', () => { }) it('should accept a custom chain config (createCustomCommon() static constructor)', async () => { - const customChainParams = { name: 'custom', chainId: 123, networkId: 678 } + const customChainParams = { name: 'custom', chainId: 123 } const common = createCustomCommon(customChainParams, { baseChain: 'mainnet', hardfork: 'byzantium', diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 78702db2ce..27b76b0a0a 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -139,7 +139,7 @@ describe('runBlock() -> successful API parameter usage', async () => { }) it('PoW block, Common custom chain (createCustomCommon() static constructor)', async () => { - const customChainParams = { name: 'custom', chainId: 123, networkId: 678 } + const customChainParams = { name: 'custom', chainId: 123 } const common = createCustomCommon(customChainParams, { baseChain: 'mainnet', hardfork: 'berlin', diff --git a/packages/vm/test/api/testdata/testnet.json b/packages/vm/test/api/testdata/testnet.json index b270831712..c503a09d32 100644 --- a/packages/vm/test/api/testdata/testnet.json +++ b/packages/vm/test/api/testdata/testnet.json @@ -1,7 +1,6 @@ { "name": "testnet", "chainId": 12345, - "networkId": 12345, "defaultHardfork": "byzantium", "consensus": { "type": "pow", diff --git a/packages/vm/test/api/testdata/testnet2.json b/packages/vm/test/api/testdata/testnet2.json index bbef65a16d..6d8db16448 100644 --- a/packages/vm/test/api/testdata/testnet2.json +++ b/packages/vm/test/api/testdata/testnet2.json @@ -1,7 +1,6 @@ { "name": "testnet2", "chainId": 22222, - "networkId": 22222, "defaultHardfork": "istanbul", "consensus": { "type": "pos", diff --git a/packages/vm/test/api/testdata/testnetMerge.json b/packages/vm/test/api/testdata/testnetMerge.json index 995d7b1d2a..e6698fa6b3 100644 --- a/packages/vm/test/api/testdata/testnetMerge.json +++ b/packages/vm/test/api/testdata/testnetMerge.json @@ -1,7 +1,6 @@ { "name": "testnetMerge", "chainId": 55555, - "networkId": 55555, "defaultHardfork": "istanbul", "consensus": { "type": "poa", From 34ab100dff0fa472a080c0c4b444a4df05e00786 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Thu, 18 Jul 2024 11:30:13 +0200 Subject: [PATCH 09/58] Implement Mega EOF (#3440) * common: add EOF EIPs * evm: implement eip3540 * evm: eof fixes * evm: add eip3540 tests * evm/common: add EOF meta eip * evm: setup eof in msg/env * evm: add placeholders for eof opcodes * evm: add explicit eof flag for authcall * evm: rename eof msg type * evm: setup to run EOF * evm: add eip4200 * evm: refactor eof * evm: add stack deltas * evm: add stackDelta * evm: make verify use stackDelta * evm: add eoftests * evm: eip4200 validation * evm: add general eof container validation tests * evm: all header validator tests * evm: eip5450 tests * evm: add reachable code/opcodes verification eof * evm: add dataloadn check eof * evm: add error [no ci] * evm: add various eof stack checks [no ci] * evm: implement callf/retf [no ci] * evm: implement dataload* * evm: implement swap/dup/exchange * evm: add stack.exchange * evm: add extcall*opcodes EOF * common: add eof to prague * evm: fix dupn * evm: mark non-async opcodes as non async * evm: fix exchange * evm: fix swap * evm: fix rjumpv * evm: partially fix callf * evm: fix eof opcode error handling * evm: add jumpf [no ci] * evm: implement extcall * evm: add extdelegatecall / extstaticcall * evm: fix datacopy opcode [no ci] * evm: add returndataload * evm: add dataload gas * evm: fix returndatacopy for eof contracts [no ci] * evm: extdelegatecall cannot call legacy contracts [no ci] * evm: add eof rules for legacy contracts [no ci] * evm: clear return data buffer on ext*call data exotic cases * evm: partial eofcreate implementation * evm: add returncontract [no ci] * evm: fix eofcreate with no auxdata [no ci] * evm: first attempt to fix auxdata returncontract [no ci] * evm: fix auxdata length write and return value on error * evm: add initcontainer mode to eof container * evm: fix eofcreate gas calculation [no ci] * evm: charge correct ext*call gas * evm: add comment * evm: add container mode * evm: add support for txn eof creations * evm: fix return contract tests for EOF * evm: fix stackDelta RETURNCONTRACT for header validation * eof: fix reachable code validation if rjump at end of code * evm: eof container validation add support eofcreate / returncontract * evm: correct eofcreate / returncontract to only have 1 byte immediate in validate * evm: more header validation * evm: eof verify dupn exchange * evm: add container size max * evm: verify rjumpv into self * evm: update max container sections * evm: fix max header size constant * evm: implement EIP 5450 stack validation algorithm * evm: fix RETURNCONTRACT stack delta * evm: updat eeof header validation for "initcode" containers * evm: fix eof dir * evm: delete old eof container tests * evm: remove more old tests * evm: remove old eof test * evm: remove old eof test * evm: fix EXCHANGE * evm: ensure eof put right value on stack on ext*call revert * evm: ensure extcall argument order correct * evm: EXPERIMENTAL - eof initcode container validation on tx init * evm: ensure eof header parsing for init txs also fails * evm: container: allow lower data sizes for deployment containers * evm: fix callf/jumpf stack overflow check * evm: implement swapn stack check for eof validation * evm: create stack delta generator script * vm: remove outdated VM EOF API test * vm: remove other outdated test * evm: move and fix header tester to scripts dir * fix evm header validation test name * fix hardfork: change to prague without EOF * evm: lint * common: fix build * evm/eof: add comments * eof: cleanup errors * eof: add comment * fix typo * update eof-header-validation.ts such that it works * Fixes --------- Co-authored-by: Holger Drewes --- packages/blockchain/src/constructors.ts | 2 +- packages/common/src/eips.ts | 140 ++++- packages/common/src/hardforks.ts | 4 +- packages/evm/scripts/stackDeltaGenerator.ts | 302 ++++++++++ packages/evm/src/eof.ts | 105 ---- packages/evm/src/eof/constants.ts | 36 ++ packages/evm/src/eof/container.ts | 461 +++++++++++++++ packages/evm/src/eof/errors.ts | 254 +++++++++ packages/evm/src/eof/setup.ts | 27 + packages/evm/src/eof/stackDelta.ts | 168 ++++++ packages/evm/src/eof/util.ts | 16 + packages/evm/src/eof/verify.ts | 519 +++++++++++++++++ packages/evm/src/evm.ts | 68 +-- packages/evm/src/exceptions.ts | 2 +- packages/evm/src/index.ts | 2 - packages/evm/src/interpreter.ts | 105 +++- packages/evm/src/message.ts | 7 +- packages/evm/src/opcodes/codes.ts | 54 ++ packages/evm/src/opcodes/functions.ts | 528 +++++++++++++++++- packages/evm/src/opcodes/gas.ts | 257 ++++++++- packages/evm/src/stack.ts | 20 + packages/evm/src/types.ts | 9 + packages/evm/test/eips/eip-4200.spec.ts | 40 ++ packages/evm/test/eips/eip-5450.spec.ts | 39 ++ .../evm/test/eips/eof-header-validation.ts | 93 +++ packages/evm/test/eips/eof-runner.spec.ts | 41 ++ packages/evm/test/eips/eof-utils.ts | 9 + packages/evm/test/eof.spec.ts | 35 -- .../EIPs/eip-3540-evm-object-format.spec.ts | 235 -------- .../EIPs/eip-3670-eof-code-validation.spec.ts | 163 ------ .../vm/test/retesteth/transition-child.cts | 8 +- 31 files changed, 3112 insertions(+), 637 deletions(-) create mode 100644 packages/evm/scripts/stackDeltaGenerator.ts delete mode 100644 packages/evm/src/eof.ts create mode 100644 packages/evm/src/eof/constants.ts create mode 100644 packages/evm/src/eof/container.ts create mode 100644 packages/evm/src/eof/errors.ts create mode 100644 packages/evm/src/eof/setup.ts create mode 100644 packages/evm/src/eof/stackDelta.ts create mode 100644 packages/evm/src/eof/util.ts create mode 100644 packages/evm/src/eof/verify.ts create mode 100644 packages/evm/test/eips/eip-4200.spec.ts create mode 100644 packages/evm/test/eips/eip-5450.spec.ts create mode 100644 packages/evm/test/eips/eof-header-validation.ts create mode 100644 packages/evm/test/eips/eof-runner.spec.ts create mode 100644 packages/evm/test/eips/eof-utils.ts delete mode 100644 packages/evm/test/eof.spec.ts delete mode 100644 packages/vm/test/api/EIPs/eip-3540-evm-object-format.spec.ts delete mode 100644 packages/vm/test/api/EIPs/eip-3670-eof-code-validation.spec.ts diff --git a/packages/blockchain/src/constructors.ts b/packages/blockchain/src/constructors.ts index f48b9354eb..75c3cc2925 100644 --- a/packages/blockchain/src/constructors.ts +++ b/packages/blockchain/src/constructors.ts @@ -91,7 +91,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { /** * Creates a blockchain from a list of block objects, - * objects must be readable by {@link Block.fromBlockData} + * objects must be readable by {@link createBlockFromBlockData} * * @param blockData List of block objects * @param opts Constructor options, see {@link BlockchainOptions} diff --git a/packages/common/src/eips.ts b/packages/common/src/eips.ts index 81a645c1f5..e2d7900be2 100644 --- a/packages/common/src/eips.ts +++ b/packages/common/src/eips.ts @@ -7,6 +7,20 @@ type EIPsDict = { } export const EIPs: EIPsDict = { + /** + * Description : SWAPN, DUPN and EXCHANGE instructions + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-663.md + * Status : Review + */ + 663: { + minimumHardfork: Hardfork.Chainstart, + requiredEIPs: [3540, 5450], + gasPrices: { + dupn: 3, // Base fee of the DUPN opcode + swapn: 3, // Base fee of the SWAPN opcode + exchange: 3, // Base fee of the EXCHANGE opcode + }, + }, /** * Description : Transient storage opcodes * URL : https://eips.ethereum.org/EIPS/eip-1153 @@ -176,12 +190,12 @@ export const EIPs: EIPsDict = { }, /** * Description : EVM Object Format (EOF) v1 - * URL : https://eips.ethereum.org/EIPS/eip-3540 + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-3540.md * Status : Review */ 3540: { minimumHardfork: Hardfork.London, - requiredEIPs: [3541], + requiredEIPs: [3541, 3860], }, /** * Description : Reject new contracts starting with the 0xEF byte @@ -224,7 +238,7 @@ export const EIPs: EIPsDict = { }, /** * Description : EOF - Code Validation - * URL : https://eips.ethereum.org/EIPS/eip-3670 + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-3670.md * Status : Review */ 3670: { @@ -267,6 +281,20 @@ export const EIPs: EIPsDict = { maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract }, }, + /** + * Description : EOF - Static relative jumps + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-4200.md + * Status : Review + */ + 4200: { + minimumHardfork: Hardfork.London, + requiredEIPs: [3540, 3670], + gasPrices: { + rjump: 2, // Base fee of the RJUMP opcode + rjumpi: 4, // Base fee of the RJUMPI opcode + rjumpv: 4, // Base fee of the RJUMPV opcode + }, + }, /** * Description : Difficulty Bomb Delay to June 2022 * URL : https://eips.ethereum.org/EIPS/eip-4345 @@ -291,6 +319,19 @@ export const EIPs: EIPsDict = { prevrandao: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) }, }, + /** + * Description : EOF - Functions + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-4750.md + * Status : Review + */ + 4750: { + minimumHardfork: Hardfork.London, + requiredEIPs: [3540, 3670, 5450], + gasPrices: { + callf: 5, // Base fee of the CALLF opcode + retf: 3, // Base fee of the RETF opcode + }, + }, /** * Description : Beacon block root in the EVM * URL : https://eips.ethereum.org/EIPS/eip-4788 @@ -350,6 +391,15 @@ export const EIPs: EIPsDict = { difficultyBombDelay: 11400000, // the amount of blocks to delay the difficulty bomb with }, }, + /** + * Description : EOF - Stack Validation + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-5450.md + * Status : Review + */ + 5450: { + minimumHardfork: Hardfork.London, + requiredEIPs: [3540, 3670, 4200, 4750], + }, /** * Description : MCOPY - Memory copying instruction * URL : https://eips.ethereum.org/EIPS/eip-5656 @@ -371,6 +421,18 @@ export const EIPs: EIPsDict = { minimumHardfork: Hardfork.Cancun, requiredEIPs: [7685], }, + /** + * Description : EOF - JUMPF and non-returning functions + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-6206.md + * Status : Review + */ + 6206: { + minimumHardfork: Hardfork.London, + requiredEIPs: [4750, 5450], + gasPrices: { + jumpf: 5, // Base fee of the JUMPF opcode + }, + }, /** * Description : SELFDESTRUCT only in same transaction * URL : https://eips.ethereum.org/EIPS/eip-6780 @@ -421,6 +483,28 @@ export const EIPs: EIPsDict = { withdrawalRequestPredeployAddress: BigInt('0x00A3ca265EBcb825B45F985A16CEFB49958cE017'), // Address of the validator excess address }, }, + /** + * Description : Revamped CALL instructions + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-7069.md + * Status : Review + */ + 7069: { + minimumHardfork: Hardfork.Berlin, + /* Note: per EIP these are the additionally required EIPs: + EIP 150 - This is the entire Tangerine Whistle hardfork + EIP 211 - (RETURNDATASIZE / RETURNDATACOPY) - Included in Byzantium + EIP 214 - (STATICCALL) - Included in Byzantium + */ + requiredEIPs: [2929], + gasPrices: { + extcall: 0, // Base fee of the EXTCALL opcode + extdelegatecall: 0, // Base fee of the EXTDELEGATECALL opcode + extstaticcall: 0, // Base fee of the EXTSTATICCALL opcode + returndataload: 3, // Base fee of the RETURNDATALOAD opcode + minRetainedGas: 5000, // Minimum gas retained prior to executing an EXT*CALL opcode (this is the minimum gas available after performing the EXT*CALL) + minCalleeGas: 2300, //Minimum gas available to the the address called by an EXT*CALL opcode + }, + }, /** * Description : Increase the MAX_EFFECTIVE_BALANCE -> Execution layer triggered consolidations (experimental) * URL : https://eips.ethereum.org/EIPS/eip-7251 @@ -435,6 +519,21 @@ export const EIPs: EIPsDict = { consolidationRequestPredeployAddress: BigInt('0x00b42dbF2194e931E80326D950320f7d9Dbeac02'), // Address of the consolidations contract }, }, + /** + * Description : EOF - Data section access instructions + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-7480.md + * Status : Review + */ + 7480: { + minimumHardfork: Hardfork.London, + requiredEIPs: [3540, 3670], + gasPrices: { + dataload: 4, // Base fee of the DATALOAD opcode + dataloadn: 3, // Base fee of the DATALOADN opcode + datasize: 2, // Base fee of the DATASIZE opcode + datacopy: 3, // Base fee of the DATACOPY opcode + }, + }, /** * Description : BLOBBASEFEE opcode * URL : https://eips.ethereum.org/EIPS/eip-7516 @@ -447,6 +546,22 @@ export const EIPs: EIPsDict = { blobbasefee: 2, // Gas cost of the BLOBBASEFEE opcode }, }, + /** + * Description : EOF Contract Creation + * URL : https://github.com/ethereum/EIPs/blob/dd32a34cfe4473bce143641bfffe4fd67e1987ab/EIPS/eip-7620.md + * Status : Review + */ + 7620: { + minimumHardfork: Hardfork.London, + /* Note: per EIP these are the additionally required EIPs: + EIP 170 - (Max contract size) - Included in Spurious Dragon + */ + requiredEIPs: [3540, 3541, 3670], + gasPrices: { + eofcreate: 32000, // Base fee of the EOFCREATE opcode (Same as CREATE/CREATE2) + returncontract: 0, // Base fee of the RETURNCONTRACT opcode + }, + }, /** * Description : General purpose execution layer requests * URL : https://eips.ethereum.org/EIPS/eip-7685 @@ -458,6 +573,25 @@ export const EIPs: EIPsDict = { requiredEIPs: [3675], gasPrices: {}, }, + /** + * Description : EVM Object Format (EOFv1) Meta + * URL : https://github.com/ethereum/EIPs/blob/4153e95befd0264082de3c4c2fe3a85cc74d3152/EIPS/eip-7692.md + * Status : Draft + */ + 7692: { + minimumHardfork: Hardfork.Cancun, + requiredEIPs: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7698], + gasPrices: {}, + }, + /** + * Description : EOF - Creation transaction + * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-7698.md + * Status : Draft + */ + 7698: { + minimumHardfork: Hardfork.London, + requiredEIPs: [3540, 7620], + }, /** * Description : Set EOA account code for one transaction * URL : https://github.com/ethereum/EIPs/blob/62419ca3f45375db00b04a368ea37c0bfb05386a/EIPS/eip-7702.md diff --git a/packages/common/src/hardforks.ts b/packages/common/src/hardforks.ts index f10edd52aa..79935595cc 100644 --- a/packages/common/src/hardforks.ts +++ b/packages/common/src/hardforks.ts @@ -366,7 +366,9 @@ export const hardforks: HardforksDict = { */ prague: { name: 'prague', - eips: [2537, 2935, 6110, 7002, 7251, 7685, 7702], + // TODO update this accordingly to the right devnet setup + //eips: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7692, 7698], // This is EOF-only + eips: [2537, 2935, 6110, 7002, 7251, 7685, 7702], // This is current prague without EOF }, /** * Description: Next feature hardfork after prague, internally used for verkle testing/implementation (incomplete/experimental) diff --git a/packages/evm/scripts/stackDeltaGenerator.ts b/packages/evm/scripts/stackDeltaGenerator.ts new file mode 100644 index 0000000000..d0914c8ee6 --- /dev/null +++ b/packages/evm/scripts/stackDeltaGenerator.ts @@ -0,0 +1,302 @@ +const stackDelta: any = {} + +class OpcodeInfo { + static terminalOpcode( + instr: string, + opcode: number, + inputs: number, + outputs: number, + opSize: number + ) { + return this.parse(instr, opcode, inputs, outputs, opSize) + } + + static validOpcode( + instr: string, + opcode: number, + inputs: number, + outputs: number, + opSize: number + ) { + return this.parse(instr, opcode, inputs, outputs, opSize) + } + static unallocatedOpcode(opcode: number) { + return undefined + } + + static invalidOpcode(instr: string, opcode: number) { + return undefined + } + + static parse(instr: string, opcode: number, inputs: number, outputs: number, opSize: number) { + const hexStr = '0x' + opcode.toString(16).padStart(2, '0') + stackDelta[hexStr] = { + inputs, + outputs, + name: instr, + intermediates: opSize - 1, + } + } +} + +// This code is from Besu: https://github.com/hyperledger/besu/blob/ac5d03f91d4c9e938ff5b4ba90abae1bb4afa997/evm/src/main/java/org/hyperledger/besu/evm/code/OpcodeInfo.java#L79 +const tbl = [ + OpcodeInfo.terminalOpcode('STOP', 0x00, 0, 0, 1), + OpcodeInfo.validOpcode('ADD', 0x01, 2, 1, 1), + OpcodeInfo.validOpcode('MUL', 0x02, 2, 1, 1), + OpcodeInfo.validOpcode('SUB', 0x03, 2, 1, 1), + OpcodeInfo.validOpcode('DIV', 0x04, 2, 1, 1), + OpcodeInfo.validOpcode('SDIV', 0x05, 2, 1, 1), + OpcodeInfo.validOpcode('MOD', 0x06, 2, 1, 1), + OpcodeInfo.validOpcode('SMOD', 0x07, 2, 1, 1), + OpcodeInfo.validOpcode('ADDMOD', 0x08, 3, 1, 1), + OpcodeInfo.validOpcode('MULMOD', 0x09, 3, 1, 1), + OpcodeInfo.validOpcode('EXP', 0x0a, 2, 1, 1), + OpcodeInfo.validOpcode('SIGNEXTEND', 0x0b, 2, 1, 1), + OpcodeInfo.unallocatedOpcode(0x0c), + OpcodeInfo.unallocatedOpcode(0x0d), + OpcodeInfo.unallocatedOpcode(0x0e), + OpcodeInfo.unallocatedOpcode(0x0f), + OpcodeInfo.validOpcode('LT', 0x10, 2, 1, 1), + OpcodeInfo.validOpcode('GT', 0x11, 2, 1, 1), + OpcodeInfo.validOpcode('SLT', 0x12, 2, 1, 1), + OpcodeInfo.validOpcode('SGT', 0x13, 2, 1, 1), + OpcodeInfo.validOpcode('EQ', 0x14, 2, 1, 1), + OpcodeInfo.validOpcode('ISZERO', 0x15, 1, 1, 1), + OpcodeInfo.validOpcode('AND', 0x16, 2, 1, 1), + OpcodeInfo.validOpcode('OR', 0x17, 2, 1, 1), + OpcodeInfo.validOpcode('XOR', 0x18, 2, 1, 1), + OpcodeInfo.validOpcode('NOT', 0x19, 1, 1, 1), + OpcodeInfo.validOpcode('BYTE', 0x1a, 2, 1, 1), + OpcodeInfo.validOpcode('SHL', 0x1b, 2, 1, 1), + OpcodeInfo.validOpcode('SHR', 0x1c, 2, 1, 1), + OpcodeInfo.validOpcode('SAR', 0x1d, 2, 1, 1), + OpcodeInfo.unallocatedOpcode(0x1e), + OpcodeInfo.unallocatedOpcode(0x1f), + OpcodeInfo.validOpcode('SHA3', 0x20, 2, 1, 1), + OpcodeInfo.unallocatedOpcode(0x21), + OpcodeInfo.unallocatedOpcode(0x22), + OpcodeInfo.unallocatedOpcode(0x23), + OpcodeInfo.unallocatedOpcode(0x24), + OpcodeInfo.unallocatedOpcode(0x25), + OpcodeInfo.unallocatedOpcode(0x26), + OpcodeInfo.unallocatedOpcode(0x27), + OpcodeInfo.unallocatedOpcode(0x28), + OpcodeInfo.unallocatedOpcode(0x29), + OpcodeInfo.unallocatedOpcode(0x2a), + OpcodeInfo.unallocatedOpcode(0x2b), + OpcodeInfo.unallocatedOpcode(0x2c), + OpcodeInfo.unallocatedOpcode(0x2d), + OpcodeInfo.unallocatedOpcode(0x2e), + OpcodeInfo.unallocatedOpcode(0x2f), + OpcodeInfo.validOpcode('ADDRESS', 0x30, 0, 1, 1), + OpcodeInfo.validOpcode('BALANCE', 0x31, 1, 1, 1), + OpcodeInfo.validOpcode('ORIGIN', 0x32, 0, 1, 1), + OpcodeInfo.validOpcode('CALLER', 0x33, 0, 1, 1), + OpcodeInfo.validOpcode('CALLVALUE', 0x34, 0, 1, 1), + OpcodeInfo.validOpcode('CALLDATALOAD', 0x35, 1, 1, 1), + OpcodeInfo.validOpcode('CALLDATASIZE', 0x36, 0, 1, 1), + OpcodeInfo.validOpcode('CALLDATACOPY', 0x37, 3, 0, 1), + OpcodeInfo.invalidOpcode('CODESIZE', 0x38), + OpcodeInfo.invalidOpcode('CODECOPY', 0x39), + OpcodeInfo.validOpcode('GASPRICE', 0x3a, 0, 1, 1), + OpcodeInfo.invalidOpcode('EXTCODESIZE', 0x3b), + OpcodeInfo.invalidOpcode('EXTCODECOPY', 0x3c), + OpcodeInfo.validOpcode('RETURNDATASIZE', 0x3d, 0, 1, 1), + OpcodeInfo.validOpcode('RETURNDATACOPY', 0x3e, 3, 0, 1), + OpcodeInfo.invalidOpcode('EXTCODEHASH', 0x3f), + OpcodeInfo.validOpcode('BLOCKHASH', 0x40, 1, 1, 1), + OpcodeInfo.validOpcode('COINBASE', 0x41, 0, 1, 1), + OpcodeInfo.validOpcode('TIMESTAMP', 0x42, 0, 1, 1), + OpcodeInfo.validOpcode('NUMBER', 0x43, 0, 1, 1), + OpcodeInfo.validOpcode('PREVRANDAO', 0x44, 0, 1, 1), // was DIFFICULTY + OpcodeInfo.validOpcode('GASLIMIT', 0x45, 0, 1, 1), + OpcodeInfo.validOpcode('CHAINID', 0x46, 0, 1, 1), + OpcodeInfo.validOpcode('SELFBALANCE', 0x47, 0, 1, 1), + OpcodeInfo.validOpcode('BASEFEE', 0x48, 0, 1, 1), + OpcodeInfo.validOpcode('BLOBAHASH', 0x49, 1, 1, 1), + OpcodeInfo.validOpcode('BLOBBASEFEE', 0x4a, 0, 1, 1), + OpcodeInfo.unallocatedOpcode(0x4b), + OpcodeInfo.unallocatedOpcode(0x4c), + OpcodeInfo.unallocatedOpcode(0x4d), + OpcodeInfo.unallocatedOpcode(0x4e), + OpcodeInfo.unallocatedOpcode(0x4f), + OpcodeInfo.validOpcode('POP', 0x50, 1, 0, 1), + OpcodeInfo.validOpcode('MLOAD', 0x51, 1, 1, 1), + OpcodeInfo.validOpcode('MSTORE', 0x52, 2, 0, 1), + OpcodeInfo.validOpcode('MSTORE8', 0x53, 2, 0, 1), + OpcodeInfo.validOpcode('SLOAD', 0x54, 1, 1, 1), + OpcodeInfo.validOpcode('SSTORE', 0x55, 2, 0, 1), + OpcodeInfo.invalidOpcode('JUMP', 0x56), + OpcodeInfo.invalidOpcode('JUMPI', 0x57), + OpcodeInfo.invalidOpcode('PC', 0x58), + OpcodeInfo.validOpcode('MSIZE', 0x59, 0, 1, 1), + OpcodeInfo.invalidOpcode('GAS', 0x5a), + OpcodeInfo.validOpcode('NOOP', 0x5b, 0, 0, 1), // was JUMPDEST + OpcodeInfo.validOpcode('TLOAD', 0x5c, 1, 1, 1), + OpcodeInfo.validOpcode('TSTORE', 0x5d, 2, 0, 1), + OpcodeInfo.validOpcode('MCOPY', 0x5e, 3, 0, 1), + OpcodeInfo.validOpcode('PUSH0', 0x5f, 0, 1, 1), + OpcodeInfo.validOpcode('PUSH1', 0x60, 0, 1, 2), + OpcodeInfo.validOpcode('PUSH2', 0x61, 0, 1, 3), + OpcodeInfo.validOpcode('PUSH3', 0x62, 0, 1, 4), + OpcodeInfo.validOpcode('PUSH4', 0x63, 0, 1, 5), + OpcodeInfo.validOpcode('PUSH5', 0x64, 0, 1, 6), + OpcodeInfo.validOpcode('PUSH6', 0x65, 0, 1, 7), + OpcodeInfo.validOpcode('PUSH7', 0x66, 0, 1, 8), + OpcodeInfo.validOpcode('PUSH8', 0x67, 0, 1, 9), + OpcodeInfo.validOpcode('PUSH9', 0x68, 0, 1, 10), + OpcodeInfo.validOpcode('PUSH10', 0x69, 0, 1, 11), + OpcodeInfo.validOpcode('PUSH11', 0x6a, 0, 1, 12), + OpcodeInfo.validOpcode('PUSH12', 0x6b, 0, 1, 13), + OpcodeInfo.validOpcode('PUSH13', 0x6c, 0, 1, 14), + OpcodeInfo.validOpcode('PUSH14', 0x6d, 0, 1, 15), + OpcodeInfo.validOpcode('PUSH15', 0x6e, 0, 1, 16), + OpcodeInfo.validOpcode('PUSH16', 0x6f, 0, 1, 17), + OpcodeInfo.validOpcode('PUSH17', 0x70, 0, 1, 18), + OpcodeInfo.validOpcode('PUSH18', 0x71, 0, 1, 19), + OpcodeInfo.validOpcode('PUSH19', 0x72, 0, 1, 20), + OpcodeInfo.validOpcode('PUSH20', 0x73, 0, 1, 21), + OpcodeInfo.validOpcode('PUSH21', 0x74, 0, 1, 22), + OpcodeInfo.validOpcode('PUSH22', 0x75, 0, 1, 23), + OpcodeInfo.validOpcode('PUSH23', 0x76, 0, 1, 24), + OpcodeInfo.validOpcode('PUSH24', 0x77, 0, 1, 25), + OpcodeInfo.validOpcode('PUSH25', 0x78, 0, 1, 26), + OpcodeInfo.validOpcode('PUSH26', 0x79, 0, 1, 27), + OpcodeInfo.validOpcode('PUSH27', 0x7a, 0, 1, 28), + OpcodeInfo.validOpcode('PUSH28', 0x7b, 0, 1, 29), + OpcodeInfo.validOpcode('PUSH29', 0x7c, 0, 1, 30), + OpcodeInfo.validOpcode('PUSH30', 0x7d, 0, 1, 31), + OpcodeInfo.validOpcode('PUSH31', 0x7e, 0, 1, 32), + OpcodeInfo.validOpcode('PUSH32', 0x7f, 0, 1, 33), + OpcodeInfo.validOpcode('DUP1', 0x80, 1, 2, 1), + OpcodeInfo.validOpcode('DUP2', 0x81, 2, 3, 1), + OpcodeInfo.validOpcode('DUP3', 0x82, 3, 4, 1), + OpcodeInfo.validOpcode('DUP4', 0x83, 4, 5, 1), + OpcodeInfo.validOpcode('DUP5', 0x84, 5, 6, 1), + OpcodeInfo.validOpcode('DUP6', 0x85, 6, 7, 1), + OpcodeInfo.validOpcode('DUP7', 0x86, 7, 8, 1), + OpcodeInfo.validOpcode('DUP8', 0x87, 8, 9, 1), + OpcodeInfo.validOpcode('DUP9', 0x88, 9, 10, 1), + OpcodeInfo.validOpcode('DUP10', 0x89, 10, 11, 1), + OpcodeInfo.validOpcode('DUP11', 0x8a, 11, 12, 1), + OpcodeInfo.validOpcode('DUP12', 0x8b, 12, 13, 1), + OpcodeInfo.validOpcode('DUP13', 0x8c, 13, 14, 1), + OpcodeInfo.validOpcode('DUP14', 0x8d, 14, 15, 1), + OpcodeInfo.validOpcode('DUP15', 0x8e, 15, 16, 1), + OpcodeInfo.validOpcode('DUP16', 0x8f, 16, 17, 1), + OpcodeInfo.validOpcode('SWAP1', 0x90, 2, 2, 1), + OpcodeInfo.validOpcode('SWAP2', 0x91, 3, 3, 1), + OpcodeInfo.validOpcode('SWAP3', 0x92, 4, 4, 1), + OpcodeInfo.validOpcode('SWAP4', 0x93, 5, 5, 1), + OpcodeInfo.validOpcode('SWAP5', 0x94, 6, 6, 1), + OpcodeInfo.validOpcode('SWAP6', 0x95, 7, 7, 1), + OpcodeInfo.validOpcode('SWAP7', 0x96, 8, 8, 1), + OpcodeInfo.validOpcode('SWAP8', 0x97, 9, 9, 1), + OpcodeInfo.validOpcode('SWAP9', 0x98, 10, 10, 1), + OpcodeInfo.validOpcode('SWAP10', 0x99, 11, 11, 1), + OpcodeInfo.validOpcode('SWAP11', 0x9a, 12, 12, 1), + OpcodeInfo.validOpcode('SWAP12', 0x9b, 13, 13, 1), + OpcodeInfo.validOpcode('SWAP13', 0x9c, 14, 14, 1), + OpcodeInfo.validOpcode('SWAP14', 0x9d, 15, 15, 1), + OpcodeInfo.validOpcode('SWAP15', 0x9e, 16, 16, 1), + OpcodeInfo.validOpcode('SWAP16', 0x9f, 17, 17, 1), + OpcodeInfo.validOpcode('LOG0', 0xa0, 2, 0, 1), + OpcodeInfo.validOpcode('LOG1', 0xa1, 3, 0, 1), + OpcodeInfo.validOpcode('LOG2', 0xa2, 4, 0, 1), + OpcodeInfo.validOpcode('LOG3', 0xa3, 5, 0, 1), + OpcodeInfo.validOpcode('LOG4', 0xa4, 6, 0, 1), + OpcodeInfo.unallocatedOpcode(0xa5), + OpcodeInfo.unallocatedOpcode(0xa6), + OpcodeInfo.unallocatedOpcode(0xa7), + OpcodeInfo.unallocatedOpcode(0xa8), + OpcodeInfo.unallocatedOpcode(0xa9), + OpcodeInfo.unallocatedOpcode(0xaa), + OpcodeInfo.unallocatedOpcode(0xab), + OpcodeInfo.unallocatedOpcode(0xac), + OpcodeInfo.unallocatedOpcode(0xad), + OpcodeInfo.unallocatedOpcode(0xae), + OpcodeInfo.unallocatedOpcode(0xaf), + OpcodeInfo.unallocatedOpcode(0xb0), + OpcodeInfo.unallocatedOpcode(0xb1), + OpcodeInfo.unallocatedOpcode(0xb2), + OpcodeInfo.unallocatedOpcode(0xb3), + OpcodeInfo.unallocatedOpcode(0xb4), + OpcodeInfo.unallocatedOpcode(0xb5), + OpcodeInfo.unallocatedOpcode(0xb6), + OpcodeInfo.unallocatedOpcode(0xb7), + OpcodeInfo.unallocatedOpcode(0xb8), + OpcodeInfo.unallocatedOpcode(0xb9), + OpcodeInfo.unallocatedOpcode(0xba), + OpcodeInfo.unallocatedOpcode(0xbb), + OpcodeInfo.unallocatedOpcode(0xbc), + OpcodeInfo.unallocatedOpcode(0xbd), + OpcodeInfo.unallocatedOpcode(0xbe), + OpcodeInfo.unallocatedOpcode(0xbf), + OpcodeInfo.unallocatedOpcode(0xc0), + OpcodeInfo.unallocatedOpcode(0xc1), + OpcodeInfo.unallocatedOpcode(0xc2), + OpcodeInfo.unallocatedOpcode(0xc3), + OpcodeInfo.unallocatedOpcode(0xc4), + OpcodeInfo.unallocatedOpcode(0xc5), + OpcodeInfo.unallocatedOpcode(0xc6), + OpcodeInfo.unallocatedOpcode(0xc7), + OpcodeInfo.unallocatedOpcode(0xc8), + OpcodeInfo.unallocatedOpcode(0xc9), + OpcodeInfo.unallocatedOpcode(0xca), + OpcodeInfo.unallocatedOpcode(0xcb), + OpcodeInfo.unallocatedOpcode(0xcc), + OpcodeInfo.unallocatedOpcode(0xcd), + OpcodeInfo.unallocatedOpcode(0xce), + OpcodeInfo.unallocatedOpcode(0xcf), + OpcodeInfo.validOpcode('DATALOAD', 0xd0, 1, 1, 1), + OpcodeInfo.validOpcode('DATALOADN', 0xd1, 0, 1, 3), + OpcodeInfo.validOpcode('DATASIZE', 0xd2, 0, 1, 1), + OpcodeInfo.validOpcode('DATACOPY', 0xd3, 3, 0, 1), + OpcodeInfo.unallocatedOpcode(0xd4), + OpcodeInfo.unallocatedOpcode(0xd5), + OpcodeInfo.unallocatedOpcode(0xd6), + OpcodeInfo.unallocatedOpcode(0xd7), + OpcodeInfo.unallocatedOpcode(0xd8), + OpcodeInfo.unallocatedOpcode(0xd9), + OpcodeInfo.unallocatedOpcode(0xda), + OpcodeInfo.unallocatedOpcode(0xdb), + OpcodeInfo.unallocatedOpcode(0xdc), + OpcodeInfo.unallocatedOpcode(0xdd), + OpcodeInfo.unallocatedOpcode(0xde), + OpcodeInfo.unallocatedOpcode(0xdf), + OpcodeInfo.terminalOpcode('RJUMP', 0xe0, 0, 0, 3), + OpcodeInfo.validOpcode('RJUMPI', 0xe1, 1, 0, 3), + OpcodeInfo.validOpcode('RJUMPV', 0xe2, 1, 0, 2), + OpcodeInfo.validOpcode('CALLF', 0xe3, 0, 0, 3), + OpcodeInfo.terminalOpcode('RETF', 0xe4, 0, 0, 1), + OpcodeInfo.terminalOpcode('JUMPF', 0xe5, 0, 0, 3), + OpcodeInfo.validOpcode('DUPN', 0xe6, 0, 1, 2), + OpcodeInfo.validOpcode('SWAPN', 0xe7, 0, 0, 2), + OpcodeInfo.validOpcode('EXCHANGE', 0xe8, 0, 0, 2), + OpcodeInfo.unallocatedOpcode(0xe9), + OpcodeInfo.unallocatedOpcode(0xea), + OpcodeInfo.unallocatedOpcode(0xeb), + OpcodeInfo.validOpcode('EOFCREATE', 0xec, 4, 1, 2), + OpcodeInfo.unallocatedOpcode(0xed), + OpcodeInfo.terminalOpcode('RETURNCONTRACT', 0xee, 2, 1, 2), + OpcodeInfo.unallocatedOpcode(0xef), + OpcodeInfo.invalidOpcode('CREATE', 0xf0), + OpcodeInfo.invalidOpcode('CALL', 0xf1), + OpcodeInfo.invalidOpcode('CALLCODE', 0xf2), + OpcodeInfo.terminalOpcode('RETURN', 0xf3, 2, 0, 1), + OpcodeInfo.invalidOpcode('DELEGATECALL', 0xf4), + OpcodeInfo.invalidOpcode('CREATE2', 0xf5), + OpcodeInfo.unallocatedOpcode(0xf6), + OpcodeInfo.validOpcode('RETURNDATALOAD', 0xf7, 1, 1, 1), + OpcodeInfo.validOpcode('EXTCALL', 0xf8, 4, 1, 1), + OpcodeInfo.validOpcode('EXTDELEGATECALL', 0xf9, 3, 1, 1), + OpcodeInfo.invalidOpcode('STATICCALL', 0xfa), + OpcodeInfo.validOpcode('EXTSTATICCALL', 0xfb, 3, 1, 1), + OpcodeInfo.unallocatedOpcode(0xfc), + OpcodeInfo.terminalOpcode('REVERT', 0xfd, 2, 0, 1), + OpcodeInfo.terminalOpcode('INVALID', 0xfe, 0, 0, 1), + OpcodeInfo.invalidOpcode('SELFDESTRUCT', 0xff), +] + +console.log(JSON.stringify(stackDelta)) diff --git a/packages/evm/src/eof.ts b/packages/evm/src/eof.ts deleted file mode 100644 index 17a8ff29d6..0000000000 --- a/packages/evm/src/eof.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { handlers } from './opcodes/index.js' - -export const FORMAT = 0xef -export const MAGIC = 0x00 -export const VERSION = 0x01 - -/** - * - * @param container A `Uint8Array` containing bytecode to be checked for EOF1 compliance - * @returns an object containing the size of the code section and data sections for a valid - * EOF1 container or else undefined if `container` is not valid EOF1 bytecode - * - * Note: See https://eips.ethereum.org/EIPS/eip-3540 for further details - */ -export const codeAnalysis = (container: Uint8Array) => { - const secCode = 0x01 - const secData = 0x02 - const secTerminator = 0x00 - let computedContainerSize = 0 - const sectionSizes = { - code: 0, - data: 0, - } - if (container[0] !== FORMAT || container[1] !== MAGIC || container[2] !== VERSION) - // Bytecode does not contain EOF1 "magic" or version number in expected positions - return - - if ( - // EOF1 bytecode must be more than 7 bytes long for EOF1 header plus code section (but no data section) - container.length > 7 && - // EOF1 code section indicator - container[3] === secCode && - // EOF1 header terminator - container[6] === secTerminator - ) { - sectionSizes.code = (container[4] << 8) | container[5] - // Calculate expected length of EOF1 container based on code section - computedContainerSize = 7 + sectionSizes.code - // EOF1 code section must be at least 1 byte long - if (sectionSizes.code < 1) return - } else if ( - // EOF1 container must be more than 10 bytes long if data section is included - container.length > 10 && - // EOF1 code section indicator - container[3] === secCode && - // EOF1 data section indicator - container[6] === secData && - // EOF1 header terminator - container[9] === secTerminator - ) { - sectionSizes.code = (container[4] << 8) | container[5] - sectionSizes.data = (container[7] << 8) | container[8] - // Calculate expected length of EOF1 container based on code and data sections - computedContainerSize = 10 + sectionSizes.code + sectionSizes.data - // Code & Data sizes cannot be 0 - if (sectionSizes.code < 1 || sectionSizes.data < 1) return - } - if (container.length !== computedContainerSize) { - // Computed container length based on section details does not match length of actual bytecode - return - } - return sectionSizes -} - -export const validOpcodes = (code: Uint8Array) => { - // EIP-3670 - validate all opcodes - const opcodes = new Set(handlers.keys()) - opcodes.add(0xfe) // Add INVALID opcode to set - - let x = 0 - while (x < code.length) { - const opcode = code[x] - x++ - if (!opcodes.has(opcode)) { - // No invalid/undefined opcodes - return false - } - if (opcode >= 0x60 && opcode <= 0x7f) { - // Skip data block following push - x += opcode - 0x5f - if (x > code.length - 1) { - // Push blocks must not exceed end of code section - return false - } - } - } - const terminatingOpcodes = new Set([0x00, 0xf3, 0xfd, 0xfe, 0xff]) - // Per EIP-3670, the final opcode of a code section must be STOP, RETURN, REVERT, INVALID, or SELFDESTRUCT - if (!terminatingOpcodes.has(code[code.length - 1])) { - return false - } - return true -} - -export const getEOFCode = (code: Uint8Array) => { - const sectionSizes = codeAnalysis(code) - if (sectionSizes === undefined) { - return code - } else { - const codeStart = sectionSizes.data > 0 ? 10 : 7 - return code.subarray(codeStart, codeStart + sectionSizes.code) - } -} - -export const EOF = { FORMAT, MAGIC, VERSION, codeAnalysis, validOpcodes } diff --git a/packages/evm/src/eof/constants.ts b/packages/evm/src/eof/constants.ts new file mode 100644 index 0000000000..42ec1cc74b --- /dev/null +++ b/packages/evm/src/eof/constants.ts @@ -0,0 +1,36 @@ +// Constants, which are taken from https://eips.ethereum.org/EIPS/eip-3540 + +// The "starting bytes" of an EOF contract +export const FORMAT = 0xef +export const MAGIC = 0x00 +export const VERSION = 0x01 + +// The min/max sizes of valid headers +export const MIN_HEADER_SIZE = 15 // This min size is used to invalidate an invalid container quickly +export const MAX_HEADER_SIZE = 49152 // Max initcode size, EIP 3860 + +export const KIND_TYPE = 0x01 // The type byte of the types section +export const KIND_CODE = 0x02 // The type byte of the code section +export const KIND_CONTAINER = 0x03 // The type byte of the container section (this is the only optional section in the header) +export const KIND_DATA = 0x04 // The type byte of the data section +export const TERMINATOR = 0x00 // The terminator byte of the header + +export const TYPE_MIN = 0x0004 // The minimum size of the types section +export const TYPE_MAX = 0x1000 // The maximum size of the types section +export const TYPE_DIVISOR = 4 // The divisor of types: the type section size should be a multiple of this + +export const CODE_MIN = 0x0001 // The minimum size of the code section + +export const CODE_SIZE_MIN = 1 // The minimum size of a code section in the body (the actual code) + +export const CONTAINER_MIN = 0x0001 // The minimum size of the container section +export const CONTAINER_MAX = 0x0100 // The maximum size of the container section + +export const CONTAINER_SIZE_MIN = 1 // The minimum size of a container in the body + +// Constants regarding the type section in the body of the container +export const INPUTS_MAX = 0x7f // The maximum amounts of inputs to a code section in the body +export const OUTPUTS_MAX = 0x80 // The maximum amounts of outputs of a code section in the body +// Note: 0x80 is a special amount of outputs, this marks the code section as "terminating". +// A terminating section will exit the current call frame, such as RETURN / STOP opcodes. It will not RETF to another code section +export const MAX_STACK_HEIGHT = 0x03ff // The maximum stack height of a code section (this enforces that the stack of this section cannot overflow) diff --git a/packages/evm/src/eof/container.ts b/packages/evm/src/eof/container.ts new file mode 100644 index 0000000000..7a60e1f141 --- /dev/null +++ b/packages/evm/src/eof/container.ts @@ -0,0 +1,461 @@ +import { + CODE_MIN, + CODE_SIZE_MIN, + CONTAINER_MAX, + CONTAINER_MIN, + CONTAINER_SIZE_MIN, + FORMAT, + INPUTS_MAX, + KIND_CODE, + KIND_CONTAINER, + KIND_DATA, + KIND_TYPE, + MAGIC, + MAX_HEADER_SIZE, + MAX_STACK_HEIGHT, + OUTPUTS_MAX, + TERMINATOR, + TYPE_DIVISOR, + TYPE_MAX, + TYPE_MIN, + VERSION, +} from './constants.js' +import { EOFError, validationError } from './errors.js' +import { ContainerSectionType, verifyCode } from './verify.js' + +import type { EVM } from '../evm.js' + +/* + This file creates EOF Containers + EOF Containers are described in EIP-3540. + A container consists of a header and a body. The header describes the layout of the body. + The body has the actual "interesting" contents, such as the bytecode to run, the data section, + and possibly yet-to-be-deployed containers (via EOFCREATE, to create new EOF contracts from an existing one) +*/ + +// This enum marks the "mode" of a container +// Depending on this mode, certain extra checks for validity have to be done, or some checks can be skipped +export enum EOFContainerMode { + Default, // Default container validation + Initmode, // Initmode container validation (for subcontainers pointed to by EOFCreate) + TxInitmode, // Tx initmode container validation (for txs deploying EOF contracts) +} + +// The StreamReader is a helper class to help reading byte arrays +class StreamReader { + private data: Uint8Array // Stream to read + private ptr: number // Current pointer to where the stream is being read + constructor(stream: Uint8Array) { + this.data = stream + this.ptr = 0 + } + + /** + * Read `amount` bytes from the stream. Throws when trying to read out of bounds with an optional error string. + * This also updates the internal pointer + * @param amount Bytes to read + * @param errorStr Optional error string to throw when trying to read out-of-bounds + * @returns The byte array with length `amount` + */ + readBytes(amount: number, errorStr?: string) { + const end = this.ptr + amount + if (end > this.data.length) { + validationError(EOFError.OutOfBounds, this.ptr, errorStr) + } + const ptr = this.ptr + this.ptr += amount + return this.data.slice(ptr, end) + } + + /** + * Reads an Uint8. Also updates the pointer. + * @param errorStr Optional error string + * @returns The uint8 + */ + readUint(errorStr?: string) { + if (this.ptr >= this.data.length) { + validationError(EOFError.OutOfBounds, this.ptr, errorStr) + } + return this.data[this.ptr++] + } + + /** + * Verify that the current uint8 pointed to by the pointer is the expected uint8 + * Also updates the pointer + * @param expect The uint to expect + * @param errorStr Optional error string when the read uint is not the expected uint + */ + verifyUint(expect: number, errorStr?: string) { + if (this.readUint() !== expect) { + validationError(EOFError.VerifyUint, this.ptr - 1, errorStr) + } + } + + /** + * Same as readUint, except this reads an uint16 + * @param errorStr + * @returns + */ + readUint16(errorStr?: string) { + const end = this.ptr + 2 + if (end > this.data.length) { + validationError(EOFError.OutOfBounds, this.ptr, errorStr) + } + const ptr = this.ptr + this.ptr += 2 + return new DataView(this.data.buffer).getUint16(ptr) + } + + /** + * Get the current pointer of the stream + * @returns The pointer + */ + getPtr() { + return this.ptr + } + + // Get the remainder bytes of the current stream + readRemainder() { + return this.data.slice(this.ptr) + } + + // Returns `true` if the stream is fully read, or false if there are dangling bytes + isAtEnd() { + return this.ptr === this.data.length + } +} + +// TODO add initcode flags (isEOFContract) +// TODO validation: mark sections as either initcode or runtime code to validate + +/** + * The EOFHeader, describing the header of the EOF container + */ +class EOFHeader { + typeSize: number // Size of the types section + codeSizes: number[] // Sizes of the code sections + containerSizes: number[] // Sizes of the containers + dataSize: number // Size of the data section + dataSizePtr: number // Used to edit the dataSize in RETURNCONTRACT + buffer: Uint8Array // The raw buffer of the entire header + + private codeStartPos: number[] // Internal array to track at which byte of the container the code starts (per section) + + /** + * Create an EOF header. Performs various validation checks inside the constructor + * @param input The input should either be a raw header, or a complete container + */ + constructor(input: Uint8Array) { + if (input.length > MAX_HEADER_SIZE) { + throw new Error('err: container size more than maximum valid size') + } + const stream = new StreamReader(input) + // Verify that the header starts with 0xEF0001 + stream.verifyUint(FORMAT, EOFError.FORMAT) + stream.verifyUint(MAGIC, EOFError.MAGIC) + stream.verifyUint(VERSION, EOFError.VERSION) + if (input.length < 15) { + throw new Error('err: container size less than minimum valid size') + } + // Verify that the types section is present, and verify that the type section length is valid + stream.verifyUint(KIND_TYPE, EOFError.KIND_TYPE) + const typeSize = stream.readUint16(EOFError.TypeSize) + if (typeSize < TYPE_MIN) { + validationError(EOFError.InvalidTypeSize, typeSize) + } + if (typeSize % TYPE_DIVISOR !== 0) { + validationError(EOFError.InvalidTypeSize, typeSize) + } + if (typeSize > TYPE_MAX) { + throw new Error(`err: number of code sections must not exceed 1024 (got ${typeSize})`) + } + // Verify that the code section is present, and verify that the code section size is valid + stream.verifyUint(KIND_CODE, EOFError.KIND_CODE) + const codeSize = stream.readUint16(EOFError.CodeSize) + if (codeSize < CODE_MIN) { + validationError(EOFError.MinCodeSections) + } + if (codeSize !== typeSize / TYPE_DIVISOR) { + validationError(EOFError.TypeSections, typeSize / TYPE_DIVISOR, codeSize) + } + // Read the actual code sizes in the code section, and verify that each code section has the minimum size + const codeSizes = [] + for (let i = 0; i < codeSize; i++) { + const codeSectionSize = stream.readUint16(EOFError.CodeSection) + if (codeSectionSize < CODE_SIZE_MIN) { + validationError(EOFError.CodeSectionSize) + } + codeSizes.push(codeSectionSize) + } + + // Check if there are container sections + let nextSection = stream.readUint() + const containerSizes: number[] = [] + if (nextSection === KIND_CONTAINER) { + // The optional container section is present, validate that the size is within bounds + const containerSectionSize = stream.readUint16(EOFError.ContainerSize) + + if (containerSectionSize < CONTAINER_MIN) { + validationError(EOFError.ContainerSectionSize) + } + if (containerSectionSize > CONTAINER_MAX) { + validationError(EOFError.ContainerSectionSize) + } + + // Read the actual container sections, and validate that each container section has the minimum size + for (let i = 0; i < containerSectionSize; i++) { + const containerSize = stream.readUint16(EOFError.ContainerSection) + + if (containerSize < CONTAINER_SIZE_MIN) { + validationError(EOFError.ContainerSectionMin) + } + + containerSizes.push(containerSize) + } + + nextSection = stream.readUint() + } + + // Verify that the next section is of the data type + if (nextSection !== KIND_DATA) { + validationError(EOFError.KIND_DATA) + } + + this.dataSizePtr = stream.getPtr() + + const dataSize = stream.readUint16(EOFError.DataSize) + + // Verify that the header ends with the TERMINATOR byte + stream.verifyUint(TERMINATOR, EOFError.TERMINATOR) + + // Write all values to the header object + this.typeSize = typeSize + this.codeSizes = codeSizes + this.containerSizes = containerSizes + this.dataSize = dataSize + // Slice the input such that `this.buffer` is now the complete header + // If there are dangling bytes in the stream, this is OK: this is the body section of the container + this.buffer = input.slice(0, stream.getPtr()) + const relativeOffset = this.buffer.length + this.typeSize + // Write the start of the first code section into `codeStartPos` + // Note: in EVM, if one would set the Program Counter to this byte, it would start executing the bytecode of the first code section + this.codeStartPos = [relativeOffset] + } + + sections() { + return [this.typeSize, this.codeSizes, this.containerSizes, this.dataSize] + } + sectionSizes() { + return [1, this.codeSizes.length, this.containerSizes.length, 1] + } + + // Returns the code position in the container for the requested section + // Setting the Program Counter in the EVM to a number of this array would start executing the bytecode of the indexed section + getCodePosition(section: number) { + if (this.codeStartPos[section]) { + return this.codeStartPos[section] + } + const start = this.codeStartPos.length + let offset = this.codeStartPos[start - 1] + for (let i = start; i <= section; i++) { + offset += this.codeSizes[i - 1] + this.codeStartPos[i] = offset + } + return offset + } +} + +export interface TypeSection { + inputs: number + outputs: number + maxStackHeight: number +} + +/** + * The EOF body holds the contents of the EOF container, such as the code sections (bytecode), + * the subcontainers (EOF containers to be deployed via EOFCREATE) and the data section + */ +class EOFBody { + typeSections: TypeSection[] // Array of type sections, used to index the inputs/outputs/max stack height of each section + codeSections: Uint8Array[] // The bytecode of each code section + containerSections: Uint8Array[] // The raw container bytes of each subcontainer + entireCode: Uint8Array // The `entireCode` are all code sections concatenated + dataSection: Uint8Array // The bytes of the data section + buffer: Uint8Array // The raw bytes of the body + + txCallData?: Uint8Array // Only available in TxInitmode. The `txCallData` are the dangling bytes after parsing the container, + // and these are used for the CALLDATA in the EVM when trying to create a contract via a transaction, and the deployment code is an EOF container + + constructor( + buf: Uint8Array, // The buffer of the body. This should be the entire body. It is not valid to pass an entire EOF container in here + header: EOFHeader, // The EOFHeader corresponding to this body + eofMode: EOFContainerMode = EOFContainerMode.Default, // The container mode of EOF + dataSectionAllowedSmaller = false // Only for validation: Deployment containers are allowed to have smaller data section size + ) { + const stream = new StreamReader(buf) + const typeSections: TypeSection[] = [] + // Read and parse each type section, and validate that the type section values are within valid bounds + for (let i = 0; i < header.typeSize / 4; i++) { + const inputs = stream.readUint(EOFError.Inputs) + const outputs = stream.readUint(EOFError.Outputs) + const maxStackHeight = stream.readUint16(EOFError.MaxStackHeight) + if (i === 0) { + if (inputs !== 0) { + validationError(EOFError.Code0Inputs) + } + if (outputs !== 0x80) { + validationError(EOFError.Code0Outputs) + } + } + if (inputs > INPUTS_MAX) { + validationError(EOFError.MaxInputs, i, inputs) + } + if (outputs > OUTPUTS_MAX) { + validationError(EOFError.MaxOutputs, i, outputs) + } + if (maxStackHeight > MAX_STACK_HEIGHT) { + validationError(EOFError.MaxStackHeightLimit, i, maxStackHeight) + } + typeSections.push({ + inputs, + outputs, + maxStackHeight, + }) + } + // Read each code section + const codeStartPtr = stream.getPtr() + const codes = [] + for (const [i, codeSize] of header.codeSizes.entries()) { + try { + const code = stream.readBytes(codeSize) + codes.push(code) + } catch { + validationError(EOFError.CodeSection, i) + } + } + // Write the entire code section to the entireCodeSection + const entireCodeSection = buf.slice(codeStartPtr, stream.getPtr()) + + // Read all raw subcontainers and push those to the containers array + const containers = [] + for (const [i, containerSize] of header.containerSizes.entries()) { + try { + const container = stream.readBytes(containerSize) + containers.push(container) + } catch { + validationError(EOFError.ContainerSection, i) + } + } + + // Data section of the body + // Note: for EOF containers in Initmode (these are Subcontainers) it is allowed + // to have a data section of size lower than what is written in the header + // For details, see "Data section lifecycle" of EIP 7620 + let dataSection: Uint8Array + + // Edge case: deployment code validation + if (eofMode !== EOFContainerMode.Initmode && !dataSectionAllowedSmaller) { + dataSection = stream.readBytes(header.dataSize, EOFError.DataSection) + + if (eofMode === EOFContainerMode.Default) { + if (!stream.isAtEnd()) { + // If there are dangling bytes in default container mode, this is invalid + validationError(EOFError.DanglingBytes) + } + } else { + // Tx init mode: the remaining bytes (if any) are used as CALLDATA in the EVM, in case of a Tx init + this.txCallData = stream.readRemainder() + } + } else { + dataSection = stream.readRemainder() + } + + // Write all data to the object + this.typeSections = typeSections + this.codeSections = codes + this.containerSections = containers + this.entireCode = entireCodeSection + this.dataSection = dataSection + this.buffer = buf + } + sections() { + return [this.typeSections, this.codeSections, this.dataSection] + } + size() { + return { + typeSize: this.typeSections.length, + codeSize: this.codeSections.length, + dataSize: this.dataSection.length, + } + } + sectionSizes() { + return [ + this.typeSections.map(() => 4), + this.codeSections.map((b) => b.length), + this.dataSection.length, + ] + } +} + +/** + * Main constructor for the EOFContainer + */ +export class EOFContainer { + header: EOFHeader + body: EOFBody + buffer: Uint8Array + eofMode: EOFContainerMode + + /** + * + * @param buf Entire container buffer + * @param eofMode Container mode to validate the container on + * @param dataSectionAllowedSmaller `true` if the data section is allowed to be smaller than the data section size in the header + */ + constructor( + buf: Uint8Array, + eofMode: EOFContainerMode = EOFContainerMode.Default, + dataSectionAllowedSmaller = false + ) { + this.eofMode = eofMode + this.header = new EOFHeader(buf) + this.body = new EOFBody( + buf.slice(this.header.buffer.length), + this.header, + eofMode, + dataSectionAllowedSmaller + ) + this.buffer = buf + } +} + +/** + * This method validates the EOF. It also performs deeper validation of the body, such as stack/opcode validation + * This is ONLY necessary when trying to deploy contracts from a transaction: these can submit containers which are invalid + * Since all deployed EOF containers are valid by definition, `validateEOF` does not need to be called each time an EOF contract is called + * @param input Full container buffer + * @param evm EVM, to read opcodes from + * @param containerMode Container mode to validate on + * @param eofMode EOF mode to run in + * @returns + */ +export function validateEOF( + input: Uint8Array, + evm: EVM, + containerMode: ContainerSectionType = ContainerSectionType.RuntimeCode, + eofMode: EOFContainerMode = EOFContainerMode.Default +) { + const container = new EOFContainer( + input, + eofMode, + containerMode === ContainerSectionType.DeploymentCode + ) + const containerMap = verifyCode(container, evm, containerMode) + // Recursively validate the containerSections + for (let i = 0; i < container.body.containerSections.length; i++) { + const subContainer = container.body.containerSections[i] + const mode = containerMap.get(i)! + validateEOF(subContainer, evm, mode) + } + return container +} diff --git a/packages/evm/src/eof/errors.ts b/packages/evm/src/eof/errors.ts new file mode 100644 index 0000000000..2d3c3773ce --- /dev/null +++ b/packages/evm/src/eof/errors.ts @@ -0,0 +1,254 @@ +export enum EOFError { + // Stream Reader + OutOfBounds = 'Trying to read out of bounds', + VerifyUint = 'Uint does not match expected value ', + VerifyBytes = 'Bytes do not match expected value', + + // Section Markers + FORMAT = 'err: invalid format', + MAGIC = 'err: invalid magic', + VERSION = `err: invalid eof version`, + KIND_TYPE = `err: expected kind types`, + KIND_CODE = `err: expected kind code`, + KIND_DATA = `err: expected kind data`, + TERMINATOR = `err: expected terminator`, + + // Section Sizes + TypeSize = `missing type size`, + InvalidTypeSize = `err: type section size invalid`, + CodeSize = `missing code size`, + CodeSectionSize = `code section should be at least one byte`, + InvalidCodeSize = `code size does not match type size`, + DataSize = `missing data size`, + ContainerSize = 'missing container size', + ContainerSectionSize = 'container section should at least contain one section and at most 255 sections', + + // Type Section + TypeSections = `err: mismatch of code sections count and type signatures`, + Inputs = 'expected inputs', + Outputs = 'expected outputs', + MaxInputs = 'inputs exceeds 127, the maximum, got: ', + MaxOutputs = 'outputs exceeds 127, the maximum, got: ', + Code0Inputs = 'first code section should have 0 inputs', + Code0Outputs = 'first code section should have 0x80 (terminating section) outputs', + MaxStackHeight = `expected maxStackHeight`, + MaxStackHeightLimit = `stack height limit of 1024 exceeded: `, + + // Code/Data Section + MinCodeSections = `should have at least 1 code section`, + MaxCodeSections = `can have at most 1024 code sections`, + CodeSection = `expected a code section`, + DataSection = `Expected data section`, + + // Container section + ContainerSection = 'expected a container section', + ContainerSectionMin = 'container section should be at least 1 byte', + InvalidEOFCreateTarget = 'EOFCREATE targets an undefined container', + InvalidRETURNContractTarget = 'RETURNCONTRACT targets an undefined container', + ContainerDoubleType = 'Container is targeted by both EOFCREATE and RETURNCONTRACT', + UnreachableContainerSections = 'Unreachable containers (by both EOFCREATE and RETURNCONTRACT)', + ContainerTypeError = 'Container contains opcodes which this mode (deployment mode / init code / runtime mode) cannot have', + + // Dangling Bytes + DanglingBytes = 'got dangling bytes in body', + + // Code verifcation + InvalidOpcode = 'invalid opcode', + InvalidTerminator = 'invalid terminating opcode', + OpcodeIntermediatesOOB = 'invalid opcode: intermediates out-of-bounds', + + InvalidRJUMP = 'invalid rjump* target', + InvalidCallTarget = 'invalid callf/jumpf target', + InvalidCALLFReturning = 'invalid callf: calls to non-returning function', + InvalidStackHeight = 'invalid stack height', + InvalidJUMPF = 'invalid jumpf target (output count)', + InvalidReturningSection = 'invalid returning code section: section is not returning', + RJUMPVTableSize0 = 'invalid RJUMPV: table size 0', + UnreachableCodeSections = 'unreachable code sections', + UnreachableCode = 'unreachable code (by forward jumps)', + DataLoadNOutOfBounds = 'DATALOADN reading out of bounds', + MaxStackHeightViolation = 'Max stack height does not match the reported max stack height', + StackUnderflow = 'Stack underflow', + StackOverflow = 'Stack overflow', + UnstableStack = 'Unstable stack (can reach stack under/overflow by jumps)', + RetfNoReturn = 'Trying to return to undefined function', // This should never happen (this is a return stack underflow) + ReturnStackOverflow = 'Return stack overflow', + InvalidExtcallTarget = 'invalid extcall target: address > 20 bytes', + InvalidReturnContractDataSize = 'invalid RETURNCONTRACT: data size lower than expected', + + InvalidEofFormat = 'invalid EOF format', +} + +export enum SimpleErrors { + minContainerSize = 'err: container size less than minimum valid size', + invalidContainerSize = 'err: invalid container size', + typeSize = 'err: type section size invalid', + code0msh = 'err: computed max stack height for code section 0 does not match expect', + underflow = 'err: stack underflow', + code0IO = 'err: input and output of first code section must be 0', + + // Stream Reader + // OutOfBounds = 'err: relative offset out-of-bounds: ', + VerifyUint = 'Uint does not match expected value ', + VerifyBytes = 'Bytes do not match expected value', + + // Section Sizes + TypeSize = `missing type size`, + InvalidTypeSize = `err: type section invalid`, + CodeSize = `missing code size`, + CodeSectionSize = `code section should be at least one byte`, + InvalidCodeSize = `code size does not match type size`, + DataSize = `missing data size`, + + // Type Section + TypeSections = `need to have a type section for each code section`, + Inputs = 'expected inputs', + Outputs = 'expected outputs', + MaxInputs = 'inputs exceeds 127, the maximum, got: ', + MaxOutputs = 'outputs exceeds 127, the maximum, got: ', + Code0Inputs = 'first code section should have 0 inputs', + Code0Outputs = 'first code section should have 0 outputs', + MaxStackHeight = `expected maxStackHeight`, + MaxStackHeightLimit = `stack height limit of 1024 exceeded: `, + + // Code/Data Section + MinCodeSections = `should have at least 1 code section`, + MaxCodeSections = `can have at most 1024 code sections`, + CodeSection = `expected a code section`, + DataSection = `Expected data section`, + + // Dangling Bytes + DanglingBytes = 'got dangling bytes in body', +} + +export function validationErrorMsg(type: EOFError, ...args: any) { + switch (type) { + case EOFError.OutOfBounds: { + return EOFError.OutOfBounds + ` at pos: ${args[0]}: ${args[1]}` + } + case EOFError.VerifyBytes: { + return EOFError.VerifyBytes + ` at pos: ${args[0]}: ${args[1]}` + } + case EOFError.VerifyUint: { + return EOFError.VerifyUint + `at pos: ${args[0]}: ${args[1]}` + } + case EOFError.TypeSize: { + return EOFError.TypeSize + args[0] + } + case EOFError.InvalidTypeSize: { + return EOFError.InvalidTypeSize + args[0] + } + case EOFError.InvalidCodeSize: { + return EOFError.InvalidCodeSize + args[0] + } + case EOFError.Inputs: { + return `${EOFError.Inputs} - typeSection ${args[0]}` + } + case EOFError.Outputs: { + return `${EOFError.Outputs} - typeSection ${args[0]}` + } + case EOFError.Code0Inputs: { + return `first code section should have 0 inputs` + } + case EOFError.Code0Outputs: { + return `first code section should have 0 outputs` + } + case EOFError.MaxInputs: { + return EOFError.MaxInputs + `${args[1]} - code section ${args[0]}` + } + case EOFError.MaxOutputs: { + return EOFError.MaxOutputs + `${args[1]} - code section ${args[0]}` + } + case EOFError.CodeSection: { + return `expected code: codeSection ${args[0]}: ` + } + case EOFError.DataSection: { + return EOFError.DataSection + } + case EOFError.MaxStackHeight: { + return `${EOFError.MaxStackHeight} - typeSection ${args[0]}: ` + } + case EOFError.MaxStackHeightLimit: { + return `${EOFError.MaxStackHeightLimit}, got: ${args[1]} - typeSection ${args[0]}` + } + case EOFError.DanglingBytes: { + return EOFError.DanglingBytes + } + default: { + return type + } + } +} +export function validationError(type: EOFError, ...args: any): never { + switch (type) { + case EOFError.OutOfBounds: { + const pos = args[0] + if (pos === 0 || pos === 2 || pos === 3 || pos === 6) { + throw new Error(args[1]) + } + throw new Error(EOFError.OutOfBounds + ` `) + } + case EOFError.VerifyBytes: { + const pos = args[0] + if (pos === 0 || pos === 2 || pos === 3 || pos === 6) { + throw new Error(args[1]) + } + throw new Error(EOFError.VerifyBytes + ` at pos: ${args[0]}: ${args[1]}`) + } + case EOFError.VerifyUint: { + const pos = args[0] + if (pos === 0 || pos === 2 || pos === 3 || pos === 6 || pos === 18) { + throw new Error(args[1]) + } + throw new Error(EOFError.VerifyUint + `at pos: ${args[0]}: ${args[1]}`) + } + case EOFError.TypeSize: { + throw new Error(EOFError.TypeSize + args[0]) + } + case EOFError.TypeSections: { + throw new Error(`${EOFError.TypeSections} (types ${args[0]} code ${args[1]})`) + } + case EOFError.InvalidTypeSize: { + throw new Error(EOFError.InvalidTypeSize) + } + case EOFError.InvalidCodeSize: { + throw new Error(EOFError.InvalidCodeSize + args[0]) + } + case EOFError.Inputs: { + throw new Error(`${EOFError.Inputs} - typeSection ${args[0]}`) + } + case EOFError.Outputs: { + throw new Error(`${EOFError.Outputs} - typeSection ${args[0]}`) + } + case EOFError.Code0Inputs: { + throw new Error(`first code section should have 0 inputs`) + } + case EOFError.Code0Outputs: { + throw new Error(`first code section should have 0 outputs`) + } + case EOFError.MaxInputs: { + throw new Error(EOFError.MaxInputs + `${args[1]} - code section ${args[0]}`) + } + case EOFError.MaxOutputs: { + throw new Error(EOFError.MaxOutputs + `${args[1]} - code section ${args[0]}`) + } + case EOFError.CodeSection: { + throw new Error(`expected code: codeSection ${args[0]}: `) + } + case EOFError.DataSection: { + throw new Error(EOFError.DataSection) + } + case EOFError.MaxStackHeight: { + throw new Error(`${EOFError.MaxStackHeight} - typeSection ${args[0]}: `) + } + case EOFError.MaxStackHeightLimit: { + throw new Error(`${EOFError.MaxStackHeightLimit}, got: ${args[1]} - typeSection ${args[0]}`) + } + case EOFError.DanglingBytes: { + throw new Error(EOFError.DanglingBytes) + } + default: { + throw new Error(type) + } + } +} diff --git a/packages/evm/src/eof/setup.ts b/packages/evm/src/eof/setup.ts new file mode 100644 index 0000000000..6d977ecfb3 --- /dev/null +++ b/packages/evm/src/eof/setup.ts @@ -0,0 +1,27 @@ +import { EOFContainer, EOFContainerMode } from './container.js' + +import type { RunState } from '../interpreter.js' + +/** + * This method setups the EOF inside the EVM. It prepares the `RunState` to start running EVM in EOF mode + * @param runState Current run state + * @param eofMode EOF mode to run in (only changes in case of EOFCREATE) + */ +export function setupEOF(runState: RunState, eofMode: EOFContainerMode = EOFContainerMode.Default) { + runState.env.eof = { + container: new EOFContainer(runState.code, eofMode), + eofRunState: { + returnStack: [], // Return stack for RETF/CALLF/JUMPF + }, + } + + // In case that txCallData is set, then set the `callData` of the `env` to this calldata + // This ensures that CALLDATA can be read when deploying EOF contracts using transactions + if (runState.env.eof.container.body.txCallData !== undefined) { + runState.env.callData = runState.env.eof.container.body.txCallData + } + + // Set the program counter to the first code section + const pc = runState.env.eof.container.header.getCodePosition(0) + runState.programCounter = pc +} diff --git a/packages/evm/src/eof/stackDelta.ts b/packages/evm/src/eof/stackDelta.ts new file mode 100644 index 0000000000..70b37ecb93 --- /dev/null +++ b/packages/evm/src/eof/stackDelta.ts @@ -0,0 +1,168 @@ +// Generated using a script, which can be found in ./evm/scripts/stackDeltaGenerator.ts + +export const stackDelta: { + [key: number]: { + inputs: number // Number of inputs to this operation + outputs: number // Number of outputs after this operation + name: string // Name of the opcode + intermediates: number // Intermediate bytes (such as 2 intermediates after a PUSH2) + terminating?: boolean // Marks the opcode as terminating. This opcode will exit the current CALL frame. (Such as STOP/RETURN) + } +} = { + 0x00: { inputs: 0, outputs: 0, name: 'STOP', intermediates: 0, terminating: true }, + 0x01: { inputs: 2, outputs: 1, name: 'ADD', intermediates: 0 }, + 0x02: { inputs: 2, outputs: 1, name: 'MUL', intermediates: 0 }, + 0x03: { inputs: 2, outputs: 1, name: 'SUB', intermediates: 0 }, + 0x04: { inputs: 2, outputs: 1, name: 'DIV', intermediates: 0 }, + 0x05: { inputs: 2, outputs: 1, name: 'SDIV', intermediates: 0 }, + 0x06: { inputs: 2, outputs: 1, name: 'MOD', intermediates: 0 }, + 0x07: { inputs: 2, outputs: 1, name: 'SMOD', intermediates: 0 }, + 0x08: { inputs: 3, outputs: 1, name: 'ADDMOD', intermediates: 0 }, + 0x09: { inputs: 3, outputs: 1, name: 'MULMOD', intermediates: 0 }, + 0x0a: { inputs: 2, outputs: 1, name: 'EXP', intermediates: 0 }, + 0x0b: { inputs: 2, outputs: 1, name: 'SIGNEXTEND', intermediates: 0 }, + 0x10: { inputs: 2, outputs: 1, name: 'LT', intermediates: 0 }, + 0x11: { inputs: 2, outputs: 1, name: 'GT', intermediates: 0 }, + 0x12: { inputs: 2, outputs: 1, name: 'SLT', intermediates: 0 }, + 0x13: { inputs: 2, outputs: 1, name: 'SGT', intermediates: 0 }, + 0x14: { inputs: 2, outputs: 1, name: 'EQ', intermediates: 0 }, + 0x15: { inputs: 1, outputs: 1, name: 'ISZERO', intermediates: 0 }, + 0x16: { inputs: 2, outputs: 1, name: 'AND', intermediates: 0 }, + 0x17: { inputs: 2, outputs: 1, name: 'OR', intermediates: 0 }, + 0x18: { inputs: 2, outputs: 1, name: 'XOR', intermediates: 0 }, + 0x19: { inputs: 1, outputs: 1, name: 'NOT', intermediates: 0 }, + 0x1a: { inputs: 2, outputs: 1, name: 'BYTE', intermediates: 0 }, + 0x1b: { inputs: 2, outputs: 1, name: 'SHL', intermediates: 0 }, + 0x1c: { inputs: 2, outputs: 1, name: 'SHR', intermediates: 0 }, + 0x1d: { inputs: 2, outputs: 1, name: 'SAR', intermediates: 0 }, + 0x20: { inputs: 2, outputs: 1, name: 'SHA3', intermediates: 0 }, + 0x30: { inputs: 0, outputs: 1, name: 'ADDRESS', intermediates: 0 }, + 0x31: { inputs: 1, outputs: 1, name: 'BALANCE', intermediates: 0 }, + 0x32: { inputs: 0, outputs: 1, name: 'ORIGIN', intermediates: 0 }, + 0x33: { inputs: 0, outputs: 1, name: 'CALLER', intermediates: 0 }, + 0x34: { inputs: 0, outputs: 1, name: 'CALLVALUE', intermediates: 0 }, + 0x35: { inputs: 1, outputs: 1, name: 'CALLDATALOAD', intermediates: 0 }, + 0x36: { inputs: 0, outputs: 1, name: 'CALLDATASIZE', intermediates: 0 }, + 0x37: { inputs: 3, outputs: 0, name: 'CALLDATACOPY', intermediates: 0 }, + 0x3a: { inputs: 0, outputs: 1, name: 'GASPRICE', intermediates: 0 }, + 0x3d: { inputs: 0, outputs: 1, name: 'RETURNDATASIZE', intermediates: 0 }, + 0x3e: { inputs: 3, outputs: 0, name: 'RETURNDATACOPY', intermediates: 0 }, + 0x40: { inputs: 1, outputs: 1, name: 'BLOCKHASH', intermediates: 0 }, + 0x41: { inputs: 0, outputs: 1, name: 'COINBASE', intermediates: 0 }, + 0x42: { inputs: 0, outputs: 1, name: 'TIMESTAMP', intermediates: 0 }, + 0x43: { inputs: 0, outputs: 1, name: 'NUMBER', intermediates: 0 }, + 0x44: { inputs: 0, outputs: 1, name: 'PREVRANDAO', intermediates: 0 }, + 0x45: { inputs: 0, outputs: 1, name: 'GASLIMIT', intermediates: 0 }, + 0x46: { inputs: 0, outputs: 1, name: 'CHAINID', intermediates: 0 }, + 0x47: { inputs: 0, outputs: 1, name: 'SELFBALANCE', intermediates: 0 }, + 0x48: { inputs: 0, outputs: 1, name: 'BASEFEE', intermediates: 0 }, + 0x49: { inputs: 1, outputs: 1, name: 'BLOBAHASH', intermediates: 0 }, + 0x4a: { inputs: 0, outputs: 1, name: 'BLOBBASEFEE', intermediates: 0 }, + 0x50: { inputs: 1, outputs: 0, name: 'POP', intermediates: 0 }, + 0x51: { inputs: 1, outputs: 1, name: 'MLOAD', intermediates: 0 }, + 0x52: { inputs: 2, outputs: 0, name: 'MSTORE', intermediates: 0 }, + 0x53: { inputs: 2, outputs: 0, name: 'MSTORE8', intermediates: 0 }, + 0x54: { inputs: 1, outputs: 1, name: 'SLOAD', intermediates: 0 }, + 0x55: { inputs: 2, outputs: 0, name: 'SSTORE', intermediates: 0 }, + 0x59: { inputs: 0, outputs: 1, name: 'MSIZE', intermediates: 0 }, + 0x5b: { inputs: 0, outputs: 0, name: 'NOOP', intermediates: 0 }, + 0x5c: { inputs: 1, outputs: 1, name: 'TLOAD', intermediates: 0 }, + 0x5d: { inputs: 2, outputs: 0, name: 'TSTORE', intermediates: 0 }, + 0x5e: { inputs: 3, outputs: 0, name: 'MCOPY', intermediates: 0 }, + 0x5f: { inputs: 0, outputs: 1, name: 'PUSH0', intermediates: 0 }, + 0x60: { inputs: 0, outputs: 1, name: 'PUSH1', intermediates: 1 }, + 0x61: { inputs: 0, outputs: 1, name: 'PUSH2', intermediates: 2 }, + 0x62: { inputs: 0, outputs: 1, name: 'PUSH3', intermediates: 3 }, + 0x63: { inputs: 0, outputs: 1, name: 'PUSH4', intermediates: 4 }, + 0x64: { inputs: 0, outputs: 1, name: 'PUSH5', intermediates: 5 }, + 0x65: { inputs: 0, outputs: 1, name: 'PUSH6', intermediates: 6 }, + 0x66: { inputs: 0, outputs: 1, name: 'PUSH7', intermediates: 7 }, + 0x67: { inputs: 0, outputs: 1, name: 'PUSH8', intermediates: 8 }, + 0x68: { inputs: 0, outputs: 1, name: 'PUSH9', intermediates: 9 }, + 0x69: { inputs: 0, outputs: 1, name: 'PUSH10', intermediates: 10 }, + 0x6a: { inputs: 0, outputs: 1, name: 'PUSH11', intermediates: 11 }, + 0x6b: { inputs: 0, outputs: 1, name: 'PUSH12', intermediates: 12 }, + 0x6c: { inputs: 0, outputs: 1, name: 'PUSH13', intermediates: 13 }, + 0x6d: { inputs: 0, outputs: 1, name: 'PUSH14', intermediates: 14 }, + 0x6e: { inputs: 0, outputs: 1, name: 'PUSH15', intermediates: 15 }, + 0x6f: { inputs: 0, outputs: 1, name: 'PUSH16', intermediates: 16 }, + 0x70: { inputs: 0, outputs: 1, name: 'PUSH17', intermediates: 17 }, + 0x71: { inputs: 0, outputs: 1, name: 'PUSH18', intermediates: 18 }, + 0x72: { inputs: 0, outputs: 1, name: 'PUSH19', intermediates: 19 }, + 0x73: { inputs: 0, outputs: 1, name: 'PUSH20', intermediates: 20 }, + 0x74: { inputs: 0, outputs: 1, name: 'PUSH21', intermediates: 21 }, + 0x75: { inputs: 0, outputs: 1, name: 'PUSH22', intermediates: 22 }, + 0x76: { inputs: 0, outputs: 1, name: 'PUSH23', intermediates: 23 }, + 0x77: { inputs: 0, outputs: 1, name: 'PUSH24', intermediates: 24 }, + 0x78: { inputs: 0, outputs: 1, name: 'PUSH25', intermediates: 25 }, + 0x79: { inputs: 0, outputs: 1, name: 'PUSH26', intermediates: 26 }, + 0x7a: { inputs: 0, outputs: 1, name: 'PUSH27', intermediates: 27 }, + 0x7b: { inputs: 0, outputs: 1, name: 'PUSH28', intermediates: 28 }, + 0x7c: { inputs: 0, outputs: 1, name: 'PUSH29', intermediates: 29 }, + 0x7d: { inputs: 0, outputs: 1, name: 'PUSH30', intermediates: 30 }, + 0x7e: { inputs: 0, outputs: 1, name: 'PUSH31', intermediates: 31 }, + 0x7f: { inputs: 0, outputs: 1, name: 'PUSH32', intermediates: 32 }, + 0x80: { inputs: 1, outputs: 2, name: 'DUP1', intermediates: 0 }, + 0x81: { inputs: 2, outputs: 3, name: 'DUP2', intermediates: 0 }, + 0x82: { inputs: 3, outputs: 4, name: 'DUP3', intermediates: 0 }, + 0x83: { inputs: 4, outputs: 5, name: 'DUP4', intermediates: 0 }, + 0x84: { inputs: 5, outputs: 6, name: 'DUP5', intermediates: 0 }, + 0x85: { inputs: 6, outputs: 7, name: 'DUP6', intermediates: 0 }, + 0x86: { inputs: 7, outputs: 8, name: 'DUP7', intermediates: 0 }, + 0x87: { inputs: 8, outputs: 9, name: 'DUP8', intermediates: 0 }, + 0x88: { inputs: 9, outputs: 10, name: 'DUP9', intermediates: 0 }, + 0x89: { inputs: 10, outputs: 11, name: 'DUP10', intermediates: 0 }, + 0x8a: { inputs: 11, outputs: 12, name: 'DUP11', intermediates: 0 }, + 0x8b: { inputs: 12, outputs: 13, name: 'DUP12', intermediates: 0 }, + 0x8c: { inputs: 13, outputs: 14, name: 'DUP13', intermediates: 0 }, + 0x8d: { inputs: 14, outputs: 15, name: 'DUP14', intermediates: 0 }, + 0x8e: { inputs: 15, outputs: 16, name: 'DUP15', intermediates: 0 }, + 0x8f: { inputs: 16, outputs: 17, name: 'DUP16', intermediates: 0 }, + 0x90: { inputs: 2, outputs: 2, name: 'SWAP1', intermediates: 0 }, + 0x91: { inputs: 3, outputs: 3, name: 'SWAP2', intermediates: 0 }, + 0x92: { inputs: 4, outputs: 4, name: 'SWAP3', intermediates: 0 }, + 0x93: { inputs: 5, outputs: 5, name: 'SWAP4', intermediates: 0 }, + 0x94: { inputs: 6, outputs: 6, name: 'SWAP5', intermediates: 0 }, + 0x95: { inputs: 7, outputs: 7, name: 'SWAP6', intermediates: 0 }, + 0x96: { inputs: 8, outputs: 8, name: 'SWAP7', intermediates: 0 }, + 0x97: { inputs: 9, outputs: 9, name: 'SWAP8', intermediates: 0 }, + 0x98: { inputs: 10, outputs: 10, name: 'SWAP9', intermediates: 0 }, + 0x99: { inputs: 11, outputs: 11, name: 'SWAP10', intermediates: 0 }, + 0x9a: { inputs: 12, outputs: 12, name: 'SWAP11', intermediates: 0 }, + 0x9b: { inputs: 13, outputs: 13, name: 'SWAP12', intermediates: 0 }, + 0x9c: { inputs: 14, outputs: 14, name: 'SWAP13', intermediates: 0 }, + 0x9d: { inputs: 15, outputs: 15, name: 'SWAP14', intermediates: 0 }, + 0x9e: { inputs: 16, outputs: 16, name: 'SWAP15', intermediates: 0 }, + 0x9f: { inputs: 17, outputs: 17, name: 'SWAP16', intermediates: 0 }, + 0xa0: { inputs: 2, outputs: 0, name: 'LOG0', intermediates: 0 }, + 0xa1: { inputs: 3, outputs: 0, name: 'LOG1', intermediates: 0 }, + 0xa2: { inputs: 4, outputs: 0, name: 'LOG2', intermediates: 0 }, + 0xa3: { inputs: 5, outputs: 0, name: 'LOG3', intermediates: 0 }, + 0xa4: { inputs: 6, outputs: 0, name: 'LOG4', intermediates: 0 }, + 0xd0: { inputs: 1, outputs: 1, name: 'DATALOAD', intermediates: 0 }, + 0xd1: { inputs: 0, outputs: 1, name: 'DATALOADN', intermediates: 2 }, + 0xd2: { inputs: 0, outputs: 1, name: 'DATASIZE', intermediates: 0 }, + 0xd3: { inputs: 3, outputs: 0, name: 'DATACOPY', intermediates: 0 }, + 0xe0: { inputs: 0, outputs: 0, name: 'RJUMP', intermediates: 2 }, + 0xe1: { inputs: 1, outputs: 0, name: 'RJUMPI', intermediates: 2 }, + // NOTE: for RJUMPV the intermediate byte is set to 0, this has to do with the validation algorithm specifics + // This has to do with the dynamic intermediate size of RJUMPV, which depends upon the table size byte right after RJUMPV + 0xe2: { inputs: 1, outputs: 0, name: 'RJUMPV', intermediates: 0 }, + // CALLF special case for stack validation algorithm: the inputs and outputs MUST stay 0 + // (this is currently the case also in EVM) + 0xe3: { inputs: 0, outputs: 0, name: 'CALLF', intermediates: 2 }, + 0xe4: { inputs: 0, outputs: 0, name: 'RETF', intermediates: 0, terminating: true }, + 0xe5: { inputs: 0, outputs: 0, name: 'JUMPF', intermediates: 2, terminating: true }, + 0xe6: { inputs: 0, outputs: 1, name: 'DUPN', intermediates: 1 }, + 0xe7: { inputs: 0, outputs: 0, name: 'SWAPN', intermediates: 1 }, + 0xe8: { inputs: 0, outputs: 0, name: 'EXCHANGE', intermediates: 1 }, + 0xec: { inputs: 4, outputs: 1, name: 'EOFCREATE', intermediates: 1 }, + 0xee: { inputs: 2, outputs: 0, name: 'RETURNCONTRACT', intermediates: 1, terminating: true }, + 0xf3: { inputs: 2, outputs: 0, name: 'RETURN', intermediates: 0, terminating: true }, + 0xf7: { inputs: 1, outputs: 1, name: 'RETURNDATALOAD', intermediates: 0 }, + 0xf8: { inputs: 4, outputs: 1, name: 'EXTCALL', intermediates: 0 }, + 0xf9: { inputs: 3, outputs: 1, name: 'EXTDELEGATECALL', intermediates: 0 }, + 0xfb: { inputs: 3, outputs: 1, name: 'EXTSTATICCALL', intermediates: 0 }, + 0xfd: { inputs: 2, outputs: 0, name: 'REVERT', intermediates: 0, terminating: true }, + 0xfe: { inputs: 0, outputs: 0, name: 'INVALID', intermediates: 0, terminating: true }, +} diff --git a/packages/evm/src/eof/util.ts b/packages/evm/src/eof/util.ts new file mode 100644 index 0000000000..b28a5943e0 --- /dev/null +++ b/packages/evm/src/eof/util.ts @@ -0,0 +1,16 @@ +import { keccak256 } from 'ethereum-cryptography/keccak.js' +import { equalsBytes } from 'ethereum-cryptography/utils' + +import { FORMAT, MAGIC } from './constants.js' + +export const EOFBYTES = new Uint8Array([FORMAT, MAGIC]) +export const EOFHASH = keccak256(EOFBYTES) + +/** + * Returns `true` if `code` is an EOF contract, returns `false` otherwise + * @param code Code to test if it is EOF + */ +export function isEOF(code: Uint8Array): boolean { + const check = code.subarray(0, EOFBYTES.length) + return equalsBytes(EOFBYTES, check) +} diff --git a/packages/evm/src/eof/verify.ts b/packages/evm/src/eof/verify.ts new file mode 100644 index 0000000000..00537f1eb0 --- /dev/null +++ b/packages/evm/src/eof/verify.ts @@ -0,0 +1,519 @@ +import { EOFError, validationError } from './errors.js' +import { stackDelta } from './stackDelta.js' + +import type { EVM } from '../evm.js' +import type { EOFContainer } from './container.js' + +/** + * Note for reviewers regarding these flags: these only reside inside `verify.ts` (this file) + * and `container.ts`. For `container.ts`, the only behavior which ever changes is in the `DeploymentCode` mode + * This `DeploymentCode` mode means that the subcontainer is flagged in such way that this container is launched + * in a "deployment" mode. This means, that the data section of the body is actually allowed to contain + * less data than is written in the header. However, once the target container (by the container in deployment) + * mode is returned by RETURNCONTRACT it should have at least the header amount of data. + * See also "data section lifecycle" + * Note: the subcontainers of a container can be marked "InitCode" or "DeploymentCode". + * InitCode cannot contain the instructions RETURN / STOP + * InitCode is the only container type which can contain RETURNCONTRACT + * A container can also be marked DeploymentCode, this is a subcontainer targeted by RETURNCONTRACT + * A container cannot be marked both InitCode and DeploymentCode + * This flag is thus to distinguish between subcontainers, and also thus also allows for data section sizes + * lower than the size in the header in case of `InitCode` + */ +export enum ContainerSectionType { + InitCode, // Targeted by EOFCreate + DeploymentCode, // Targeted by RETURNCONTRACT + RuntimeCode, // "Default" runtime code +} + +/** + * This method validates an EOF container deeply. It will validate the opcodes, validate the stack, and performs + * various checks such as checking for forbidden opcodes in certain modes, jumps to invalid places, etc. + * For more information, see "Code validation" of https://github.com/ipsilon/eof/blob/main/spec/eof.md + * This is a compilation of all the extra validation rules introduced by the various EIPs + * In particular, the stack validation EIP https://eips.ethereum.org/EIPS/eip-5450 is a big part here + * @param container EOFContainer to verify + * @param evm The EVM to run in (pulls opcodes from here) + * @param mode The validation mode to run in + * @returns Returns a Map which marks what ContainerSectionType each container is + * NOTE: this should likely not be a map, since a container section can only be of a single type, not multiple + */ +export function verifyCode( + container: EOFContainer, + evm: EVM, + mode: ContainerSectionType = ContainerSectionType.RuntimeCode +) { + return validateOpcodes(container, evm, mode) +} + +// Helper methods to read Int16s / Uint16s +function readInt16(code: Uint8Array, start: number) { + return new DataView(code.buffer).getInt16(start) +} + +function readUint16(code: Uint8Array, start: number) { + return new DataView(code.buffer).getUint16(start) +} + +function validateOpcodes( + container: EOFContainer, + evm: EVM, + mode: ContainerSectionType = ContainerSectionType.RuntimeCode +) { + // Track the intermediate bytes + const intermediateBytes = new Set() + // Track the jump locations (for forward jumps it is unknown at the first pass if the byte is intermediate) + const jumpLocations = new Set() + + // Track the type of the container targets + // Should at the end of the analysis have all the containers + const containerTypeMap = new Map() + + function addJump(location: number) { + if (intermediateBytes.has(location)) { + // When trying to JUMP into an intermediate byte: this is invalid + validationError(EOFError.InvalidRJUMP) + } + jumpLocations.add(location) + } + + function addIntermediate(location: number) { + if (jumpLocations.has(location)) { + // When trying to add an intermediate to a location already JUMPed to: this is invalid + validationError(EOFError.InvalidRJUMP) + } + intermediateBytes.add(location) + } + + // TODO (?) -> stackDelta currently only has active EOF opcodes, can use it directly (?) + // (so no need to generate the valid opcodeNumbers) + + // Validate each code section + const opcodes = evm.getActiveOpcodes() + + const opcodeNumbers = new Set() + + for (const [key] of opcodes) { + opcodeNumbers.add(key) + } + + // Add INVALID as valid + opcodeNumbers.add(0xfe) + + // Remove CODESIZE, CODECOPY, EXTCODESIZE, EXTCODECOPY, EXTCODEHASH, GAS + opcodeNumbers.delete(0x38) + opcodeNumbers.delete(0x39) + opcodeNumbers.delete(0x5a) + opcodeNumbers.delete(0x3b) + opcodeNumbers.delete(0x3c) + opcodeNumbers.delete(0x3f) + + // Remove CALLCODE and SELFDESTRUCT + opcodeNumbers.delete(0xf2) + opcodeNumbers.delete(0xff) + + // TODO omnibus https://github.com/ipsilon/eof/blob/main/spec/eof.md states + // JUMP / JUMPI / PC / CREATE / CREATE2 also banned + // This is not in the EIPs yet + // Add these opcodes here + + opcodeNumbers.delete(0x56) // JUMP + opcodeNumbers.delete(0x57) // JUMPI + + opcodeNumbers.delete(0x58) // PC + + opcodeNumbers.delete(0xf0) // CREATE + opcodeNumbers.delete(0xf5) // CREATE2 + + // Note: this name might be misleading since this is the list of opcodes which are OK as final opcodes in a code section + // TODO if using stackDelta for EOF it is possible to add a "termination" boolean for the opcode to mark it as terminating + // (so no need to generate this set here) + const terminatingOpcodes = new Set() + + terminatingOpcodes.add(0x00) // STOP + terminatingOpcodes.add(0xf3) // RETURN + terminatingOpcodes.add(0xfd) // REVERT + terminatingOpcodes.add(0xfe) // INVALID + + terminatingOpcodes.add(0xee) // RETURNCONTRACT + + terminatingOpcodes.add(0xe4) // RETF + terminatingOpcodes.add(0xe5) // JUMPF + + terminatingOpcodes.add(0xe0) // RJUMPing back into code section is OK + + for (const opcode of terminatingOpcodes) { + if (!opcodeNumbers.has(opcode)) { + terminatingOpcodes.delete(opcode) + } + } + + const validJumps = new Set() + + // Add all reachable code sections + const reachableSections: { [key: number]: Set } = {} + + let codeSection = -1 + for (const code of container.body.codeSections) { + codeSection++ + + reachableSections[codeSection] = new Set() + + const returningFunction = container.body.typeSections[codeSection].outputs === 0x80 + + // Tracking set of reachable opcodes + const reachableOpcodes = new Set() + reachableOpcodes.add(0) + + // Validate that each opcode is defined + let ptr = 0 + let lastOpcode: number = 0 // Note: code sections cannot be empty, so this number will always be set + + // Implement the EIP 5450 stack validation algorithm + const inputs = container.body.typeSections[codeSection].inputs + let maxStackHeight = inputs + // These arrays track the min/max stack height **before** executing the instruction + const stackHeightMin: number[] = [inputs] + const stackHeightMax: number[] = [inputs] + + // This loop will loop over the entire code section and will validate various rules + // For (most) validation rules, see https://github.com/ipsilon/eof/blob/main/spec/eof.md + // For all validation rules per opcode, find the corresponding EIP, the rules are there + while (ptr < code.length) { + // This set tracks the successor opcodes of this opcode (for stack purposes) + const successorSet = new Set() + + // ReachableOpcodes: this can likely be deleted after implementing the 5450 algorithm + if (!reachableOpcodes.has(ptr)) { + validationError(EOFError.UnreachableCode) + } + + if (stackHeightMin[ptr] === undefined || stackHeightMax[ptr] === undefined) { + // This error either means that the code is unreachable, + // or it is possible that it is only reachable via a backwards jump + validationError(EOFError.UnreachableCode) + } + + validJumps.add(ptr) + const opcode = code[ptr] + + const minStackCurrent = stackHeightMin[ptr] + const maxStackCurrent = stackHeightMax[ptr] + + const opcodeInputs = stackDelta[opcode].inputs + const opcodeOutputs = stackDelta[opcode].outputs + + if (minStackCurrent - opcodeInputs < 0) { + validationError(EOFError.StackUnderflow) + } + + const delta = opcodeOutputs - opcodeInputs + + let minStackNext = minStackCurrent + delta + let maxStackNext = maxStackCurrent + delta + + if (maxStackNext > 1023) { + // TODO verify if 1023 or 1024 is the right constant + validationError(EOFError.StackOverflow) + } + + if (returningFunction && opcode === 0xe4) { + validationError(EOFError.InvalidReturningSection) + } + + lastOpcode = opcode + if (!opcodeNumbers.has(opcode)) { + validationError(EOFError.InvalidOpcode) + } + + if (opcode === 0xe0 || opcode === 0xe1) { + // RJUMP / RJUMPI + const target = readInt16(code, ptr + 1) + ptr + 3 + if (target < 0 || target >= code.length) { + validationError(EOFError.InvalidRJUMP) + } + + successorSet.add(target) + + addJump(target) + reachableOpcodes.add(target) + + if (opcode === 0xe0) { + // For RJUMP check that the instruction after RJUMP is reachable + // If this is not the case, then it is not yet targeted by a forward jump + // And hence violates the spec + if (!reachableOpcodes.has(ptr + 3) && ptr + 3 < code.length) { + // Note: the final condition above ensures that the bytes after ptr are there + // This is an edge case, if the container ends with RJUMP (which is valid) + validationError(EOFError.UnreachableCode) + } + } + } else if (opcode === 0xe2) { + // RJUMPV + const tableSize = code[ptr + 1] + 1 + + if (tableSize === undefined) { + validationError(EOFError.OpcodeIntermediatesOOB) + } else if (tableSize === 0) { + validationError(EOFError.RJUMPVTableSize0) + } + + if (ptr + tableSize * 2 + 2 >= code.length) { + // Fall-through case + validationError(EOFError.OpcodeIntermediatesOOB) + } + + const newPc = ptr + 2 + tableSize * 2 + + for (let i = 0; i < tableSize; i++) { + const newPtr = ptr + 2 + i * 2 + // Add the table bytes to intermediates + addIntermediate(newPtr) + addIntermediate(newPtr + 1) + const target = readInt16(code, newPtr) + newPc + if (target < 0 || target >= code.length) { + validationError(EOFError.OpcodeIntermediatesOOB) + } + + successorSet.add(target) + + addJump(target) + reachableOpcodes.add(target) + } + + // Special case for RJUMPV: move ptr over the table (the immediate starting byte will be added later) + // In this special case, add the immediate starting byte + addIntermediate(ptr + 1) + ptr += 2 * tableSize + 1 + } else if (opcode === 0xe3 || opcode === 0xe5) { + // CALLF / JUMPF + const target = readUint16(code, ptr + 1) + reachableSections[codeSection].add(target) + if (target >= container.header.codeSizes.length) { + validationError(EOFError.InvalidCallTarget) + } + if (opcode === 0xe3) { + // CALLF + const targetOutputs = container.body.typeSections[target].outputs + const targetInputs = container.body.typeSections[target].inputs + if (targetOutputs === 0x80) { + // CALLF points to non-returning function which is not allowed + validationError(EOFError.InvalidCALLFReturning) + } + + if (minStackCurrent < targetInputs) { + validationError(EOFError.StackUnderflow) + } + + if ( + maxStackCurrent + container.body.typeSections[target].maxStackHeight - targetInputs > + 1024 + ) { + validationError(EOFError.StackOverflow) + } + + minStackNext += targetOutputs - targetInputs + maxStackNext += targetOutputs - targetInputs + } else { + // JUMPF + const currentOutputs = container.body.typeSections[codeSection].outputs + const targetOutputs = container.body.typeSections[target].outputs + const targetInputs = container.body.typeSections[target].inputs + const targetNonReturning = targetOutputs === 0x80 + + if (targetOutputs > currentOutputs && !targetNonReturning) { + // Spec rule: + // JUMPF operand must point to a code section with equal or fewer number of outputs as + // the section in which it resides, or to a section with 0x80 as outputs (non-returning) + validationError(EOFError.InvalidJUMPF) + } + + if (returningFunction && targetOutputs <= 0x7f) { + // Current function is returning, but target is not, cannot jump into this + validationError(EOFError.InvalidReturningSection) + } + + if (targetNonReturning) { + // Target is returning + if (minStackCurrent < targetInputs) { + validationError(EOFError.StackUnderflow) + } + } else { + // Target is returning + const expectedStack = currentOutputs + targetInputs - targetOutputs + if (!(minStackCurrent === maxStackCurrent && maxStackCurrent === expectedStack)) { + validationError(EOFError.InvalidStackHeight) + } + } + if ( + maxStackCurrent + container.body.typeSections[target].maxStackHeight - targetInputs > + 1024 + ) { + //console.log(maxStackCurrent, targetOutputs, targetInputs, targetNonReturning) + validationError(EOFError.StackOverflow) + } + } + } else if (opcode === 0xe4) { + // RETF + // Stack height must match the outputs of current code section + const outputs = container.body.typeSections[codeSection].outputs + if (!(minStackCurrent === maxStackCurrent && maxStackCurrent === outputs)) { + validationError(EOFError.InvalidStackHeight) + } + } else if (opcode === 0xe6) { + // DUPN + const toDup = code[ptr + 1] + if (toDup + 1 > minStackCurrent) { + validationError(EOFError.StackUnderflow) + } + } else if (opcode === 0xe7) { + // SWAPN + const toSwap = code[ptr + 1] + // TODO: EVMONEs test wants this to be `toSwap + 2`, but that seems to be incorrect + // Will keep `toSwap + 1` for now + if (toSwap + 1 > minStackCurrent) { + validationError(EOFError.StackUnderflow) + } + } else if (opcode === 0xe8) { + // EXCHANGE + const exchangeRaw = code[ptr + 1] + const n = (exchangeRaw >> 4) + 1 + const m = (exchangeRaw & 0x0f) + 1 + if (n + m + 1 > minStackCurrent) { + validationError(EOFError.StackUnderflow) + } + } else if (opcode === 0xec) { + // EOFCREATE + const target = code[ptr + 1] + if (target >= container.header.containerSizes.length) { + validationError(EOFError.InvalidEOFCreateTarget) + } + if (containerTypeMap.has(target)) { + if (containerTypeMap.get(target) !== ContainerSectionType.InitCode) { + validationError(EOFError.ContainerDoubleType) + } + } + containerTypeMap.set(target, ContainerSectionType.InitCode) + } else if (opcode === 0xee) { + // RETURNCONTRACT + + if (mode !== ContainerSectionType.InitCode) { + validationError(EOFError.ContainerTypeError) + } + + const target = code[ptr + 1] + if (target >= container.header.containerSizes.length) { + validationError(EOFError.InvalidRETURNContractTarget) + } + if (containerTypeMap.has(target)) { + if (containerTypeMap.get(target) !== ContainerSectionType.DeploymentCode) { + validationError(EOFError.ContainerDoubleType) + } + } + containerTypeMap.set(target, ContainerSectionType.DeploymentCode) + } else if (opcode === 0xd1) { + // DATALOADN + const dataTarget = readUint16(code, ptr + 1) + const endOfSlice = dataTarget + 32 + if (container.header.dataSize < endOfSlice) { + validationError(EOFError.DataLoadNOutOfBounds) + } + } else if (opcode === 0x00 || opcode === 0xf3) { + // STOP / RETURN + + if (mode === ContainerSectionType.InitCode) { + validationError(EOFError.ContainerTypeError) + } + } + + // Move ptr forward over any intermediates (if any) + // Note: for EOF this stackDelta is guaranteed to exist + const intermediates = stackDelta[opcode].intermediates + if (intermediates > 0) { + for (let i = 1; i <= intermediates; i++) { + addIntermediate(ptr + i) + } + ptr += intermediates // If the opcode has any intermediates, jump over it + } + if (ptr >= code.length) { + validationError(EOFError.OpcodeIntermediatesOOB) + } + ptr++ // Move to next opcode + if (stackDelta[opcode].terminating === undefined) { + // If the opcode is not terminating we can add the next opcode to the reachable opcodes + // It can be reached by sequential instruction flow + reachableOpcodes.add(ptr) + + // Add next opcode to successorSet + // NOTE: these are all opcodes except RJUMP + if (opcode !== 0xe0) { + successorSet.add(ptr) + } + } + + // TODO here validate stack / reachability and stack overflow check + + for (const successor of successorSet) { + if (successor < ptr) { + // Reached via backwards jump + if ( + stackHeightMin[successor] !== minStackNext || + stackHeightMax[successor] !== maxStackNext + ) { + validationError(EOFError.UnstableStack) + } + } + + if (stackHeightMax[successor] === undefined) { + // Target is seen for first time + stackHeightMin[successor] = minStackNext + stackHeightMax[successor] = maxStackNext + } else { + stackHeightMin[successor] = Math.min(stackHeightMin[successor], minStackNext) + stackHeightMax[successor] = Math.max(stackHeightMax[successor], maxStackNext) + } + } + + maxStackHeight = Math.max(maxStackNext, maxStackHeight) + } + + // Validate that the final opcode terminates + if (!terminatingOpcodes.has(lastOpcode)) { + validationError(EOFError.InvalidTerminator) + } + + if (container.body.typeSections[codeSection].maxStackHeight !== maxStackHeight) { + validationError(EOFError.MaxStackHeightViolation) + } + if (maxStackHeight > 1023) { + // TODO verify if 1023 or 1024 is the right constant + validationError(EOFError.MaxStackHeightLimit) + } + } + + // Verify that each code section can be reached from code section 0 + const sectionAccumulator = new Set() + sectionAccumulator.add(0) // 0 is always reachable + const toCheck = [0] + + while (toCheck.length > 0) { + const checkArray = reachableSections[toCheck.pop()!] + for (const checkSection of checkArray) { + if (!sectionAccumulator.has(checkSection)) { + // Only check the reachable section if + sectionAccumulator.add(checkSection) + toCheck.push(checkSection) + } + } + } + + if (sectionAccumulator.size !== container.header.codeSizes.length) { + validationError(EOFError.UnreachableCodeSections) + } + + if (containerTypeMap.size !== container.header.containerSizes.length) { + validationError(EOFError.UnreachableContainerSections) + } + + return containerTypeMap +} diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index 6e3d677284..a166f503a6 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -18,7 +18,8 @@ import { } from '@ethereumjs/util' import debugDefault from 'debug' -import { EOF, getEOFCode } from './eof.js' +import { FORMAT } from './eof/constants.js' +import { isEOF } from './eof/util.js' import { ERROR, EvmError } from './exceptions.js' import { Interpreter } from './interpreter.js' import { Journal } from './journal.js' @@ -164,11 +165,12 @@ export class EVM implements EVMInterface { // Supported EIPs const supportedEIPs = [ - 1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651, - 3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6110, 6780, 6800, 7002, 7251, 7516, - 7685, 7702, 7709, + 663, 1153, 1153, 1559, 1559, 2537, 2537, 2565, 2565, 2718, 2718, 2929, 2929, 2930, 2930, 2935, + 2935, 3074, 3074, 3198, 3198, 3529, 3529, 3540, 3540, 3541, 3541, 3607, 3607, 3651, 3651, + 3670, 3670, 3855, 3855, 3860, 3860, 4200, 4399, 4399, 4750, 4788, 4788, 4844, 4844, 4895, + 4895, 5133, 5133, 5450, 5656, 5656, 6110, 6110, 6206, 6780, 6780, 6800, 6800, 7002, 7002, + 7069, 7251, 7251, 7480, 7516, 7516, 7620, 7685, 7685, 7692, 7698, 7702, 7702, 7709, 7709, ] - for (const eip of this.common.eips()) { if (!supportedEIPs.includes(eip)) { throw new Error(`EIP-${eip} is not supported by the EVM`) @@ -408,8 +410,9 @@ export class EVM implements EVMInterface { } } + // TODO at some point, figure out why we swapped out data to code in the first place message.code = message.data - message.data = new Uint8Array(0) + message.data = message.eofCallData ?? new Uint8Array() message.to = await this._generateAddress(message) if (this.common.isActivatedEIP(6780)) { @@ -542,7 +545,7 @@ export class EVM implements EVMInterface { } // run the message with the updated gas limit and add accessed gas used to the result - let result = await this.runInterpreter({ ...message, gasLimit } as Message) + let result = await this.runInterpreter({ ...message, gasLimit, isCreate: true } as Message) result.executionGasUsed += message.gasLimit - gasLimit // fee for size of the return value @@ -570,36 +573,22 @@ export class EVM implements EVMInterface { // If enough gas and allowed code size let CodestoreOOG = false if (totalGas <= message.gasLimit && (this.allowUnlimitedContractSize || allowedCodeSize)) { - if (this.common.isActivatedEIP(3541) && result.returnValue[0] === EOF.FORMAT) { + if (this.common.isActivatedEIP(3541) && result.returnValue[0] === FORMAT) { if (!this.common.isActivatedEIP(3540)) { result = { ...result, ...INVALID_BYTECODE_RESULT(message.gasLimit) } - } - // Begin EOF1 contract code checks - // EIP-3540 EOF1 header check - const eof1CodeAnalysisResults = EOF.codeAnalysis(result.returnValue) - if (typeof eof1CodeAnalysisResults?.code === 'undefined') { - result = { - ...result, - ...INVALID_EOF_RESULT(message.gasLimit), - } - } else if (this.common.isActivatedEIP(3670)) { - // EIP-3670 EOF1 opcode check - const codeStart = eof1CodeAnalysisResults.data > 0 ? 10 : 7 - // The start of the code section of an EOF1 compliant contract will either be - // index 7 (if no data section is present) or index 10 (if a data section is present) - // in the bytecode of the contract - if ( - !EOF.validOpcodes( - result.returnValue.subarray(codeStart, codeStart + eof1CodeAnalysisResults.code) - ) - ) { - result = { - ...result, - ...INVALID_EOF_RESULT(message.gasLimit), - } - } else { - result.executionGasUsed = totalGas - } + } else if ( + // TODO check if this is correct + // Also likely cleanup this eofCallData stuff + /*(message.depth > 0 && message.eofCallData === undefined) || + (message.depth === 0 && !isEOF(message.code))*/ + !isEOF(message.code) + ) { + // TODO the message.eof was flagged for this to work for this first + // Running into Legacy mode: unable to deploy EOF contract + result = { ...result, ...INVALID_BYTECODE_RESULT(message.gasLimit) } + } else { + // 3541 is active and current runtime mode is EOF + result.executionGasUsed = totalGas } } else { result.executionGasUsed = totalGas @@ -726,6 +715,7 @@ export class EVM implements EVMInterface { callValue: message.value ?? BIGINT_0, code: message.code as Uint8Array, isStatic: message.isStatic ?? false, + isCreate: message.isCreate ?? false, depth: message.depth ?? 0, gasPrice: this._tx!.gasPrice, origin: this._tx!.origin ?? message.caller ?? Address.zero(), @@ -733,7 +723,6 @@ export class EVM implements EVMInterface { contract, codeAddress: message.codeAddress, gasRefund: message.gasRefund, - containerCode: message.containerCode, chargeCodeAccesses: message.chargeCodeAccesses, blobVersionedHashes: message.blobVersionedHashes ?? [], accessWitness: message.accessWitness, @@ -1008,14 +997,9 @@ export class EVM implements EVMInterface { message.code = precompile message.isCompiled = true } else { - message.containerCode = await this.stateManager.getContractCode(message.codeAddress) + message.code = await this.stateManager.getContractCode(message.codeAddress) message.isCompiled = false message.chargeCodeAccesses = true - if (this.common.isActivatedEIP(3540)) { - message.code = getEOFCode(message.containerCode) - } else { - message.code = message.containerCode - } } } } diff --git a/packages/evm/src/exceptions.ts b/packages/evm/src/exceptions.ts index 72ede8f493..9959f38dfd 100644 --- a/packages/evm/src/exceptions.ts +++ b/packages/evm/src/exceptions.ts @@ -19,9 +19,9 @@ export enum ERROR { INVALID_RETURNSUB = 'invalid RETURNSUB', INVALID_JUMPSUB = 'invalid JUMPSUB', INVALID_BYTECODE_RESULT = 'invalid bytecode deployed', - INVALID_EOF_FORMAT = 'invalid EOF format', INITCODE_SIZE_VIOLATION = 'initcode exceeds max initcode size', INVALID_INPUT_LENGTH = 'invalid input length', + INVALID_EOF_FORMAT = 'invalid EOF format', AUTHCALL_UNSET = 'attempting to AUTHCALL without AUTH set', diff --git a/packages/evm/src/index.ts b/packages/evm/src/index.ts index e1636497ee..6fcfc55462 100644 --- a/packages/evm/src/index.ts +++ b/packages/evm/src/index.ts @@ -1,4 +1,3 @@ -import { EOF } from './eof.js' import { EVM } from './evm.js' import { ERROR as EVMErrorMessage, EvmError } from './exceptions.js' import { Message } from './message.js' @@ -37,7 +36,6 @@ export type { } export { - EOF, EVM, EvmError, EVMErrorMessage, diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index ec46ecb3e1..35d6be0e44 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -3,6 +3,7 @@ import { Account, BIGINT_0, BIGINT_1, + BIGINT_2, MAX_UINT64, bigIntToHex, bytesToBigInt, @@ -11,7 +12,10 @@ import { } from '@ethereumjs/util' import debugDefault from 'debug' -import { EOF } from './eof.js' +import { FORMAT, MAGIC, VERSION } from './eof/constants.js' +import { EOFContainerMode, validateEOF } from './eof/container.js' +import { setupEOF } from './eof/setup.js' +import { ContainerSectionType } from './eof/verify.js' import { ERROR, EvmError } from './exceptions.js' import { type EVMPerformanceLogger, type Timer } from './logger.js' import { Memory } from './memory.js' @@ -22,7 +26,7 @@ import { Stack } from './stack.js' import type { EVM } from './evm.js' import type { Journal } from './journal.js' import type { AsyncOpHandler, Opcode, OpcodeMapEntry } from './opcodes/index.js' -import type { Block, Blockchain, EVMProfilerOpts, EVMResult, Log } from './types.js' +import type { Block, Blockchain, EOFEnv, EVMProfilerOpts, EVMResult, Log } from './types.js' import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' @@ -56,6 +60,7 @@ export interface Env { callValue: bigint code: Uint8Array isStatic: boolean + isCreate: boolean depth: number gasPrice: bigint origin: Address @@ -63,7 +68,7 @@ export interface Env { contract: Account codeAddress: Address /* Different than address for DELEGATECALL and CALLCODE */ gasRefund: bigint /* Current value (at begin of the frame) of the gas refund */ - containerCode?: Uint8Array /** Full container code for EOF1 contracts */ + eof?: EOFEnv /* Optional EOF environment in case of EOF execution */ blobVersionedHashes: Uint8Array[] /** Versioned hashes for blob transactions */ createdAddresses?: Set accessWitness?: AccessWitnessInterface @@ -184,40 +189,54 @@ export class Interpreter { } async run(code: Uint8Array, opts: InterpreterOpts = {}): Promise { - if (!this.common.isActivatedEIP(3540) || code[0] !== EOF.FORMAT) { + if (!this.common.isActivatedEIP(3540) || code[0] !== FORMAT) { // EIP-3540 isn't active and first byte is not 0xEF - treat as legacy bytecode this._runState.code = code } else if (this.common.isActivatedEIP(3540)) { - if (code[1] !== EOF.MAGIC) { + if (code[1] !== MAGIC) { // Bytecode contains invalid EOF magic byte return { runState: this._runState, exceptionError: new EvmError(ERROR.INVALID_BYTECODE_RESULT), } } - if (code[2] !== EOF.VERSION) { + if (code[2] !== VERSION) { // Bytecode contains invalid EOF version number return { runState: this._runState, exceptionError: new EvmError(ERROR.INVALID_EOF_FORMAT), } } - // Code is EOF1 format - const codeSections = EOF.codeAnalysis(code) - if (!codeSections) { - // Code is invalid EOF1 format if `codeSections` is falsy + this._runState.code = code + + const isTxCreate = this._env.isCreate && this._env.depth === 0 + const eofMode = isTxCreate ? EOFContainerMode.TxInitmode : EOFContainerMode.Default + + try { + setupEOF(this._runState, eofMode) + } catch (e) { return { runState: this._runState, - exceptionError: new EvmError(ERROR.INVALID_EOF_FORMAT), + exceptionError: new EvmError(ERROR.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed } } - if (codeSections.data) { - // Set code to EOF container code section which starts at byte position 10 if data section is present - this._runState.code = code.subarray(10, 10 + codeSections!.code) - } else { - // Set code to EOF container code section which starts at byte position 7 if no data section is present - this._runState.code = code.subarray(7, 7 + codeSections!.code) + if (isTxCreate) { + // Tx tries to deploy container + try { + validateEOF( + this._runState.code, + this._evm, + ContainerSectionType.InitCode, + EOFContainerMode.TxInitmode + ) + } catch (e) { + // Trying to deploy an invalid EOF container + return { + runState: this._runState, + exceptionError: new EvmError(ERROR.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed + } + } } } this._runState.programCounter = opts.pc ?? this._runState.programCounter @@ -691,14 +710,14 @@ export class Interpreter { * Returns the size of code running in current environment. */ getCodeSize(): bigint { - return BigInt(this._env.containerCode ? this._env.containerCode.length : this._env.code.length) + return BigInt(this._env.code.length) } /** * Returns the code running in current environment. */ getCode(): Uint8Array { - return this._env.containerCode ?? this._env.code + return this._env.code } /** @@ -1021,8 +1040,9 @@ export class Interpreter { async create( gasLimit: bigint, value: bigint, - data: Uint8Array, - salt?: Uint8Array + codeToRun: Uint8Array, + salt?: Uint8Array, + eofCallData?: Uint8Array ): Promise { const selfdestruct = new Set(this._result.selfdestruct) const caller = this._env.address @@ -1049,7 +1069,7 @@ export class Interpreter { if (this.common.isActivatedEIP(3860)) { if ( - data.length > Number(this.common.param('vm', 'maxInitCodeSize')) && + codeToRun.length > Number(this.common.param('vm', 'maxInitCodeSize')) && this._evm.allowUnlimitedInitCodeSize === false ) { return BIGINT_0 @@ -1060,7 +1080,8 @@ export class Interpreter { caller, gasLimit, value, - data, + data: codeToRun, + eofCallData, salt, depth, selfdestruct, @@ -1118,7 +1139,7 @@ export class Interpreter { } } - return this._getReturnCode(results) + return this._getReturnCode(results, true) } /** @@ -1134,6 +1155,20 @@ export class Interpreter { return this.create(gasLimit, value, data, salt) } + /** + * Creates a new contract with a given value. Generates + * a deterministic address via EOFCREATE rules. + */ + async eofcreate( + gasLimit: bigint, + value: bigint, + containerData: Uint8Array, + salt: Uint8Array, + callData: Uint8Array + ): Promise { + return this.create(gasLimit, value, containerData, salt, callData) + } + /** * Mark account for later deletion and give the remaining balance to the * specified beneficiary address. This will cause a trap and the @@ -1205,11 +1240,25 @@ export class Interpreter { this._result.logs.push(log) } - private _getReturnCode(results: EVMResult) { - if (results.execResult.exceptionError) { - return BIGINT_0 + private _getReturnCode(results: EVMResult, isEOFCreate = false) { + if (this._runState.env.eof === undefined || isEOFCreate) { + if (results.execResult.exceptionError) { + return BIGINT_0 + } else { + return BIGINT_1 + } } else { - return BIGINT_1 + // EOF mode, call was either EXTCALL / EXTDELEGATECALL / EXTSTATICCALL + if (results.execResult.exceptionError !== undefined) { + if (results.execResult.exceptionError.error === ERROR.REVERT) { + // Revert + return BIGINT_1 + } else { + // Failure + return BIGINT_2 + } + } + return BIGINT_0 } } } diff --git a/packages/evm/src/message.ts b/packages/evm/src/message.ts index 85cefdf583..7730fec394 100644 --- a/packages/evm/src/message.ts +++ b/packages/evm/src/message.ts @@ -1,6 +1,7 @@ import { Address, BIGINT_0 } from '@ethereumjs/util' import type { PrecompileFunc } from './precompiles/index.js' +import type { EOFEnv } from './types.js' import type { AccessWitnessInterface } from '@ethereumjs/common' import type { PrefixedHexString } from '@ethereumjs/util' @@ -21,6 +22,7 @@ interface MessageOpts { caller?: Address gasLimit: bigint data?: Uint8Array + eofCallData?: Uint8Array depth?: number code?: Uint8Array | PrecompileFunc codeAddress?: Address @@ -48,13 +50,15 @@ export class Message { caller: Address gasLimit: bigint data: Uint8Array + eofCallData?: Uint8Array // Only used in EOFCreate to signal an EOF contract to be created with this calldata (via EOFCreate) + isCreate?: boolean depth: number code?: Uint8Array | PrecompileFunc _codeAddress?: Address isStatic: boolean isCompiled: boolean salt?: Uint8Array - containerCode?: Uint8Array /** container code for EOF1 contracts - used by CODECOPY/CODESIZE */ + eof?: EOFEnv chargeCodeAccesses?: boolean /** * Set of addresses to selfdestruct. Key is the unprefixed address. @@ -83,6 +87,7 @@ export class Message { this.caller = opts.caller ?? defaults.caller this.gasLimit = opts.gasLimit this.data = opts.data ?? defaults.data + this.eofCallData = opts.eofCallData this.depth = opts.depth ?? defaults.depth this.code = opts.code this._codeAddress = opts.codeAddress diff --git a/packages/evm/src/opcodes/codes.ts b/packages/evm/src/opcodes/codes.ts index 5b24d27c28..2c374af45a 100644 --- a/packages/evm/src/opcodes/codes.ts +++ b/packages/evm/src/opcodes/codes.ts @@ -267,6 +267,14 @@ const hardforkOpcodes: { hardfork: Hardfork; opcodes: OpcodeEntry }[] = [ ] const eipOpcodes: { eip: number; opcodes: OpcodeEntry }[] = [ + { + eip: 663, + opcodes: { + 0xe6: { name: 'DUPN', isAsync: false, dynamicGas: false }, + 0xe7: { name: 'SWAPN', isAsync: false, dynamicGas: false }, + 0xe8: { name: 'EXCHANGE', isAsync: false, dynamicGas: false }, + }, + }, { eip: 1153, opcodes: { @@ -293,6 +301,21 @@ const eipOpcodes: { eip: number; opcodes: OpcodeEntry }[] = [ 0xf7: { name: 'AUTHCALL', isAsync: true, dynamicGas: true }, }, }, + { + eip: 4200, + opcodes: { + 0xe0: { name: 'RJUMP', isAsync: false, dynamicGas: false }, + 0xe1: { name: 'RJUMPI', isAsync: false, dynamicGas: false }, + 0xe2: { name: 'RJUMPV', isAsync: false, dynamicGas: false }, + }, + }, + { + eip: 4750, + opcodes: { + 0xe3: { name: 'CALLF', isAsync: false, dynamicGas: false }, + 0xe4: { name: 'RETF', isAsync: false, dynamicGas: false }, + }, + }, { eip: 4844, opcodes: { @@ -305,12 +328,43 @@ const eipOpcodes: { eip: number; opcodes: OpcodeEntry }[] = [ 0x5e: { name: 'MCOPY', isAsync: false, dynamicGas: true }, }, }, + { + eip: 6206, + opcodes: { + 0xe5: { name: 'JUMPF', isAsync: false, dynamicGas: false }, + }, + }, + { + eip: 7069, + opcodes: { + 0xf7: { name: 'RETURNDATALOAD', isAsync: false, dynamicGas: false }, + 0xf8: { name: 'EXTCALL', isAsync: true, dynamicGas: true }, + 0xf9: { name: 'EXTDELEGATECALL', isAsync: true, dynamicGas: true }, + 0xfb: { name: 'EXTSTATICCALL', isAsync: true, dynamicGas: true }, + }, + }, + { + eip: 7480, + opcodes: { + 0xd0: { name: 'DATALOAD', isAsync: false, dynamicGas: false }, + 0xd1: { name: 'DATALOADN', isAsync: false, dynamicGas: false }, + 0xd2: { name: 'DATASIZE', isAsync: false, dynamicGas: false }, + 0xd3: { name: 'DATACOPY', isAsync: false, dynamicGas: true }, + }, + }, { eip: 7516, opcodes: { 0x4a: { name: 'BLOBBASEFEE', isAsync: false, dynamicGas: false }, }, }, + { + eip: 7620, + opcodes: { + 0xec: { name: 'EOFCREATE', isAsync: true, dynamicGas: true }, + 0xee: { name: 'RETURNCONTRACT', isAsync: true, dynamicGas: true }, + }, + }, ] /** diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 7685432e24..69e5faf9bd 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -24,6 +24,7 @@ import { bigIntToBytes, bytesToBigInt, bytesToHex, + bytesToInt, concatBytes, ecrecover, getVerkleTreeIndexesForStorageSlot, @@ -34,6 +35,9 @@ import { } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' +import { EOFContainer, EOFContainerMode } from '../eof/container.js' +import { EOFError } from '../eof/errors.js' +import { EOFBYTES, EOFHASH, isEOF } from '../eof/util.js' import { ERROR } from '../exceptions.js' import { @@ -518,6 +522,14 @@ export const handlers: Map = new Map([ 0x3b, async function (runState) { const addressBigInt = runState.stack.pop() + const address = new Address(addresstoBytes(addressBigInt)) + // EOF check + const code = await runState.stateManager.getContractCode(address) + if (isEOF(code)) { + // In legacy code, the target code is treated as to be "EOFBYTES" code + runState.stack.push(BigInt(EOFBYTES.length)) + return + } let size if (typeof runState.stateManager.getContractCodeSize === 'function') { @@ -543,10 +555,15 @@ export const handlers: Map = new Map([ const [addressBigInt, memOffset, codeOffset, dataLength] = runState.stack.popN(4) if (dataLength !== BIGINT_0) { - const code = await runState.stateManager.getContractCode( + let code = await runState.stateManager.getContractCode( new Address(addresstoBytes(addressBigInt)) ) + if (isEOF(code)) { + // In legacy code, the target code is treated as to be "EOFBYTES" code + code = EOFBYTES + } + const data = getDataSlice(code, codeOffset, dataLength) const memOffsetNum = Number(memOffset) const lengthNum = Number(dataLength) @@ -560,6 +577,16 @@ export const handlers: Map = new Map([ async function (runState) { const addressBigInt = runState.stack.pop() const address = new Address(addresstoBytes(addressBigInt)) + + // EOF check + const code = await runState.stateManager.getContractCode(address) + if (isEOF(code)) { + // In legacy code, the target code is treated as to be "EOFBYTES" code + // Therefore, push the hash of EOFBYTES to the stack + runState.stack.push(bytesToBigInt(EOFHASH)) + return + } + const account = await runState.stateManager.getAccount(address) if (!account || account.isEmpty()) { runState.stack.push(BIGINT_0) @@ -984,6 +1011,346 @@ export const handlers: Map = new Map([ runState.interpreter.log(mem, topicsCount, topicsBuf) }, ], + // 0xd0: DATALOAD + [ + 0xd0, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const pos = runState.stack.pop() + if (pos > runState.env.eof!.container.body.dataSection.length) { + runState.stack.push(BIGINT_0) + return + } + + const i = Number(pos) + let loaded = runState.env.eof!.container.body.dataSection.subarray(i, i + 32) + loaded = loaded.length ? loaded : Uint8Array.from([0]) + let r = bytesToBigInt(loaded) + // Pad the loaded length with 0 bytes in case it is smaller than 32 + if (loaded.length < 32) { + r = r << (BIGINT_8 * BigInt(32 - loaded.length)) + } + runState.stack.push(r) + }, + ], + // 0xd1: DATALOADN + [ + 0xd1, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const toLoad = Number( + bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 2)) + ) + const data = bytesToBigInt( + runState.env.eof!.container.body.dataSection.subarray(toLoad, toLoad + 32) + ) + runState.stack.push(data) + runState.programCounter += 2 + }, + ], + // 0xd2: DATASIZE + [ + 0xd2, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + runState.stack.push(BigInt(runState.env.eof!.container.body.dataSection.length)) + }, + ], + // 0xd3: DATACOPY + [ + 0xd3, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const [memOffset, offset, size] = runState.stack.popN(3) + if (size !== BIGINT_0) { + const data = getDataSlice(runState.env.eof!.container.body.dataSection, offset, size) + const memOffsetNum = Number(memOffset) + const dataLengthNum = Number(size) + runState.memory.write(memOffsetNum, dataLengthNum, data) + } + }, + ], + // 0xe0: RJUMP + [ + 0xe0, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const code = runState.env.code + const rjumpDest = new DataView(code.buffer).getInt16(runState.programCounter) + runState.programCounter += 2 + rjumpDest + } + }, + ], + // 0xe1: RJUMPI + [ + 0xe1, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const cond = runState.stack.pop() + // Move PC to the PC post instruction + if (cond > 0) { + const code = runState.env.code + const rjumpDest = new DataView(code.buffer).getInt16(runState.programCounter) + runState.programCounter += rjumpDest + } + // In all cases, increment PC with 2 (also in the case if `cond` is `0`) + runState.programCounter += 2 + } + }, + ], + // 0xe2: RJUMPV + [ + 0xe2, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const code = runState.env.code + const jumptableEntries = code[runState.programCounter] + // Note: if the size of the immediate is `0`, this thus means that the actual size is `2` + // This allows for 256 entries in the table instead of 255 + const jumptableSize = (jumptableEntries + 1) * 2 + // Move PC to start of the jump table + runState.programCounter += 1 + const jumptableCase = runState.stack.pop() + if (jumptableCase <= jumptableEntries) { + const rjumpDest = new DataView(code.buffer).getInt16( + runState.programCounter + Number(jumptableCase) * 2 + ) + runState.programCounter += jumptableSize + rjumpDest + } else { + runState.programCounter += jumptableSize + } + } + }, + ], + // 0xe3: CALLF + [ + 0xe3, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const sectionTarget = bytesToInt( + runState.code.slice(runState.programCounter, runState.programCounter + 2) + ) + const stackItems = runState.stack.length + const typeSection = runState.env.eof!.container.body.typeSections[sectionTarget] + if (1024 < stackItems + typeSection?.inputs - typeSection?.maxStackHeight) { + trap(EOFError.StackOverflow) + } + if (runState.env.eof!.eofRunState.returnStack.length >= 1024) { + trap(EOFError.ReturnStackOverflow) + } + runState.env.eof?.eofRunState.returnStack.push(runState.programCounter + 2) + + // Find out the opcode we should jump into + runState.programCounter = runState.env.eof!.container.header.getCodePosition(sectionTarget) + }, + ], + // 0xe4: RETF + [ + 0xe4, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const newPc = runState.env.eof!.eofRunState.returnStack.pop() + if (newPc === undefined) { + // This should NEVER happen since it is validated that functions either terminate (the call frame) or return + trap(EOFError.RetfNoReturn) + } + runState.programCounter = newPc! + }, + ], + // 0xe5: JUMPF + [ + 0xe5, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.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) + // It is commented out here + const sectionTarget = bytesToInt( + runState.code.slice(runState.programCounter, runState.programCounter + 2) + ) + const stackItems = runState.stack.length + const typeSection = runState.env.eof!.container.body.typeSections[sectionTarget] + if (1024 < stackItems + typeSection?.inputs - typeSection?.maxStackHeight) { + trap(EOFError.StackOverflow) + } + /*if (runState.env.eof!.eofRunState.returnStack.length >= 1024) { + trap(EOFError.ReturnStackOverflow) + } + runState.env.eof?.eofRunState.returnStack.push(runState.programCounter + 2)*/ + + // Find out the opcode we should jump into + runState.programCounter = runState.env.eof!.container.header.getCodePosition(sectionTarget) + }, + ], + // 0xe6: DUPN + [ + 0xe6, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const toDup = + Number( + bytesToBigInt( + runState.code.subarray(runState.programCounter, runState.programCounter + 1) + ) + ) + 1 + runState.stack.dup(toDup) + runState.programCounter++ + }, + ], + // 0xe7: SWAPN + [ + 0xe7, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const toSwap = + Number( + bytesToBigInt( + runState.code.subarray(runState.programCounter, runState.programCounter + 1) + ) + ) + 1 + runState.stack.swap(toSwap) + runState.programCounter++ + }, + ], + // 0xe8: EXCHANGE + [ + 0xe8, + function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } + const toExchange = Number( + bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 1)) + ) + const n = (toExchange >> 4) + 1 + const m = (toExchange & 0x0f) + 1 + runState.stack.exchange(n, n + m) + runState.programCounter++ + }, + ], + // 0xec: EOFCREATE + [ + 0xec, + async function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + // Read container index + const containerIndex = runState.env.code[runState.programCounter] + const containerCode = runState.env.eof!.container.body.containerSections[containerIndex] + + // Pop stack values + const [value, salt, inputOffset, inputSize] = runState.stack.popN(4) + + const gasLimit = runState.messageGasLimit! + runState.messageGasLimit = undefined + + let data = new Uint8Array(0) + if (inputSize !== BIGINT_0) { + data = runState.memory.read(Number(inputOffset), Number(inputSize), true) + } + + runState.programCounter++ // Jump over the immediate byte + + const ret = await runState.interpreter.eofcreate( + gasLimit, + value, + containerCode, + setLengthLeft(bigIntToBytes(salt), 32), + data + ) + runState.stack.push(ret) + } + }, + ], + // 0xee: RETURNCONTRACT + [ + 0xee, + async function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + // Read container index + const containerIndex = runState.env.code[runState.programCounter] + const containerCode = runState.env.eof!.container.body.containerSections[containerIndex] + + // Read deployContainer as EOFCreate (initcode) container + const deployContainer = new EOFContainer(containerCode, EOFContainerMode.Initmode) + + // Pop stack values + const [auxDataOffset, auxDataSize] = runState.stack.popN(2) + + let auxData = new Uint8Array(0) + if (auxDataSize !== BIGINT_0) { + auxData = runState.memory.read(Number(auxDataOffset), Number(auxDataSize)) + } + + const originalDataSize = deployContainer.header.dataSize + const preDeployDataSectionSize = deployContainer.body.dataSection.length + const actualSectionSize = preDeployDataSectionSize + Number(auxDataSize) + + if (actualSectionSize < originalDataSize) { + trap(EOFError.InvalidReturnContractDataSize) + } + + if (actualSectionSize > 0xffff) { + // Data section size is now larger than the max data section size + // Temp: trap OOG? + trap(ERROR.OUT_OF_GAS) + } + + const newSize = setLengthLeft(bigIntToBytes(BigInt(actualSectionSize)), 2) + + // Write the bytes to the containerCode + const dataSizePtr = deployContainer.header.dataSizePtr + containerCode[dataSizePtr] = newSize[0] + containerCode[dataSizePtr + 1] = newSize[1] + + const returnContainer = concatBytes(containerCode, auxData) + + runState.interpreter.finish(returnContainer) + } + }, + ], // '0xf0' range - closures // 0xf0: CREATE [ @@ -1007,6 +1374,12 @@ export const handlers: Map = new Map([ data = runState.memory.read(Number(offset), Number(length), true) } + if (isEOF(data)) { + // Legacy cannot deploy EOF code + runState.stack.push(BIGINT_0) + return + } + const ret = await runState.interpreter.create(gasLimit, value, data) runState.stack.push(ret) }, @@ -1037,6 +1410,12 @@ export const handlers: Map = new Map([ data = runState.memory.read(Number(offset), Number(length), true) } + if (isEOF(data)) { + // Legacy cannot deploy EOF code + runState.stack.push(BIGINT_0) + return + } + const ret = await runState.interpreter.create2( gasLimit, value, @@ -1204,27 +1583,113 @@ export const handlers: Map = new Map([ runState.stack.push(BIGINT_1) }, ], - // 0xf7: AUTHCALL + // 0xf7: AUTHCALL (3074) / RETURNDATALOAD (7069) [ 0xf7, - async function (runState) { - const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = - runState.stack.popN(7) + async function (runState, common) { + if (common.isActivatedEIP(3074) && runState.env.eof === undefined) { + // AUTHCALL logic + const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = + runState.stack.popN(7) - const toAddress = new Address(addresstoBytes(addr)) + const toAddress = new Address(addresstoBytes(addr)) - const gasLimit = runState.messageGasLimit! - runState.messageGasLimit = undefined + const gasLimit = runState.messageGasLimit! + runState.messageGasLimit = undefined - let data = new Uint8Array(0) - if (argsLength !== BIGINT_0) { - data = runState.memory.read(Number(argsOffset), Number(argsLength)) + let data = new Uint8Array(0) + if (argsLength !== BIGINT_0) { + data = runState.memory.read(Number(argsOffset), Number(argsLength)) + } + + const ret = await runState.interpreter.authcall(gasLimit, toAddress, value, data) + // Write return data to memory + writeCallOutput(runState, retOffset, retLength) + runState.stack.push(ret) + } else if (common.isActivatedEIP(7069)) { + // RETURNDATALOAD logic + const returnDataOffset = runState.stack.pop() + const data = getDataSlice(runState.interpreter.getReturnData(), returnDataOffset, BIGINT_32) + runState.stack.push(bytesToBigInt(data)) + } else { + // This should be unreachable + trap(ERROR.INVALID_OPCODE) } + }, + ], + // 0xf8: EXTCALL + [ + 0xf8, + async function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const [toAddr, inOffset, inLength, value] = runState.stack.popN(4) - const ret = await runState.interpreter.authcall(gasLimit, toAddress, value, data) - // Write return data to memory - writeCallOutput(runState, retOffset, retLength) - runState.stack.push(ret) + const gasLimit = runState.messageGasLimit! + runState.messageGasLimit = undefined + + if (gasLimit === -BIGINT_1) { + // Special case, abort doing any logic (this logic is defined in `gas.ts`), and put `1` on stack per spec + runState.stack.push(BIGINT_1) + runState.returnBytes = new Uint8Array(0) + return + } + + const toAddress = new Address(addresstoBytes(toAddr)) + + let data = new Uint8Array(0) + if (inLength !== BIGINT_0) { + data = runState.memory.read(Number(inOffset), Number(inLength), true) + } + + const ret = await runState.interpreter.call(gasLimit, toAddress, value, data) + // Write return data to memory + + runState.stack.push(ret) + } + }, + ], + // 0xf9: EXTDELEGATECALL + [ + 0xf9, + async function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const value = runState.interpreter.getCallValue() + const [toAddr, inOffset, inLength] = runState.stack.popN(3) + + const gasLimit = runState.messageGasLimit! + runState.messageGasLimit = undefined + + if (gasLimit === -BIGINT_1) { + // Special case, abort doing any logic (this logic is defined in `gas.ts`), and put `1` on stack per spec + runState.stack.push(BIGINT_1) + runState.returnBytes = new Uint8Array(0) + return + } + + const toAddress = new Address(addresstoBytes(toAddr)) + + const code = await runState.stateManager.getContractCode(toAddress) + + if (!isEOF(code)) { + // EXTDELEGATECALL cannot call legacy contracts + runState.stack.push(BIGINT_1) + return + } + + let data = new Uint8Array(0) + if (inLength !== BIGINT_0) { + data = runState.memory.read(Number(inOffset), Number(inLength), true) + } + + const ret = await runState.interpreter.callDelegate(gasLimit, toAddress, value, data) + runState.stack.push(ret) + } }, ], // 0xfa: STATICCALL @@ -1250,6 +1715,39 @@ export const handlers: Map = new Map([ runState.stack.push(ret) }, ], + // 0xfb: EXTSTATICCALL + [ + 0xfb, + async function (runState, _common) { + if (runState.env.eof === undefined) { + // Opcode not available in legacy contracts + trap(ERROR.INVALID_OPCODE) + } else { + const value = BIGINT_0 + const [toAddr, inOffset, inLength] = runState.stack.popN(3) + + const gasLimit = runState.messageGasLimit! + runState.messageGasLimit = undefined + + if (gasLimit === -BIGINT_1) { + // Special case, abort doing any logic (this logic is defined in `gas.ts`), and put `1` on stack per spec + runState.stack.push(BIGINT_1) + runState.returnBytes = new Uint8Array(0) + return + } + + const toAddress = new Address(addresstoBytes(toAddr)) + + let data = new Uint8Array(0) + if (inLength !== BIGINT_0) { + data = runState.memory.read(Number(inOffset), Number(inLength), true) + } + + const ret = await runState.interpreter.callStatic(gasLimit, toAddress, value, data) + runState.stack.push(ret) + } + }, + ], // 0xf3: RETURN [ 0xf3, diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index f5610f3d26..a706698cf9 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -7,6 +7,7 @@ import { BIGINT_3, BIGINT_31, BIGINT_32, + BIGINT_64, VERKLE_BALANCE_LEAF_KEY, VERKLE_CODE_HASH_LEAF_KEY, VERKLE_CODE_SIZE_LEAF_KEY, @@ -16,6 +17,7 @@ import { setLengthLeft, } from '@ethereumjs/util' +import { EOFError } from '../eof/errors.js' import { ERROR } from '../exceptions.js' import { updateSstoreGasEIP1283 } from './EIP1283.js' @@ -34,6 +36,8 @@ import { import type { RunState } from '../interpreter.js' import type { Common } from '@ethereumjs/common' +const EXTCALL_TARGET_MAX = BigInt(2) ** BigInt(8 * 20) - BigInt(1) + /** * This file returns the dynamic parts of opcodes which have dynamic gas * These are not pure functions: some edit the size of the memory @@ -248,7 +252,11 @@ export const dynamicGasHandlers: Map runState.interpreter.getReturnDataSize()) { - trap(ERROR.OUT_OF_GAS) + // For an EOF contract, the behavior is changed (see EIP 7069) + // RETURNDATACOPY in that case does not throw OOG when reading out-of-bounds + if (runState.env.eof === undefined) { + trap(ERROR.OUT_OF_GAS) + } } gas += subMemUsage(runState, memOffset, dataLength, common) @@ -448,6 +456,76 @@ export const dynamicGasHandlers: Map { + // Note: TX_CREATE_COST is in the base fee (this is 32000 and same as CREATE / CREATE2) + + // Note: in `gas.ts` programCounter is not yet incremented (which it is in `functions.ts`) + // So have to manually add to programCounter here to get the right container index + + // Read container index + const containerIndex = runState.env.code[runState.programCounter + 1] + + // Pop stack values + const [_value, _salt, inputOffset, inputSize] = runState.stack.peek(4) + + //if (common.isActivatedEIP(2929)) { + // TODO: adding or not adding this makes test + // --test=tests/prague/eip7692_eof_v1/eip7620_eof_create/test_eofcreate.py::test_eofcreate_then_call[fork_CancunEIP7692-blockchain_test] + // still succeed. This only warms the current address?? This is also in CREATE/CREATE2 + // Can this be removed in both? + /*gas += accessAddressEIP2929( + runState, + runState.interpreter.getAddress().bytes, + common, + false + ) + }*/ + + // Expand memory + gas += subMemUsage(runState, inputOffset, inputSize, common) + + // Read container + const container = runState.env.eof!.container.body.containerSections[containerIndex] + + // Charge for hashing cost + gas += + common.param('gasPrices', 'keccak256Word') * divCeil(BigInt(container.length), BIGINT_32) + + const gasLeft = runState.interpreter.getGasLeft() - gas + runState.messageGasLimit = maxCallGas(gasLeft, gasLeft, runState, common) + + return gas + }, + ], + /* RETURNCONTRACT */ + [ + 0xee, + async function (runState, gas, common): Promise { + // Pop stack values + const [auxDataOffset, auxDataSize] = runState.stack.peek(2) + + // Expand memory + gas += subMemUsage(runState, auxDataOffset, auxDataSize, common) + + return gas + }, + ], [ /* CREATE */ 0xf0, @@ -761,6 +839,131 @@ export const dynamicGasHandlers: Map { + // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 + + // Peek stack values + const [toAddr, inOffset, inLength, value] = runState.stack.peek(4) + + // If value is nonzero and in static mode, throw: + if (runState.interpreter.isStatic() && value !== BIGINT_0) { + trap(ERROR.STATIC_STATE_CHANGE) + } + + // If value > 0, charge CALL_VALUE_COST + if (value > BIGINT_0) { + gas += common.param('gasPrices', 'callValueTransfer') + } + + // Check if the target address > 20 bytes + if (toAddr > EXTCALL_TARGET_MAX) { + trap(EOFError.InvalidExtcallTarget) + } + + // Charge for memory expansion + gas += subMemUsage(runState, inOffset, inLength, common) + + const toAddress = new Address(addresstoBytes(toAddr)) + // Charge to make address warm (2600 gas) + // (in case if address is already warm, this charges the 100 gas) + gas += accessAddressEIP2929(runState, toAddress.bytes, common) + + // Charge account creation cost if value is nonzero + if (value > BIGINT_0) { + const account = await runState.stateManager.getAccount(toAddress) + const deadAccount = account === undefined || account.isEmpty() + + if (deadAccount) { + gas += common.param('gasPrices', 'callNewAccount') + } + } + + const minRetainedGas = common.param('gasPrices', 'minRetainedGas') + const minCalleeGas = common.param('gasPrices', 'minCalleeGas') + + const currentGasAvailable = runState.interpreter.getGasLeft() - gas + const reducedGas = currentGasAvailable / BIGINT_64 + // Calculate the gas limit for the callee + // (this is the gas available for the next call frame) + let gasLimit: bigint + if (reducedGas < minRetainedGas) { + gasLimit = currentGasAvailable - minRetainedGas + } else { + gasLimit = currentGasAvailable - reducedGas + } + + if ( + runState.env.depth >= Number(common.param('vm', 'stackLimit')) || + runState.env.contract.balance < value || + gasLimit < minCalleeGas + ) { + // Note: this is a hack, TODO: get around this hack and clean this up + // This special case will ensure that the actual EXT*CALL is being ran, + // But, the code in `function.ts` will note that `runState.messageGasLimit` is set to a negative number + // This special number signals that `1` should be put on the stack (per spec) + gasLimit = -BIGINT_1 + } + + runState.messageGasLimit = gasLimit + + return gas + }, + ], + /* EXTDELEGATECALL */ + [ + 0xf9, + async function (runState, gas, common): Promise { + // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 + + // Peek stack values + const [toAddr, inOffset, inLength] = runState.stack.peek(3) + + // Check if the target address > 20 bytes + if (toAddr > EXTCALL_TARGET_MAX) { + trap(EOFError.InvalidExtcallTarget) + } + + // Charge for memory expansion + gas += subMemUsage(runState, inOffset, inLength, common) + + const toAddress = new Address(addresstoBytes(toAddr)) + // Charge to make address warm (2600 gas) + // (in case if address is already warm, this charges the 100 gas) + gas += accessAddressEIP2929(runState, toAddress.bytes, common) + + const minRetainedGas = common.param('gasPrices', 'minRetainedGas') + const minCalleeGas = common.param('gasPrices', 'minCalleeGas') + + const currentGasAvailable = runState.interpreter.getGasLeft() - gas + const reducedGas = currentGasAvailable / BIGINT_64 + // Calculate the gas limit for the callee + // (this is the gas available for the next call frame) + let gasLimit: bigint + if (reducedGas < minRetainedGas) { + gasLimit = currentGasAvailable - minRetainedGas + } else { + gasLimit = currentGasAvailable - reducedGas + } + + if ( + runState.env.depth >= Number(common.param('vm', 'stackLimit')) || + gasLimit < minCalleeGas + ) { + // Note: this is a hack, TODO: get around this hack and clean this up + // This special case will ensure that the actual EXT*CALL is being ran, + // But, the code in `function.ts` will note that `runState.messageGasLimit` is set to a negative number + // This special number signals that `1` should be put on the stack (per spec) + gasLimit = -BIGINT_1 + } + + runState.messageGasLimit = gasLimit + + return gas + }, + ], [ /* STATICCALL */ 0xfa, @@ -796,6 +999,58 @@ export const dynamicGasHandlers: Map { + // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 + + // Peek stack values + const [toAddr, inOffset, inLength] = runState.stack.peek(3) + + // Check if the target address > 20 bytes + if (toAddr > EXTCALL_TARGET_MAX) { + trap(EOFError.InvalidExtcallTarget) + } + + // Charge for memory expansion + gas += subMemUsage(runState, inOffset, inLength, common) + + const toAddress = new Address(addresstoBytes(toAddr)) + // Charge to make address warm (2600 gas) + // (in case if address is already warm, this charges the 100 gas) + gas += accessAddressEIP2929(runState, toAddress.bytes, common) + + const minRetainedGas = common.param('gasPrices', 'minRetainedGas') + const minCalleeGas = common.param('gasPrices', 'minCalleeGas') + + const currentGasAvailable = runState.interpreter.getGasLeft() - gas + const reducedGas = currentGasAvailable / BIGINT_64 + // Calculate the gas limit for the callee + // (this is the gas available for the next call frame) + let gasLimit: bigint + if (reducedGas < minRetainedGas) { + gasLimit = currentGasAvailable - minRetainedGas + } else { + gasLimit = currentGasAvailable - reducedGas + } + + if ( + runState.env.depth >= Number(common.param('vm', 'stackLimit')) || + gasLimit < minCalleeGas + ) { + // Note: this is a hack, TODO: get around this hack and clean this up + // This special case will ensure that the actual EXT*CALL is being ran, + // But, the code in `function.ts` will note that `runState.messageGasLimit` is set to a negative number + // This special number signals that `1` should be put on the stack (per spec) + gasLimit = -BIGINT_1 + } + + runState.messageGasLimit = gasLimit + + return gas + }, + ], [ /* REVERT */ 0xfd, diff --git a/packages/evm/src/stack.ts b/packages/evm/src/stack.ts index 0d3a7d92ce..e2ab7e964f 100644 --- a/packages/evm/src/stack.ts +++ b/packages/evm/src/stack.ts @@ -127,6 +127,26 @@ export class Stack { this._store[this._len++] = this._store[i] } + /** + * Swap number 1 with number 2 on the stack + * @param swap1 + * @param swap2 + */ + exchange(swap1: number, swap2: number) { + const headIndex = this._len - 1 + const exchangeIndex1 = headIndex - swap1 + const exchangeIndex2 = headIndex - swap2 + + // Stack underflow is not possible in EOF + if (exchangeIndex1 < 0 || exchangeIndex2 < 0) { + throw new EvmError(ERROR.STACK_UNDERFLOW) + } + + const cache = this._store[exchangeIndex2] + this._store[exchangeIndex2] = this._store[exchangeIndex1] + this._store[exchangeIndex1] = cache + } + /** * Returns a copy of the current stack. This represents the actual state of the stack * (not the internal state of the stack, which might have unreachable elements in it) diff --git a/packages/evm/src/types.ts b/packages/evm/src/types.ts index ce787f5c1a..b8798befc4 100644 --- a/packages/evm/src/types.ts +++ b/packages/evm/src/types.ts @@ -1,5 +1,6 @@ import { zeros } from '@ethereumjs/util' +import type { EOFContainer } from './eof/container.js' import type { EvmError } from './exceptions.js' import type { InterpreterStep, RunState } from './interpreter.js' import type { Message } from './message.js' @@ -429,3 +430,11 @@ export interface bn128 { ec_add: (input_str: string) => PrefixedHexString ec_mul: (input_hex: string) => PrefixedHexString } + +// EOF type which holds the execution-related data for EOF +export type EOFEnv = { + container: EOFContainer + eofRunState: { + returnStack: number[] + } +} diff --git a/packages/evm/test/eips/eip-4200.spec.ts b/packages/evm/test/eips/eip-4200.spec.ts new file mode 100644 index 0000000000..98072f07ce --- /dev/null +++ b/packages/evm/test/eips/eip-4200.spec.ts @@ -0,0 +1,40 @@ +import { hexToBytes } from '@ethereumjs/util' +import { assert, describe, it } from 'vitest' + +import { default as testData } from '../../../ethereum-tests/EOFTests/EIP4200/validInvalid.json' +import { validateEOF } from '../../src/eof/container.js' +import { createEVM } from '../../src/index.js' + +import { getCommon } from './eof-utils.js' + +async function getEVM() { + const common = getCommon() + const evm = createEVM({ + common, + }) + return evm +} + +describe('EIP 4200 tests', async () => { + const evm = await getEVM() + for (const key in testData.validInvalid.vectors) { + it(`Container validation tests ${key}`, () => { + //@ts-ignore + const input = testData.validInvalid.vectors[key] + const code = hexToBytes(input.code) + + const expected = input.results.Prague.result + const _exception = input.results.Prague.exception + + if (expected === true) { + validateEOF(code, evm) + } else { + //console.log(input.code) + assert.throws(() => { + // TODO verify that the correct error is thrown + validateEOF(code, evm) + }) + } + }) + } +}) diff --git a/packages/evm/test/eips/eip-5450.spec.ts b/packages/evm/test/eips/eip-5450.spec.ts new file mode 100644 index 0000000000..57c4eac593 --- /dev/null +++ b/packages/evm/test/eips/eip-5450.spec.ts @@ -0,0 +1,39 @@ +import { hexToBytes } from '@ethereumjs/util' +import { assert, describe, it } from 'vitest' + +import { default as testData } from '../../../ethereum-tests/EOFTests/EIP5450/validInvalid.json' +import { validateEOF } from '../../src/eof/container.js' +import { createEVM } from '../../src/index.js' + +import { getCommon } from './eof-utils.js' + +async function getEVM() { + const common = getCommon() + const evm = createEVM({ + common, + }) + return evm +} + +describe('EIP 5450 tests', async () => { + const evm = await getEVM() + for (const key in testData.validInvalid.vectors) { + it(`Container validation tests ${key}`, () => { + //@ts-ignore + const input = testData.validInvalid.vectors[key] + const code = hexToBytes(input.code) + + const expected = input.results.Prague.result + const _exception = input.results.Prague.exception + + if (expected === true) { + validateEOF(code, evm) + } else { + assert.throws(() => { + // TODO verify that the correct error is thrown + validateEOF(code, evm) + }) + } + }) + } +}) diff --git a/packages/evm/test/eips/eof-header-validation.ts b/packages/evm/test/eips/eof-header-validation.ts new file mode 100644 index 0000000000..a2931d1e03 --- /dev/null +++ b/packages/evm/test/eips/eof-header-validation.ts @@ -0,0 +1,93 @@ +import { hexToBytes } from '@ethereumjs/util' +import * as dir from 'node-dir' +import path from 'path' +import { assert, describe, it } from 'vitest' + +import { EOFContainerMode, validateEOF } from '../../src/eof/container.js' +import { ContainerSectionType } from '../../src/eof/verify.js' +import { createEVM } from '../../src/index.js' + +import { getCommon } from './eof-utils.js' + +// Rename this test dir to the location of EOF header tests +// To test, use `npx vitest run ./scripts/eof-header-validation.spec.ts +const testDir = path.resolve('../ethereum-tests/EOFStuff/fixtures/eof_tests') + +async function getEVM() { + const common = getCommon() + const evm = createEVM({ + common, + }) + return evm +} + +await new Promise((resolve, reject) => { + const finishedCallback = (err: Error | undefined) => { + if (err) { + reject(err) + return + } + resolve() + } + const fileCallback = async ( + err: Error | undefined, + content: string | Uint8Array, + fileName: string, + next: Function + ) => { + if (err) { + reject(err) + return + } + const name = path.parse(fileName).name + describe(`EOF Header validation tests - ${name}`, async () => { + const testData = JSON.parse(content) + const evm = await getEVM() + for (const key in testData) { + it(`Test ${key}`, () => { + //@ts-ignore + const input = testData[key] + for (const testKey in input.vectors) { + const test = input.vectors[testKey] + + const code = hexToBytes(test.code) + + const expected = test.results.Prague.result + const _exception = test.results.Prague.exception + + let containerSectionType = ContainerSectionType.RuntimeCode + let eofContainerMode = EOFContainerMode.Default + + if (test.containerKind !== undefined) { + if (test.containerKind === 'INITCODE') { + containerSectionType = ContainerSectionType.InitCode + eofContainerMode = EOFContainerMode.Initmode + } else { + throw new Error('unknown container kind: ' + test.containerKind) + } + } + + if (expected === true) { + validateEOF(code, evm, containerSectionType, eofContainerMode) + } else { + assert.throws(() => { + // TODO verify that the correct error is thrown + validateEOF(code, evm, containerSectionType, eofContainerMode) + }) + } + } + }) + } + }) + + next() + } + dir.readFiles( + testDir, + { + match: /.json$/, + }, + fileCallback, + finishedCallback + ) +}) diff --git a/packages/evm/test/eips/eof-runner.spec.ts b/packages/evm/test/eips/eof-runner.spec.ts new file mode 100644 index 0000000000..574a1bf1bf --- /dev/null +++ b/packages/evm/test/eips/eof-runner.spec.ts @@ -0,0 +1,41 @@ +import { Account, Address, hexToBytes } from '@ethereumjs/util' +import { assert, describe, it } from 'vitest' + +import { createEVM } from '../../src/index.js' + +import { getCommon } from './eof-utils.js' + +async function getEVM() { + const common = getCommon() + const evm = createEVM({ + common, + }) + return evm +} + +// Note: currently 0xE3 (RETF) and 0xE4 (JUMPF) need to be added to the valid opcodes list, otherwise 1 test will fail + +describe('EOF: should run a simple contract', async () => { + it('should run without failing', async () => { + const evm = await getEVM() + const code = hexToBytes('0xef000101000402000100030400010000800001305000ef') + + const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) // caller address + const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // contract address + + await evm.stateManager.putContractCode(contractAddress, code) + await evm.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x11111111))) + + const runCallArgs = { + caller, + gasLimit: BigInt(0xffff), + to: contractAddress, + } + + const result = await evm.runCall(runCallArgs) + + // The code which is being ran should run ADDRESS POP STOP + // This costs 4 gas + assert.ok(result.execResult.executionGasUsed === BigInt(4)) + }) +}) diff --git a/packages/evm/test/eips/eof-utils.ts b/packages/evm/test/eips/eof-utils.ts new file mode 100644 index 0000000000..d47a221c64 --- /dev/null +++ b/packages/evm/test/eips/eof-utils.ts @@ -0,0 +1,9 @@ +import { Chain, Common, Hardfork } from '@ethereumjs/common' + +export const getCommon = () => { + return new Common({ + hardfork: Hardfork.Prague, + eips: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7692, 7698], + chain: Chain.Mainnet, + }) +} diff --git a/packages/evm/test/eof.spec.ts b/packages/evm/test/eof.spec.ts deleted file mode 100644 index 4d1bc33d62..0000000000 --- a/packages/evm/test/eof.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { bytesToUnprefixedHex, hexToBytes } from '@ethereumjs/util' -import { assert, describe, it } from 'vitest' - -import { getEOFCode } from '../src/eof.js' - -import type { PrefixedHexString } from '@ethereumjs/util' - -function generateEOFCode(code: string): PrefixedHexString { - const len = (code.length / 2).toString(16).padStart(4, '0') - return `0xEF000101${len}00${code}` -} - -function generateInvalidEOFCode(code: string): PrefixedHexString { - const len = (code.length / 2 + 1).toString(16).padStart(4, '0') // len will be 1 too long - return `0xEF000101${len}00${code}` -} - -describe('getEOFCode()', () => { - it('should work', () => { - const code = '600100' - const validEofCode = generateEOFCode(code) - const invalidEofCode = generateInvalidEOFCode(code) - - assert.equal( - bytesToUnprefixedHex(getEOFCode(hexToBytes(validEofCode))), - code, - 'returned just code section of EOF container' - ) - assert.equal( - bytesToUnprefixedHex(getEOFCode(hexToBytes(invalidEofCode))), - invalidEofCode.toLowerCase().slice(2), - 'returns entire code string for non EOF code' - ) - }) -}) diff --git a/packages/vm/test/api/EIPs/eip-3540-evm-object-format.spec.ts b/packages/vm/test/api/EIPs/eip-3540-evm-object-format.spec.ts deleted file mode 100644 index 5100ececc9..0000000000 --- a/packages/vm/test/api/EIPs/eip-3540-evm-object-format.spec.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { EOF } from '@ethereumjs/evm' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' -import { Account, Address, concatBytes, hexToBytes, privateToAddress } from '@ethereumjs/util' -import { assert, describe, it } from 'vitest' - -import { VM } from '../../../src/vm' - -import type { PrefixedHexString } from '@ethereumjs/util' - -const pkey = hexToBytes(`0x${'20'.repeat(32)}`) -const GWEI = BigInt('1000000000') -const sender = new Address(privateToAddress(pkey)) - -async function runTx(vm: VM, data: PrefixedHexString, nonce: number) { - const tx = FeeMarketEIP1559Transaction.fromTxData({ - data, - gasLimit: 1000000, - maxFeePerGas: 7, - nonce, - }).sign(pkey) - const result = await vm.runTx({ tx }) - const created = result.createdAddress - const code = await vm.stateManager.getContractCode(created!) - return { result, code } -} - -describe('EIP 3540 tests', () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540], - }) - - it('EOF > codeAnalysis() tests', async () => { - const eofHeader = Uint8Array.from([EOF.FORMAT, EOF.MAGIC, EOF.VERSION]) - assert.ok( - EOF.codeAnalysis(concatBytes(eofHeader, Uint8Array.from([0x01, 0x00, 0x01, 0x00, 0x00]))) - ?.code! > 0, - 'valid code section' - ) - assert.ok( - EOF.codeAnalysis( - concatBytes( - eofHeader, - Uint8Array.from([0x01, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0xaa]) - ) - )?.data! > 0, - 'valid data section' - ) - assert.ok( - !( - EOF.codeAnalysis( - concatBytes(eofHeader, Uint8Array.from([0x01, 0x00, 0x01, 0x00, 0x00, 0x00])) - ) !== undefined - ), - 'invalid container length (too long)' - ) - assert.ok( - !( - EOF.codeAnalysis(concatBytes(eofHeader, Uint8Array.from([0x01, 0x00, 0x01, 0x00]))) !== - undefined - ), - 'invalid container length (too short)' - ) - }) - - it('valid EOF format / contract creation', async () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540], - }) - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - let res = await runTx(vm, '0x67ef0001010001000060005260086018f3', 0) - assert.ok(res.code.length > 0, 'code section with no data section') - - res = await runTx(vm, '0x6BEF00010100010200010000AA600052600C6014F3', 1) - assert.ok(res.code.length > 0, 'code section with data section') - }) - - it('invalid EOF format / contract creation', async () => { - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - let res = await runTx(vm, '0x60EF60005360016000F3', 0) - assert.ok(res.code.length === 0, 'no magic') - - res = await runTx( - vm, - '0x7FEF0000000000000000000000000000000000000000000000000000000000000060005260206000F3', - 1 - ) - assert.ok(res.code.length === 0, 'invalid header') - - res = await runTx( - vm, - '0x7FEF0002000000000000000000000000000000000000000000000000000000000060005260206000F3', - 2 - ) - assert.ok(res.code.length === 0, 'valid header but invalid EOF version') - - res = await runTx( - vm, - '0x7FEF0001000000000000000000000000000000000000000000000000000000000060005260206000F3', - 3 - ) - assert.ok(res.code.length === 0, 'valid header and version but no code section') - - res = await runTx( - vm, - '0x7FEF0001030000000000000000000000000000000000000000000000000000000060005260206000F3', - 4 - ) - assert.ok(res.code.length === 0, 'valid header and version but unknown section type') - - res = await runTx( - vm, - '0x7FEF0001010002006000DEADBEEF0000000000000000000000000000000000000060005260206000F3', - 5 - ) - assert.ok(res.code.length === 0, 'code section with trailing bytes') - }) -}) - -function generateEOFCode(code: string): PrefixedHexString { - const len = (code.length / 2).toString(16).padStart(4, '0') - return `0xEF000101${len}00${code}` -} - -function generateInvalidEOFCode(code: string): PrefixedHexString { - const len = (code.length / 2 + 1).toString(16).padStart(4, '0') // len will be 1 too long - return `0xEF000101${len}00${code}` -} - -const offset = '13' -const CREATEDeploy = `0x60${offset}380360${offset}60003960${offset}380360006000F000` - -const create2offset = '15' -const CREATE2Deploy = `0x600060${create2offset}380360${create2offset}60003960${create2offset}380360006000F500` - -function deployCreateCode(initcode: string): PrefixedHexString { - return `${CREATEDeploy}${initcode}` as PrefixedHexString -} - -function deployCreate2Code(initcode: string): PrefixedHexString { - return `${CREATE2Deploy}${initcode}` as PrefixedHexString -} - -describe('ensure invalid EOF initcode in EIP-3540 does not consume all gas', () => { - it('case: tx', async () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540], - }) - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - const res = await runTx(vm, generateEOFCode('60016001F3'), 0) - - const res2 = await runTx(vm, generateInvalidEOFCode('60016001F3'), 1) - assert.ok( - res.result.totalGasSpent > res2.result.totalGasSpent, - 'invalid initcode did not consume all gas' - ) - }) - - it('case: create', async () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540], - }) - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - const res = await runTx(vm, deployCreateCode(generateEOFCode('60016001F3').substring(2)), 0) - - const res2 = await runTx( - vm, - deployCreateCode(generateInvalidEOFCode('60016001F3').substring(2)), - 1 - ) - - assert.ok( - res.result.totalGasSpent > res2.result.totalGasSpent, - 'invalid initcode did not consume all gas' - ) - }) - - it('case: create2', async () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540], - }) - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - const res = await runTx(vm, deployCreate2Code(generateEOFCode('60016001F3').substring(2)), 0) - - const res2 = await runTx( - vm, - deployCreate2Code(generateInvalidEOFCode('60016001F3').substring(2)), - 1 - ) - assert.ok( - res.result.totalGasSpent > res2.result.totalGasSpent, - 'invalid initcode did not consume all gas' - ) - }) -}) diff --git a/packages/vm/test/api/EIPs/eip-3670-eof-code-validation.spec.ts b/packages/vm/test/api/EIPs/eip-3670-eof-code-validation.spec.ts deleted file mode 100644 index a77a6daa02..0000000000 --- a/packages/vm/test/api/EIPs/eip-3670-eof-code-validation.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { EOF } from '@ethereumjs/evm' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' -import { Account, Address, hexToBytes, privateToAddress, utf8ToBytes } from '@ethereumjs/util' -import { assert, describe, it } from 'vitest' - -import { VM } from '../../../src/vm' - -import type { PrefixedHexString } from '@ethereumjs/util' -const pkey = hexToBytes(`0x${'20'.repeat(32)}`) -const GWEI = BigInt('1000000000') -const sender = new Address(privateToAddress(pkey)) - -async function runTx(vm: VM, data: PrefixedHexString, nonce: number) { - const tx = FeeMarketEIP1559Transaction.fromTxData({ - data, - gasLimit: 1000000, - maxFeePerGas: 7, - nonce, - }).sign(pkey) - const result = await vm.runTx({ tx }) - const created = result.createdAddress - const code = await vm.stateManager.getContractCode(created!) - return { result, code } -} - -describe('EIP 3670 tests', () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.London, - eips: [3540, 3670], - }) - - it('EOF > validOpcodes() tests', () => { - assert.ok(EOF.validOpcodes(Uint8Array.from([0])), 'valid -- STOP ') - assert.ok(EOF.validOpcodes(Uint8Array.from([0xfe])), 'valid -- INVALID opcode') - assert.ok(EOF.validOpcodes(Uint8Array.from([0x60, 0xaa, 0])), 'valid - PUSH1 AA STOP') - - for (const opcode of [0x00, 0xf3, 0xfd, 0xfe, 0xff]) { - assert.ok( - EOF.validOpcodes(Uint8Array.from([0x60, 0xaa, opcode])), - `code ends with valid terminating instruction 0x${opcode.toString(16)}` - ) - } - - assert.notOk(EOF.validOpcodes(Uint8Array.from([0xaa])), 'invalid -- AA -- undefined opcode') - assert.notOk( - EOF.validOpcodes(Uint8Array.from([0x7f, 0xaa, 0])), - 'invalid -- PUSH32 AA STOP -- truncated push' - ) - assert.notOk( - EOF.validOpcodes(Uint8Array.from([0x61, 0xaa, 0])), - 'invalid -- PUSH2 AA STOP -- truncated push' - ) - assert.notOk( - EOF.validOpcodes(Uint8Array.from([0x60, 0xaa, 0x30])), - 'invalid -- PUSH1 AA ADDRESS -- invalid terminal opcode' - ) - }) - - it('valid contract code transactions', async () => { - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - let res = await runTx(vm, '0x67EF0001010001000060005260086018F3', 0) - assert.ok(res.code.length > 0, 'code section with no data section') - - res = await runTx(vm, '0x6BEF00010100010200010000AA600052600C6014F3', 1) - assert.ok(res.code.length > 0, 'code section with data section') - }) - - it('invalid contract code transactions', async () => { - const vm = await VM.create({ common }) - await vm.stateManager.putAccount(sender, new Account()) - const account = await vm.stateManager.getAccount(sender) - const balance = GWEI * BigInt(21000) * BigInt(10000000) - account!.balance = balance - await vm.stateManager.putAccount(sender, account!) - - const data = '0x67EF0001010001006060005260086018F3' - const res = await runTx(vm, data, 0) - assert.ok(res.code.length === 0, 'code should not be deposited') - assert.ok( - res.result.execResult.exceptionError?.error === 'invalid EOF format', - 'deposited code does not end with terminating instruction' - ) - }) - - it('ensure invalid eof headers are rejected when calling', async () => { - const common = new Common({ - chain: Chain.Mainnet, - hardfork: Hardfork.Paris, - eips: [3540, 3670], - }) - const vm = await VM.create({ common }) - - // Valid EOF code - const codeValid = hexToBytes( - '0xef000101008102000c006080604052348015600f57600080fd5b506004361060285760003560e01c8063f8a8fd6d14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b92915050560048656c6c6f20576f726c6421' - ) - // Invalid EOF code: code is exactly the same except the byte at the zero-index is not the FORMAT magic - // This thus runs into opcode 0xED which is unassigned and thus invalid - const codeInvalid = hexToBytes( - '0xed000101008102000c006080604052348015600f57600080fd5b506004361060285760003560e01c8063f8a8fd6d14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b92915050560048656c6c6f20576f726c6421' - ) - - const codes = [codeValid, codeInvalid] - const returnValues = [ - hexToBytes('0x000000000000000000000000000000000000000000000000000000000000002a'), - utf8ToBytes(''), - ] - const expectedErrors = [false, true] - - let nonce = 0n - - for (let i = 0; i < codes.length; i++) { - const calldata = hexToBytes('0xf8a8fd6d') - - const addr = new Address(hexToBytes(`0x${'20'.repeat(20)}`)) - const pkey = hexToBytes(`0x${'42'.repeat(32)}`) - - const code = codes[i] - - await vm.stateManager.putContractCode(addr, code) - - const tx = FeeMarketEIP1559Transaction.fromTxData({ - to: addr, - data: calldata, - gasLimit: 100000, - maxFeePerGas: 10, - maxPriorityFeePerGas: 10, - nonce, - }).sign(pkey) - - const sender = tx.getSenderAddress() - - if (i === 0) { - await vm.stateManager.putAccount(sender, new Account()) - } - const acc = await vm.stateManager.getAccount(sender) - acc!.balance = 1000000000n - - await vm.stateManager.putAccount(sender, acc!) - - const ret = await vm.runTx({ tx, skipHardForkValidation: true }) - nonce++ - - const expectReturn = returnValues[i] - const expectError = expectedErrors[i] - - assert.deepEqual(ret.execResult.returnValue, expectReturn, 'return value ok') - if (expectError) { - assert.ok(ret.execResult.exceptionError !== undefined, 'threw error') - } else { - assert.ok(ret.execResult.exceptionError === undefined, 'did not throw error') - } - } - }) -}) diff --git a/packages/vm/test/retesteth/transition-child.cts b/packages/vm/test/retesteth/transition-child.cts index 8f77a71bec..38ca7ce0ea 100644 --- a/packages/vm/test/retesteth/transition-child.cts +++ b/packages/vm/test/retesteth/transition-child.cts @@ -1,5 +1,5 @@ -import { Block, BlockHeader } from '@ethereumjs/block' -import { Blockchain } from '@ethereumjs/blockchain' +import { Block, BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockchain } from '@ethereumjs/blockchain' import { RLP } from '@ethereumjs/rlp' import { createTxFromSerializedData, LegacyTransaction } from '@ethereumjs/tx' import { Account, bytesToHex, unprefixedHexToBytes } from '@ethereumjs/util' @@ -55,8 +55,8 @@ async function runTransition(argsIn: any) { nonce: '0x0000000000000000', extraData: '0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa', } - const genesis = Block.fromBlockData({ header: BlockHeader.fromHeaderData(genesisBlockData) }) - blockchain = await Blockchain.create({ common, genesisBlock: genesis }) + const genesis = createBlockFromBlockData({ header: BlockHeader.fromHeaderData(genesisBlockData) }) + blockchain = await createBlockchain({ common, genesisBlock: genesis }) } const vm = blockchain ? await VM.create({ common, blockchain }) : await VM.create({ common }) await setupPreConditions(vm.stateManager, { pre: alloc }) From 3abbcd070b020fa6ea842f6e8ca3cde7d4499acd Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Thu, 18 Jul 2024 12:25:27 +0200 Subject: [PATCH 10/58] Common: Remove HF names from Params Dict (#3517) * Remove hardfork names from hardfork params dict * Merge branch 'master' into common-remove-hardfork-names * Small fix --- packages/common/src/common.ts | 5 ++--- packages/common/src/hardforks.ts | 23 +---------------------- packages/common/src/types.ts | 1 - 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 33a0750450..014ca2ec9e 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -395,9 +395,8 @@ export class Common { protected _buildActivatedEIPsCache() { this._activatedEIPsCache = [] - for (const hfChanges of this.HARDFORK_CHANGES) { - const hf = hfChanges[1] - if (this.gteHardfork(hf['name']) && 'eips' in hf) { + for (const [name, hf] of this.HARDFORK_CHANGES) { + if (this.gteHardfork(name) && 'eips' in hf) { this._activatedEIPsCache = this._activatedEIPsCache.concat(hf['eips'] as number[]) } } diff --git a/packages/common/src/hardforks.ts b/packages/common/src/hardforks.ts index 79935595cc..b95a4183b2 100644 --- a/packages/common/src/hardforks.ts +++ b/packages/common/src/hardforks.ts @@ -7,7 +7,6 @@ export const hardforks: HardforksDict = { * Status : Final */ chainstart: { - name: 'chainstart', gasConfig: { minGasLimit: 5000, // Minimum the gas limit may ever be gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations @@ -128,7 +127,6 @@ export const hardforks: HardforksDict = { * Status : Final */ homestead: { - name: 'homestead', gasPrices: { delegatecall: 40, // Base fee of the DELEGATECALL opcode }, @@ -138,16 +136,13 @@ export const hardforks: HardforksDict = { * URL : https://eips.ethereum.org/EIPS/eip-779 * Status : Final */ - dao: { - name: 'dao', - }, + dao: {}, /** * Description: Hardfork with gas cost changes for IO-heavy operations * URL : https://eips.ethereum.org/EIPS/eip-608 * Status : Final */ tangerineWhistle: { - name: 'tangerineWhistle', gasPrices: { sload: 200, // Once per SLOAD operation call: 700, // Once per CALL operation & message call transaction @@ -165,7 +160,6 @@ export const hardforks: HardforksDict = { * Status : Final */ spuriousDragon: { - name: 'spuriousDragon', gasPrices: { expByte: 50, // Times ceil(log256(exponent)) for the EXP instruction }, @@ -179,7 +173,6 @@ export const hardforks: HardforksDict = { * Status : Final */ byzantium: { - name: 'byzantium', gasPrices: { modexpGquaddivisor: 20, // Gquaddivisor from modexp precompile for gas calculation ecAdd: 500, // Gas costs for curve addition precompile @@ -202,7 +195,6 @@ export const hardforks: HardforksDict = { * Status : Final */ constantinople: { - name: 'constantinople', gasPrices: { netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero @@ -228,7 +220,6 @@ export const hardforks: HardforksDict = { * Status : Final */ petersburg: { - name: 'petersburg', gasPrices: { netSstoreNoopGas: null, // Removed along EIP-1283 netSstoreInitGas: null, // Removed along EIP-1283 @@ -245,7 +236,6 @@ export const hardforks: HardforksDict = { * Status : Final */ istanbul: { - name: 'istanbul', gasConfig: {}, gasPrices: { blake2Round: 1, // Gas cost per round for the Blake2 F precompile @@ -275,7 +265,6 @@ export const hardforks: HardforksDict = { * Status : Final */ muirGlacier: { - name: 'muirGlacier', pow: { difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with }, @@ -286,7 +275,6 @@ export const hardforks: HardforksDict = { * Status : Final */ berlin: { - name: 'berlin', eips: [2565, 2929, 2718, 2930], }, /** @@ -295,7 +283,6 @@ export const hardforks: HardforksDict = { * Status : Final */ london: { - name: 'london', eips: [1559, 3198, 3529, 3541], }, /** @@ -304,7 +291,6 @@ export const hardforks: HardforksDict = { * Status : Final */ arrowGlacier: { - name: 'arrowGlacier', eips: [4345], }, /** @@ -313,7 +299,6 @@ export const hardforks: HardforksDict = { * Status : Final */ grayGlacier: { - name: 'grayGlacier', eips: [5133], }, /** @@ -322,7 +307,6 @@ export const hardforks: HardforksDict = { * Status : Final */ paris: { - name: 'paris', consensus: { type: 'pos', algorithm: 'casper', @@ -336,7 +320,6 @@ export const hardforks: HardforksDict = { * Status : Final */ mergeForkIdTransition: { - name: 'mergeForkIdTransition', eips: [], }, /** @@ -345,7 +328,6 @@ export const hardforks: HardforksDict = { * Status : Final */ shanghai: { - name: 'shanghai', eips: [3651, 3855, 3860, 4895], }, /** @@ -356,7 +338,6 @@ export const hardforks: HardforksDict = { * Status : Final */ cancun: { - name: 'cancun', eips: [1153, 4844, 4788, 5656, 6780, 7516], }, /** @@ -365,7 +346,6 @@ export const hardforks: HardforksDict = { * Status : Final */ prague: { - name: 'prague', // TODO update this accordingly to the right devnet setup //eips: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7692, 7698], // This is EOF-only eips: [2537, 2935, 6110, 7002, 7251, 7685, 7702], // This is current prague without EOF @@ -376,7 +356,6 @@ export const hardforks: HardforksDict = { * Status : Final */ osaka: { - name: 'osaka', eips: [2935, 6800], }, } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 88c28f96d2..3c6082db90 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -187,7 +187,6 @@ export type EIPConfig = { } & EIPOrHFConfig export type HardforkConfig = { - name: string eips?: number[] consensus?: ConsensusConfig } & EIPOrHFConfig From d7c26198e7967c6303b5b65988979a5461a6223b Mon Sep 17 00:00:00 2001 From: acolytec3 <17355484+acolytec3@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:37:36 -0400 Subject: [PATCH 11/58] Apply leaf marker on all touched values (#3520) * Apply leaf marker to touched values * Add test for leaf marker --- packages/verkle/src/node/util.ts | 4 ++-- packages/verkle/test/leafNode.spec.ts | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/verkle/src/node/util.ts b/packages/verkle/src/node/util.ts index 72c1953034..b441bdfa19 100644 --- a/packages/verkle/src/node/util.ts +++ b/packages/verkle/src/node/util.ts @@ -88,9 +88,9 @@ export const createCValues = (values: (Uint8Array | VerkleLeafNodeValue)[]) => { break } // We add 16 trailing zeros to each value since all commitments are padded to an array of 32 byte values - // TODO: Determine whether we need to apply the leaf marker (i.e. set 129th bit) for all written values - // regardless of whether the value stored is zero or not expandedValues[x * 2] = setLengthRight(val.slice(0, 16), 32) + // Apply leaf marker to all touched values (i.e. flip 129th bit) + if (retrievedValue !== VerkleLeafNodeValue.Untouched) expandedValues[x * 2][16] = 0x80 expandedValues[x * 2 + 1] = setLengthRight(val.slice(16), 32) } return expandedValues diff --git a/packages/verkle/test/leafNode.spec.ts b/packages/verkle/test/leafNode.spec.ts index d23dab7162..ff62de67ba 100644 --- a/packages/verkle/test/leafNode.spec.ts +++ b/packages/verkle/test/leafNode.spec.ts @@ -2,7 +2,13 @@ import { type VerkleCrypto, equalsBytes, randomBytes, setLengthLeft } from '@eth import { loadVerkleCrypto } from 'verkle-cryptography-wasm' import { assert, beforeAll, describe, it } from 'vitest' -import { VerkleLeafNodeValue, VerkleNodeType, decodeNode, isLeafNode } from '../src/node/index.js' +import { + VerkleLeafNodeValue, + VerkleNodeType, + createCValues, + decodeNode, + isLeafNode, +} from '../src/node/index.js' import { LeafNode } from '../src/node/leafNode.js' describe('verkle node - leaf', () => { @@ -61,11 +67,18 @@ describe('verkle node - leaf', () => { assert.deepEqual(node.getValue(0), new Uint8Array(32)) }) + it('should set the leaf marker on a touched value', async () => { + const key = randomBytes(32) + const node = await LeafNode.create(key.slice(0, 31), verkleCrypto) + node.setValue(0, VerkleLeafNodeValue.Deleted) + const c1Values = createCValues(node.values.slice(0, 128)) + assert.equal(c1Values[0][16], 0x80) + }) + it('should update a commitment when setting a value', async () => { const key = randomBytes(32) const stem = key.slice(0, 31) - const values = new Array(256).fill(new Uint8Array(32)) - const node = await LeafNode.create(stem, verkleCrypto, values) + const node = await LeafNode.create(stem, verkleCrypto) assert.deepEqual(node.c1, verkleCrypto.zeroCommitment) node.setValue(0, randomBytes(32)) assert.notDeepEqual(node.c1, verkleCrypto.zeroCommitment) From b543d2fefa97c70fc0b5b3b9ead29734346a2503 Mon Sep 17 00:00:00 2001 From: acolytec3 <17355484+acolytec3@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:38:04 -0400 Subject: [PATCH 12/58] Switch `js-sdsl` to `js-sdsl/orderedMap` sub package (#3528) * Switch js-sdsl to isolated package * lint --- package-lock.json | 22 +++++++++---------- packages/client/package.json | 2 +- .../src/sync/fetcher/trienodefetcher.ts | 2 +- .../test/sync/fetcher/trienodefetcher.spec.ts | 2 +- packages/statemanager/package.json | 2 +- packages/statemanager/src/cache/account.ts | 2 +- packages/statemanager/src/cache/code.ts | 2 +- packages/statemanager/src/cache/storage.ts | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc5d3c1479..f8a2659734 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1910,6 +1910,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -10200,15 +10209,6 @@ "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.8.3.tgz", "integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==" }, - "node_modules/js-sdsl": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", - "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -16673,6 +16673,7 @@ "@ethereumjs/util": "9.0.3", "@ethereumjs/verkle": "^0.0.2", "@ethereumjs/vm": "8.0.0", + "@js-sdsl/ordered-map": "^4.4.2", "@multiformats/multiaddr": "^12.2.1", "@polkadot/util": "^12.6.2", "@polkadot/wasm-crypto": "^7.3.2", @@ -16686,7 +16687,6 @@ "ethereum-cryptography": "^2.2.1", "it-pipe": "^1.1.0", "jayson": "^4.0.0", - "js-sdsl": "^4.4.0", "kzg-wasm": "^0.4.0", "level": "^8.0.0", "mcl-wasm": "^1.5.0", @@ -16915,9 +16915,9 @@ "@ethereumjs/rlp": "^5.0.2", "@ethereumjs/trie": "^6.2.0", "@ethereumjs/util": "^9.0.3", + "@js-sdsl/ordered-map": "^4.4.2", "debug": "^4.3.3", "ethereum-cryptography": "^2.2.1", - "js-sdsl": "^4.1.4", "lru-cache": "10.1.0" }, "devDependencies": { diff --git a/packages/client/package.json b/packages/client/package.json index 648725f084..9438ffa403 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -69,6 +69,7 @@ "@ethereumjs/util": "9.0.3", "@ethereumjs/verkle": "^0.0.2", "@ethereumjs/vm": "8.0.0", + "@js-sdsl/ordered-map": "^4.4.2", "@multiformats/multiaddr": "^12.2.1", "@polkadot/util": "^12.6.2", "@polkadot/wasm-crypto": "^7.3.2", @@ -82,7 +83,6 @@ "ethereum-cryptography": "^2.2.1", "it-pipe": "^1.1.0", "jayson": "^4.0.0", - "js-sdsl": "^4.4.0", "kzg-wasm": "^0.4.0", "level": "^8.0.0", "mcl-wasm": "^1.5.0", diff --git a/packages/client/src/sync/fetcher/trienodefetcher.ts b/packages/client/src/sync/fetcher/trienodefetcher.ts index 54b8ab96ad..3bf1a9c6a2 100644 --- a/packages/client/src/sync/fetcher/trienodefetcher.ts +++ b/packages/client/src/sync/fetcher/trienodefetcher.ts @@ -15,10 +15,10 @@ import { KECCAK256_RLP, unprefixedHexToBytes, } from '@ethereumjs/util' +import { OrderedMap } from '@js-sdsl/ordered-map' import debug from 'debug' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { bytesToHex, equalsBytes, hexToBytes } from 'ethereum-cryptography/utils' -import { OrderedMap } from 'js-sdsl' import { Fetcher } from './fetcher.js' import { getInitFecherDoneFlags } from './types.js' diff --git a/packages/client/test/sync/fetcher/trienodefetcher.spec.ts b/packages/client/test/sync/fetcher/trienodefetcher.spec.ts index d3000a9715..3f54b44b5e 100644 --- a/packages/client/test/sync/fetcher/trienodefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/trienodefetcher.spec.ts @@ -1,7 +1,7 @@ import { RLP } from '@ethereumjs/rlp' import { decodeNode } from '@ethereumjs/trie' import { bytesToHex, hexToBytes } from '@ethereumjs/util' -import { OrderedMap } from 'js-sdsl' +import { OrderedMap } from '@js-sdsl/ordered-map' import { assert, describe, it, vi } from 'vitest' import { Chain } from '../../../src/blockchain/index.js' diff --git a/packages/statemanager/package.json b/packages/statemanager/package.json index 051d8e8239..3a1318c323 100644 --- a/packages/statemanager/package.json +++ b/packages/statemanager/package.json @@ -54,9 +54,9 @@ "@ethereumjs/rlp": "^5.0.2", "@ethereumjs/trie": "^6.2.0", "@ethereumjs/util": "^9.0.3", + "@js-sdsl/ordered-map": "^4.4.2", "debug": "^4.3.3", "ethereum-cryptography": "^2.2.1", - "js-sdsl": "^4.1.4", "lru-cache": "10.1.0" }, "devDependencies": { diff --git a/packages/statemanager/src/cache/account.ts b/packages/statemanager/src/cache/account.ts index c78ca1b41f..9100b513ec 100644 --- a/packages/statemanager/src/cache/account.ts +++ b/packages/statemanager/src/cache/account.ts @@ -1,6 +1,6 @@ import { bytesToUnprefixedHex } from '@ethereumjs/util' +import { OrderedMap } from '@js-sdsl/ordered-map' import debugDefault from 'debug' -import { OrderedMap } from 'js-sdsl' import { LRUCache } from 'lru-cache' import { Cache } from './cache.js' diff --git a/packages/statemanager/src/cache/code.ts b/packages/statemanager/src/cache/code.ts index 5579da224d..3aaeb25db8 100644 --- a/packages/statemanager/src/cache/code.ts +++ b/packages/statemanager/src/cache/code.ts @@ -1,6 +1,6 @@ import { bytesToUnprefixedHex } from '@ethereumjs/util' +import { OrderedMap } from '@js-sdsl/ordered-map' import debugDefault from 'debug' -import { OrderedMap } from 'js-sdsl' import { LRUCache } from 'lru-cache' import { Cache } from './cache.js' diff --git a/packages/statemanager/src/cache/storage.ts b/packages/statemanager/src/cache/storage.ts index eb8d52bdd9..a9625a1c3b 100644 --- a/packages/statemanager/src/cache/storage.ts +++ b/packages/statemanager/src/cache/storage.ts @@ -1,6 +1,6 @@ import { bytesToUnprefixedHex, hexToBytes } from '@ethereumjs/util' +import { OrderedMap } from '@js-sdsl/ordered-map' import debugDefault from 'debug' -import { OrderedMap } from 'js-sdsl' import { LRUCache } from 'lru-cache' import { Cache } from './cache.js' From fb506280ff40b11d526f9429356609de16554d19 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Tue, 23 Jul 2024 09:54:17 +0200 Subject: [PATCH 13/58] VM: runTx(), runBlock(), buildBlock() Standalone Methods (#3530) * Move over runTx() * runTx() test and upstream usage fixes * client/test: fix import * vm: add original runTx docs to runTx * vm: unbind runBlock * vm: export runBlock * unbind runBlock in tests and client * vm/client: unbind buildBlock * vm: standalone emitEVMProfile * vm: fix tests * client: fix tests * client: fix docker build --------- Co-authored-by: Jochem Brouwer --- packages/client/src/execution/vmexecution.ts | 10 +- packages/client/src/miner/miner.ts | 4 +- packages/client/src/miner/pendingBlock.ts | 4 +- packages/client/src/rpc/modules/debug.ts | 8 +- packages/client/src/rpc/modules/eth.ts | 22 +- packages/client/src/util/debug.ts | 5 +- .../client/test/execution/vmexecution.spec.ts | 7 +- .../test/rpc/debug/storageRangeAt.spec.ts | 3 +- .../client/test/rpc/eth/blobBaseFee.spec.ts | 3 +- packages/client/test/rpc/eth/call.spec.ts | 8 +- .../client/test/rpc/eth/estimateGas.spec.ts | 10 +- .../client/test/rpc/eth/getBalance.spec.ts | 3 +- .../getBlockTransactionCountByNumber.spec.ts | 5 +- packages/client/test/rpc/eth/getCode.spec.ts | 3 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 7 +- packages/client/test/rpc/eth/getProof.spec.ts | 5 +- .../client/test/rpc/eth/getStorageAt.spec.ts | 7 +- .../test/rpc/eth/getTransactionCount.spec.ts | 3 +- packages/client/test/rpc/helpers.ts | 3 +- .../client/test/rpc/txpool/content.spec.ts | 5 +- packages/evm/src/interpreter.ts | 7 + .../statemanager/test/rpcStateManager.spec.ts | 8 +- packages/vm/benchmarks/mainnetBlocks.ts | 6 +- packages/vm/examples/buildBlock.ts | 4 +- packages/vm/examples/run-blockchain.ts | 4 +- packages/vm/examples/run-solidity-contract.ts | 6 +- packages/vm/examples/runGoerliBlock.ts | 3 +- packages/vm/examples/runTx.ts | 4 +- packages/vm/src/buildBlock.ts | 27 +- packages/vm/src/emitEVMProfile.ts | 151 +++++++++++ packages/vm/src/index.ts | 3 + packages/vm/src/runBlock.ts | 252 +++++++++--------- packages/vm/src/runTx.ts | 239 +++++++++-------- packages/vm/src/vm.ts | 212 +-------------- packages/vm/test/api/EIPs/eip-1153.spec.ts | 4 +- .../EIPs/eip-1283-net-gas-metering.spec.ts | 4 +- .../test/api/EIPs/eip-1559-FeeMarket.spec.ts | 10 +- .../api/EIPs/eip-2565-modexp-gas-cost.spec.ts | 2 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 6 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 6 +- .../eip-2935-historical-block-hashes.spec.ts | 14 +- .../test/api/EIPs/eip-3074-authcall.spec.ts | 42 +-- .../vm/test/api/EIPs/eip-3198-BaseFee.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-3529.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-3541.spec.ts | 16 +- packages/vm/test/api/EIPs/eip-3607.spec.ts | 6 +- .../api/EIPs/eip-3651-warm-coinbase.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-3855.spec.ts | 2 +- packages/vm/test/api/EIPs/eip-3860.spec.ts | 4 +- ...t-difficulty-opcode-with-prevrando.spec.ts | 2 +- .../test/api/EIPs/eip-4788-beaconroot.spec.ts | 3 +- .../vm/test/api/EIPs/eip-4844-blobs.spec.ts | 6 +- .../api/EIPs/eip-4895-withdrawals.spec.ts | 12 +- packages/vm/test/api/EIPs/eip-6110.spec.ts | 5 +- .../eip-6780-selfdestruct-same-tx.spec.ts | 6 +- .../vm/test/api/EIPs/eip-6800-verkle.spec.ts | 3 +- packages/vm/test/api/EIPs/eip-7002.spec.ts | 11 +- packages/vm/test/api/EIPs/eip-7685.spec.ts | 12 +- packages/vm/test/api/EIPs/eip-7702.spec.ts | 8 +- packages/vm/test/api/buildBlock.spec.ts | 23 +- packages/vm/test/api/customChain.spec.ts | 5 +- packages/vm/test/api/events.spec.ts | 19 +- .../vm/test/api/istanbul/eip-1108.spec.ts | 2 +- .../vm/test/api/istanbul/eip-1344.spec.ts | 2 +- .../test/api/istanbul/eip-152.deactivated.ts | 2 +- .../vm/test/api/istanbul/eip-1884.spec.ts | 4 +- .../vm/test/api/istanbul/eip-2200.spec.ts | 4 +- .../vm/test/api/muirGlacier/index.spec.ts | 2 +- packages/vm/test/api/runBlock.spec.ts | 39 ++- packages/vm/test/api/runTx.spec.ts | 71 ++--- .../vm/test/api/state/accountExists.spec.ts | 2 +- .../tester/runners/BlockchainTestsRunner.ts | 6 +- .../tester/runners/GeneralStateTestsRunner.ts | 4 +- packages/vm/test/util.ts | 2 +- 74 files changed, 720 insertions(+), 718 deletions(-) create mode 100644 packages/vm/src/emitEVMProfile.ts diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index db8cef9f07..17ea600cd6 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -22,7 +22,7 @@ import { equalsBytes, hexToBytes, } from '@ethereumjs/util' -import { VM } from '@ethereumjs/vm' +import { VM, runBlock, runTx } from '@ethereumjs/vm' import { writeFileSync } from 'fs' import * as mcl from 'mcl-wasm' import { loadVerkleCrypto } from 'verkle-cryptography-wasm' @@ -453,7 +453,7 @@ export class VMExecution extends Execution { } const reportPreimages = this.config.savePreimages - const result = await vm.runBlock({ + const result = await runBlock(vm, { clearCache, ...opts, parentStateRoot: prevVMStateRoot, @@ -744,7 +744,7 @@ export class VMExecution extends Execution { this._statsVM = this.vm const beforeTS = Date.now() - const result = await this.vm.runBlock({ + const result = await runBlock(this.vm, { block, root: parentState, clearCache, @@ -1049,7 +1049,7 @@ export class VMExecution extends Execution { // we are skipping header validation because the block has been picked from the // blockchain and header should have already been validated while putBlock const beforeTS = Date.now() - const res = await vm.runBlock({ + const res = await runBlock(vm, { block, root, clearCache: false, @@ -1073,7 +1073,7 @@ export class VMExecution extends Execution { for (const tx of block.transactions) { const txHash = bytesToHex(tx.hash()) if (allTxs || txHashes.includes(txHash)) { - const res = await vm.runTx({ block, tx }) + const res = await runTx(vm, { block, tx }) this.config.logger.info( `Executed tx hash=${txHash} gasUsed=${res.totalGasSpent} from block num=${blockNumber}` ) diff --git a/packages/client/src/miner/miner.ts b/packages/client/src/miner/miner.ts index f4fe4d78c5..91b9b19b4f 100644 --- a/packages/client/src/miner/miner.ts +++ b/packages/client/src/miner/miner.ts @@ -2,6 +2,7 @@ import { BlockHeader } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' import { BIGINT_0, BIGINT_1, BIGINT_2, bytesToHex, equalsBytes } from '@ethereumjs/util' +import { type TxReceipt, buildBlock } from '@ethereumjs/vm' import { MemoryLevel } from 'memory-level' import { LevelDB } from '../execution/level.js' @@ -14,7 +15,6 @@ import type { FullSynchronizer } from '../sync/index.js' import type { CliqueConsensus } from '@ethereumjs/blockchain' import type { CliqueConfig } from '@ethereumjs/common' import type { Miner as EthashMiner, Solution } from '@ethereumjs/ethash' -import type { TxReceipt } from '@ethereumjs/vm' export interface MinerOptions { /* Config */ @@ -275,7 +275,7 @@ export class Miner { coinbase = this.config.minerCoinbase ?? this.config.accounts[0][0] } - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { number, diff --git a/packages/client/src/miner/pendingBlock.ts b/packages/client/src/miner/pendingBlock.ts index 6f548849d0..17963074ec 100644 --- a/packages/client/src/miner/pendingBlock.ts +++ b/packages/client/src/miner/pendingBlock.ts @@ -13,7 +13,7 @@ import { toType, zeros, } from '@ethereumjs/util' -import { BuildStatus } from '@ethereumjs/vm' +import { BuildStatus, buildBlock } from '@ethereumjs/vm' import { keccak256 } from 'ethereum-cryptography/keccak' import type { Config } from '../config.js' @@ -176,7 +176,7 @@ export class PendingBlock { // is based on the parent block's state await vm.stateManager.setStateRoot(parentBlock.header.stateRoot) - const builder = await vm.buildBlock({ + const builder = await buildBlock(vm, { parentBlock, // excessBlobGas will be correctly calculated and set in buildBlock constructor, // unless already explicity provided in headerData diff --git a/packages/client/src/rpc/modules/debug.ts b/packages/client/src/rpc/modules/debug.ts index be7a61f23c..e8e63b8c9e 100644 --- a/packages/client/src/rpc/modules/debug.ts +++ b/packages/client/src/rpc/modules/debug.ts @@ -1,5 +1,5 @@ import { Address, TypeOutput, bigIntToHex, bytesToHex, hexToBytes, toType } from '@ethereumjs/util' -import { type VM, encodeReceipt } from '@ethereumjs/vm' +import { type VM, encodeReceipt, runTx } from '@ethereumjs/vm' import { INTERNAL_ERROR, INVALID_PARAMS } from '../error-code.js' import { callWithStackTrace, getBlockByOption } from '../helpers.js' @@ -166,7 +166,7 @@ export class Debug { await vmCopy.stateManager.setStateRoot(parentBlock.header.stateRoot) for (let x = 0; x < txIndex; x++) { // Run all txns in the block prior to the traced transaction - await vmCopy.runTx({ tx: block.transactions[x], block }) + await runTx(vmCopy, { tx: block.transactions[x], block }) } const trace = { @@ -210,7 +210,7 @@ export class Debug { } next?.() }) - const res = await vmCopy.runTx({ tx, block }) + const res = await runTx(vmCopy, { tx, block }) trace.gas = bigIntToHex(res.totalGasSpent) trace.failed = res.execResult.exceptionError !== undefined trace.returnValue = bytesToHex(res.execResult.returnValue) @@ -349,7 +349,7 @@ export class Debug { const vmCopy = await this.vm.shallowCopy() await vmCopy.stateManager.setStateRoot(parentBlock.header.stateRoot) for (let i = 0; i <= txIndex; i++) { - await vmCopy.runTx({ tx: block.transactions[i], block }) + await runTx(vmCopy, { tx: block.transactions[i], block }) } // await here so that any error can be handled in the catch below for proper response diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 9716195041..c624f41126 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -23,6 +23,15 @@ import { setLengthLeft, toType, } from '@ethereumjs/util' +import { + type EIP4844BlobTxReceipt, + type PostByzantiumTxReceipt, + type PreByzantiumTxReceipt, + type TxReceipt, + type VM, + runBlock, + runTx, +} from '@ethereumjs/vm' import { INTERNAL_ERROR, INVALID_HEX_STRING, INVALID_PARAMS, PARSE_ERROR } from '../error-code.js' import { callWithStackTrace, getBlockByOption, jsonRpcTx } from '../helpers.js' @@ -43,13 +52,6 @@ import type { TypedTransaction, } from '@ethereumjs/tx' import type { PrefixedHexString } from '@ethereumjs/util' -import type { - EIP4844BlobTxReceipt, - PostByzantiumTxReceipt, - PreByzantiumTxReceipt, - TxReceipt, - VM, -} from '@ethereumjs/vm' const EMPTY_SLOT = `0x${'00'.repeat(32)}` @@ -611,7 +613,7 @@ export class Eth { return from } - const { totalGasSpent } = await vm.runTx({ + const { totalGasSpent } = await runTx(vm, { tx, skipNonce: true, skipBalance: true, @@ -940,7 +942,7 @@ export class Eth { const vmCopy = await this._vm!.shallowCopy() vmCopy.common.setHardfork(block.common.hardfork()) // Run tx through copied vm to get tx gasUsed and createdAddress - const runBlockResult = await vmCopy.runBlock({ + const runBlockResult = await runBlock(vmCopy, { block, root: parentBlock.header.stateRoot, skipBlockValidation: true, @@ -1015,7 +1017,7 @@ export class Eth { const vmCopy = await this._vm!.shallowCopy() vmCopy.common.setHardfork(tx.common.hardfork()) // Run tx through copied vm to get tx gasUsed and createdAddress - const runBlockResult = await vmCopy.runBlock({ + const runBlockResult = await runBlock(vmCopy, { block, root: parentBlock.header.stateRoot, skipBlockValidation: true, diff --git a/packages/client/src/util/debug.ts b/packages/client/src/util/debug.ts index 3c01e39507..c4a549e83d 100644 --- a/packages/client/src/util/debug.ts +++ b/packages/client/src/util/debug.ts @@ -28,7 +28,7 @@ export async function debugCodeReplayBlock(execution: VMExecution, block: Block) import { Level } from 'level'; import { Common } from '@ethereumjs/common' import { Block } from '@ethereumjs/block' -import { VM } from './src' +import { VM, runBlock } from './src' import { Trie } from '@ethereumjs/trie' import { DefaultStateManager } from './src/state' import { Blockchain } from '@ethereumjs/blockchain' @@ -59,11 +59,10 @@ const main = async () => { }) const vm = await VM.create({ stateManager, blockchain, common }) - await vm.runBlock({ block }) + await runBlock({ block }) } main() ` - execution.config.logger.info(code) } diff --git a/packages/client/test/execution/vmexecution.spec.ts b/packages/client/test/execution/vmexecution.spec.ts index 72f7095631..48622702a4 100644 --- a/packages/client/test/execution/vmexecution.spec.ts +++ b/packages/client/test/execution/vmexecution.spec.ts @@ -143,13 +143,8 @@ describe('[VMExecution]', () => { }) exec = await testSetup(blockchain) - await exec.run() - - assert.doesNotThrow( - async () => exec.executeBlocks(1, 5, []), - 'blocks should execute without error' - ) + await exec.executeBlocks(1, 5, []) }) it('Should fail opening if vmPromise already assigned', async () => { diff --git a/packages/client/test/rpc/debug/storageRangeAt.spec.ts b/packages/client/test/rpc/debug/storageRangeAt.spec.ts index 1f235a2e00..8f55a24f20 100644 --- a/packages/client/test/rpc/debug/storageRangeAt.spec.ts +++ b/packages/client/test/rpc/debug/storageRangeAt.spec.ts @@ -1,5 +1,6 @@ import { createTxFromTxData } from '@ethereumjs/tx' import { bigIntToHex, bytesToBigInt, bytesToHex, hexToBytes, setLengthLeft } from '@ethereumjs/util' +import { buildBlock } from '@ethereumjs/vm' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, beforeEach, describe, it } from 'vitest' @@ -102,7 +103,7 @@ describe(method, () => { const vmCopy = await execution.vm.shallowCopy() const parentBlock = await chain.getCanonicalHeadBlock() - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BigInt(1), diff --git a/packages/client/test/rpc/eth/blobBaseFee.spec.ts b/packages/client/test/rpc/eth/blobBaseFee.spec.ts index 3c61ed8fdd..b4c9bbe01e 100644 --- a/packages/client/test/rpc/eth/blobBaseFee.spec.ts +++ b/packages/client/test/rpc/eth/blobBaseFee.spec.ts @@ -9,6 +9,7 @@ import { getBlobs, hexToBytes, } from '@ethereumjs/util' +import { buildBlock } from '@ethereumjs/vm' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -38,7 +39,7 @@ const produceBlockWith4844Tx = async ( const parentBlock = await chain.getCanonicalHeadBlock() const vmCopy = await vm.shallowCopy() // Set block's gas used to max - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BigInt(1), diff --git a/packages/client/test/rpc/eth/call.spec.ts b/packages/client/test/rpc/eth/call.spec.ts index 4015e8a89f..802ed0639b 100644 --- a/packages/client/test/rpc/eth/call.spec.ts +++ b/packages/client/test/rpc/eth/call.spec.ts @@ -3,6 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' import { Address, bigIntToHex, bytesToHex } from '@ethereumjs/util' +import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -70,7 +71,7 @@ describe(method, () => { // deploy contract let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - const result = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) const { createdAddress } = result.results[0] await vm.blockchain.putBlock(ranBlock!) @@ -86,9 +87,8 @@ describe(method, () => { estimateTx.getSenderAddress = () => { return address } - const { execResult } = await ( - await vm.shallowCopy() - ).runTx({ + const vmCopy = await vm.shallowCopy() + const { execResult } = await runTx(vmCopy, { tx: estimateTx, skipNonce: true, skipBalance: true, diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index f93461d301..f009406c71 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -4,6 +4,7 @@ import { createCommonFromGethGenesis } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' +import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -79,7 +80,7 @@ describe( // deploy contract let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - const result = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) const { createdAddress } = result.results[0] await vm.blockchain.putBlock(ranBlock!) @@ -96,9 +97,8 @@ describe( estimateTx.getSenderAddress = () => { return address } - const { totalGasSpent } = await ( - await vm.shallowCopy() - ).runTx({ + const vmCopy = await vm.shallowCopy() + const { totalGasSpent } = await runTx(vmCopy, { tx: estimateTx, skipNonce: true, skipBalance: true, @@ -148,7 +148,7 @@ describe( ) vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block: londonBlock, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block: londonBlock, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) // Test EIP1559 tx diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index 57b4175155..e2f6a69dc0 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -54,7 +55,7 @@ describe( const block = createBlockFromBlockData({}, { common }) block.transactions[0] = tx - const result = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) const { amountSpent } = result.results[0] // verify balance is genesis amount minus amountSpent diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index 74c974f541..5a12f43f82 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -56,7 +57,7 @@ describe(method, () => { let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) // verify that the transaction count is 1 @@ -120,7 +121,7 @@ describe(method, () => { let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) // verify that the transaction count is 3 diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index 0e1419bb38..6d61d0f64f 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -83,7 +84,7 @@ describe(method, () => { // deploy contract let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - const result = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) const { createdAddress } = result.results[0] await vm.blockchain.putBlock(ranBlock!) diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index 926c13d76d..0dd66f9611 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -10,6 +10,7 @@ import { commitmentsToVersionedHashes, getBlobs, } from '@ethereumjs/util' +import { buildBlock } from '@ethereumjs/vm' import { hexToBytes } from 'ethereum-cryptography/utils' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -36,7 +37,7 @@ const produceFakeGasUsedBlock = async (execution: VMExecution, chain: Chain, gas const parentBlock = await chain.getCanonicalHeadBlock() const vmCopy = await vm.shallowCopy() // Set block's gas used to max - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BigInt(1), @@ -75,7 +76,7 @@ const produceBlockWithTx = async ( const parentBlock = await chain.getCanonicalHeadBlock() const vmCopy = await vm.shallowCopy() // Set block's gas used to max - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BigInt(1), @@ -132,7 +133,7 @@ const produceBlockWith4844Tx = async ( const parentBlock = await chain.getCanonicalHeadBlock() const vmCopy = await vm.shallowCopy() // Set block's gas used to max - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BigInt(1), diff --git a/packages/client/test/rpc/eth/getProof.spec.ts b/packages/client/test/rpc/eth/getProof.spec.ts index 9169ae06ce..644061fca3 100644 --- a/packages/client/test/rpc/eth/getProof.spec.ts +++ b/packages/client/test/rpc/eth/getProof.spec.ts @@ -3,6 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Common } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { createClient, createManager, getRpcClient, startRPC } from '../helpers.js' @@ -146,7 +147,7 @@ describe(method, async () => { // deploy contract let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - const result = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) const { createdAddress } = result.results[0] await vm.blockchain.putBlock(ranBlock!) @@ -178,7 +179,7 @@ describe(method, async () => { // run block let ranBlock2: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock2 = result.block)) - await vm.runBlock({ block: block2, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block: block2, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock2!) // verify proof is accurate diff --git a/packages/client/test/rpc/eth/getStorageAt.spec.ts b/packages/client/test/rpc/eth/getStorageAt.spec.ts index 0dada977d2..2163a276c6 100644 --- a/packages/client/test/rpc/eth/getStorageAt.spec.ts +++ b/packages/client/test/rpc/eth/getStorageAt.spec.ts @@ -1,6 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -47,7 +48,11 @@ describe(method, async () => { // deploy contract let ranBlock: Block | undefined = undefined execution.vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - const result = await execution.vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const result = await runBlock(execution.vm, { + block, + generate: true, + skipBlockValidation: true, + }) const { createdAddress } = result.results[0] await chain.putBlocks([ranBlock as unknown as Block]) diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 65426552d1..6cbd479db9 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction, createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, hexToBytes, randomBytes } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { createClient, createManager, getRpcClient, startRPC } from '../helpers.js' @@ -62,7 +63,7 @@ describe(method, () => { let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) // verify nonce increments after a tx diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index b3b6304b3c..1fa17f829c 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -9,6 +9,7 @@ import { hexToBytes, parseGethGenesisState, } from '@ethereumjs/util' +import { buildBlock } from '@ethereumjs/vm' import { Client, Server as RPCServer } from 'jayson/promise' import { MemoryLevel } from 'memory-level' import { assert } from 'vitest' @@ -285,7 +286,7 @@ export async function runBlockWithTxs( // build block with tx const parentBlock = await chain.getCanonicalHeadBlock() const vmCopy = await vm.shallowCopy() - const blockBuilder = await vmCopy.buildBlock({ + const blockBuilder = await buildBlock(vmCopy, { parentBlock, headerData: { timestamp: parentBlock.header.timestamp + BIGINT_1, diff --git a/packages/client/test/rpc/txpool/content.spec.ts b/packages/client/test/rpc/txpool/content.spec.ts index b653492104..d96485f403 100644 --- a/packages/client/test/rpc/txpool/content.spec.ts +++ b/packages/client/test/rpc/txpool/content.spec.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createTxFromTxData } from '@ethereumjs/tx' import { randomBytes } from '@ethereumjs/util' +import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' import { createClient, createManager, getRpcClient, startRPC } from '../helpers.js' @@ -44,7 +45,7 @@ describe(method, () => { let ranBlock: Block | undefined = undefined vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) const service = client.services[0] as FullEthereumService service.execution.vm.common.setHardfork('london') @@ -69,7 +70,7 @@ describe(method, () => { ) vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) - await vm.runBlock({ block: londonBlock, generate: true, skipBlockValidation: true }) + await runBlock(vm, { block: londonBlock, generate: true, skipBlockValidation: true }) await vm.blockchain.putBlock(ranBlock!) ;(service.txPool as any).validate = () => {} await service.txPool.add(createTxFromTxData({ type: 2 }, {}).sign(randomBytes(32))) diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 35d6be0e44..4ce1cc582f 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -32,6 +32,8 @@ import type { Address, PrefixedHexString } from '@ethereumjs/util' const debugGas = debugDefault('evm:gas') +let counter = 0 + export interface InterpreterOpts { pc?: number } @@ -337,6 +339,11 @@ export class Interpreter { * reducing its base gas cost, and increments the program counter. */ async runStep(opcodeObj?: OpcodeMapEntry): Promise { + counter += 1 + if (counter % 1000 === 0) { + console.log(counter) + } + const opEntry = opcodeObj ?? this.lookupOpInfo(this._runState.opCode) const opInfo = opEntry.opcodeInfo diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index bd1061fd33..bcdcb0f29c 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -13,7 +13,7 @@ import { setLengthLeft, utf8ToBytes, } from '@ethereumjs/util' -import { VM } from '@ethereumjs/vm' +import { VM, runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, expect, it, vi } from 'vitest' import { RPCBlockChain, RPCStateManager } from '../src/rpcStateManager.js' @@ -247,7 +247,7 @@ describe('runTx custom transaction test', () => { { common } ).sign(privateKey) - const result = await vm.runTx({ + const result = await runTx(vm, { skipBalance: true, skipNonce: true, tx, @@ -270,7 +270,7 @@ describe('runTx test: replay mainnet transactions', () => { blockTag: blockTag - 1n, }) const vm = await VM.create({ common, stateManager: state }) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.equal( res.totalGasSpent, 21000n, @@ -297,7 +297,7 @@ describe('runBlock test', () => { const vm = await VM.create({ common, stateManager: state }) const block = createBlockFromRPC(blockData as JsonRpcBlock, [], { common }) try { - const res = await vm.runBlock({ + const res = await runBlock(vm, { block, generate: true, skipHeaderValidation: true, diff --git a/packages/vm/benchmarks/mainnetBlocks.ts b/packages/vm/benchmarks/mainnetBlocks.ts index dc806da008..2cd6e069de 100644 --- a/packages/vm/benchmarks/mainnetBlocks.ts +++ b/packages/vm/benchmarks/mainnetBlocks.ts @@ -2,15 +2,13 @@ import { readFileSync } from 'fs' import Benchmark from 'benchmark' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Block, createBlockFromRPC } from '@ethereumjs/block' -import { VM } from '@ethereumjs/vm' +import { runBlock as runBlockVM, VM } from '@ethereumjs/vm' import { getPreState, getBlockchain, verifyResult } from './util.js' const BLOCK_FIXTURE = 'benchmarks/fixture/blocks-prestate.json' const runBlock = async (vm: VM, block: Block, receipts: any) => { - await ( - await vm.shallowCopy() - ).runBlock({ + await runBlockVM(await vm.shallowCopy(), { block, generate: true, skipBlockValidation: true, diff --git a/packages/vm/examples/buildBlock.ts b/packages/vm/examples/buildBlock.ts index 748a30ca14..f04d89a0e3 100644 --- a/packages/vm/examples/buildBlock.ts +++ b/packages/vm/examples/buildBlock.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' -import { VM } from '@ethereumjs/vm' +import { buildBlock, VM } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Chain.Mainnet }) @@ -15,7 +15,7 @@ const main = async () => { const headerData = { number: 2n, } - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock, // the parent @ethereumjs/block Block headerData, // header values for the new block blockOpts: { diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index 3d52b2d2e7..02f18cc383 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -20,7 +20,7 @@ import { } from '@ethereumjs/blockchain' import { Common, ConsensusAlgorithm, ConsensusType } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' -import { VM } from '@ethereumjs/vm' +import { runBlock, VM } from '@ethereumjs/vm' import testData from './helpers/blockchain-mock-data.json' @@ -51,7 +51,7 @@ async function main() { const parentBlock = await blockchain!.getBlock(block.header.parentHash) const parentState = parentBlock.header.stateRoot // run block - await vm.runBlock({ block, root: parentState, skipHardForkValidation: true }) + await runBlock(vm, { block, root: parentState, skipHardForkValidation: true }) }) const blockchainHead = await vm.blockchain.getIteratorHead!() diff --git a/packages/vm/examples/run-solidity-contract.ts b/packages/vm/examples/run-solidity-contract.ts index 88c4346c77..d490107fb9 100644 --- a/packages/vm/examples/run-solidity-contract.ts +++ b/packages/vm/examples/run-solidity-contract.ts @@ -5,7 +5,7 @@ import { defaultAbiCoder as AbiCoder, Interface } from '@ethersproject/abi' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' -import { VM } from '@ethereumjs/vm' +import { VM, runTx } from '@ethereumjs/vm' import { buildTransaction, encodeDeployment, encodeFunction } from './helpers/tx-builder.js' import { getAccountNonce, insertAccount } from './helpers/account-utils.js' import { createBlockFromBlockData } from '@ethereumjs/block' @@ -109,7 +109,7 @@ async function deployContract( senderPrivateKey ) - const deploymentResult = await vm.runTx({ tx, block }) + const deploymentResult = await runTx(vm, { tx, block }) if (deploymentResult.execResult.exceptionError) { throw deploymentResult.execResult.exceptionError @@ -139,7 +139,7 @@ async function setGreeting( senderPrivateKey ) - const setGreetingResult = await vm.runTx({ tx, block }) + const setGreetingResult = await runTx(vm, { tx, block }) if (setGreetingResult.execResult.exceptionError) { throw setGreetingResult.execResult.exceptionError diff --git a/packages/vm/examples/runGoerliBlock.ts b/packages/vm/examples/runGoerliBlock.ts index a10bb06692..4f821fcdcb 100644 --- a/packages/vm/examples/runGoerliBlock.ts +++ b/packages/vm/examples/runGoerliBlock.ts @@ -3,13 +3,14 @@ import { Chain, Common } from '@ethereumjs/common' import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { VM } from '../src/vm.js' import goerliBlock2 from './testData/goerliBlock2.json' +import { runBlock } from '../src/index.js' const main = async () => { const common = new Common({ chain: Chain.Goerli, hardfork: 'london' }) const vm = await VM.create({ common, setHardfork: true }) const block = createBlockFromRPC(goerliBlock2, undefined, { common }) - const result = await vm.runBlock({ block, generate: true, skipHeaderValidation: true }) // we skip header validaiton since we are running a block without the full Ethereum history available + const result = await runBlock(vm, { block, generate: true, skipHeaderValidation: true }) // we skip header validaiton 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)}`) } diff --git a/packages/vm/examples/runTx.ts b/packages/vm/examples/runTx.ts index 5178d5cf6f..6ee7cf745c 100644 --- a/packages/vm/examples/runTx.ts +++ b/packages/vm/examples/runTx.ts @@ -1,7 +1,7 @@ import { Address } from '@ethereumjs/util' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' -import { VM } from '@ethereumjs/vm' +import { runTx, VM } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) @@ -16,7 +16,7 @@ const main = async () => { r: BigInt('62886504200765677832366398998081608852310526822767264927793100349258111544447'), s: BigInt('21948396863567062449199529794141973192314514851405455194940751428901681436138'), }) - const res = await vm.runTx({ tx, skipBalance: true }) + const res = await runTx(vm, { tx, skipBalance: true }) console.log(res.totalGasSpent) // 21000n - gas cost for simple ETH transfer } diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 984ff7fbf5..28b034dc60 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -32,6 +32,8 @@ import { rewardAccount, } from './runBlock.js' +import { runTx } from './index.js' + import type { BuildBlockOpts, BuilderOpts, RunTxResult, SealBlockOpts } from './types.js' import type { VM } from './vm.js' import type { Block, HeaderData } from '@ethereumjs/block' @@ -256,7 +258,7 @@ export class BlockBuilder { const blockData = { header, transactions: this.transactions } const block = createBlockFromBlockData(blockData, this.blockOpts) - const result = await this.vm.runTx({ tx, block, skipHardForkValidation }) + const result = await runTx(this.vm, { tx, block, skipHardForkValidation }) // If tx is a blob transaction, remove blobs/kzg commitments before adding to block per EIP-4844 if (tx instanceof BlobEIP4844Transaction) { @@ -388,7 +390,7 @@ export class BlockBuilder { const parentBeaconBlockRootBuf = toType(parentBeaconBlockRoot!, TypeOutput.Uint8Array) ?? zeros(32) - await accumulateParentBeaconBlockRoot.bind(this.vm)(parentBeaconBlockRootBuf, timestampBigInt) + await accumulateParentBeaconBlockRoot(this.vm, parentBeaconBlockRootBuf, timestampBigInt) } if (this.vm.common.isActivatedEIP(2935)) { if (!this.checkpointed) { @@ -401,13 +403,28 @@ export class BlockBuilder { const numberBigInt = toType(number ?? 0, TypeOutput.BigInt) const parentHashSanitized = toType(parentHash, TypeOutput.Uint8Array) ?? zeros(32) - await accumulateParentBlockHash.bind(this.vm)(numberBigInt, parentHashSanitized) + await accumulateParentBlockHash(this.vm, numberBigInt, parentHashSanitized) } } } -export async function buildBlock(this: VM, opts: BuildBlockOpts): Promise { - const blockBuilder = new BlockBuilder(this, opts) +/** + * Build a block on top of the current state + * by adding one transaction at a time. + * + * Creates a checkpoint on the StateManager and modifies the state + * as transactions are run. The checkpoint is committed on {@link BlockBuilder.build} + * or discarded with {@link BlockBuilder.revert}. + * + * @param {VM} vm + * @param {BuildBlockOpts} opts + * @returns An instance of {@link BlockBuilder} with methods: + * - {@link BlockBuilder.addTransaction} + * - {@link BlockBuilder.build} + * - {@link BlockBuilder.revert} + */ +export async function buildBlock(vm: VM, opts: BuildBlockOpts): Promise { + const blockBuilder = new BlockBuilder(vm, opts) await blockBuilder.initState() return blockBuilder } diff --git a/packages/vm/src/emitEVMProfile.ts b/packages/vm/src/emitEVMProfile.ts new file mode 100644 index 0000000000..819874c027 --- /dev/null +++ b/packages/vm/src/emitEVMProfile.ts @@ -0,0 +1,151 @@ +import type { EVMPerformanceLogOutput } from '@ethereumjs/evm' + +/** + * Emit EVM profile logs + * @param logs + * @param profileTitle + * @hidden + */ +export function emitEVMProfile(logs: EVMPerformanceLogOutput[], profileTitle: string) { + if (logs.length === 0) { + return + } + + // Track total calls / time (ms) / gas + + let calls = 0 + let totalMs = 0 + let totalGas = 0 + + // Order of columns to report (see `EVMPerformanceLogOutput` type) + + const colOrder: (keyof EVMPerformanceLogOutput)[] = [ + 'tag', + 'calls', + 'avgTimePerCall', + 'totalTime', + 'staticGasUsed', + 'dynamicGasUsed', + 'gasUsed', + 'staticGas', + 'millionGasPerSecond', + 'blocksPerSlot', + ] + + // The name of this column to report (saves space) + const colNames = [ + 'tag', + 'calls', + 'ms/call', + 'total (ms)', + 'sgas', + 'dgas', + 'total (s+d)', + 'static fee', + 'Mgas/s', + 'BpS', + ] + + // Special padStr method which inserts whitespace left and right + // This ensures that there is at least one whitespace between the columns (denoted by pipe `|` chars) + function padStr(str: string | number, leftpad: number) { + return ' ' + str.toString().padStart(leftpad, ' ') + ' ' + } + // Returns the string length of this column. Used to calculate how big the header / footer should be + function strLen(str: string | number) { + return padStr(str, 0).length - 2 + } + + // Step one: calculate the length of each colum + const colLength: number[] = [] + + for (const entry of logs) { + let ins = 0 + colLength[ins] = Math.max(colLength[ins] ?? 0, strLen(colNames[ins])) + for (const key of colOrder) { + if (entry[key] !== undefined) { + // If entry is available, max out the current column length (this will be the longest string of this column) + colLength[ins] = Math.max(colLength[ins] ?? 0, strLen(entry[key]!)) + ins++ + // In this switch statement update the total calls / time / gas used + switch (key) { + case 'calls': + calls += entry[key] + break + case 'totalTime': + totalMs += entry[key] + break + case 'gasUsed': + totalGas += entry[key] + break + } + } + } + } + + // Ensure that the column names also fit on the column length + for (const i in colLength) { + colLength[i] = Math.max(colLength[i] ?? 0, strLen(colNames[i])) + } + + // Calculate the total header length + // This is done by summing all columns together, plus adding three extra chars per column (two whitespace, one pipe) + // Remove the final pipe character since this is included in the header string (so subtract one) + const headerLength = colLength.reduce((pv, cv) => pv + cv, 0) + colLength.length * 3 - 1 + + const blockGasLimit = 30_000_000 // Block gas limit + const slotTime = 12000 // Time in milliseconds (!) per slot + + // Normalize constant to check if execution time is above one block per slot (>=1) or not (<1) + const bpsNormalizer = blockGasLimit / slotTime + + const avgGas = totalGas / totalMs // Gas per millisecond + const mGasSAvg = Math.round(avgGas) / 1e3 + const bpSAvg = Math.round((avgGas / bpsNormalizer) * 1e3) / 1e3 + + // Write the profile title + // eslint-disable-next-line + console.log('+== ' + profileTitle + ' ==+') + // Write the summary of this profile + // eslint-disable-next-line + console.log( + `+== Calls: ${calls}, Total time: ${ + Math.round(totalMs * 1e3) / 1e3 + }ms, Total gas: ${totalGas}, MGas/s: ${mGasSAvg}, Blocks per Slot (BpS): ${bpSAvg} ==+` + ) + + // Generate and write the header + const header = '|' + '-'.repeat(headerLength) + '|' + // eslint-disable-next-line + console.log(header) + + // Write the columns + let str = '' + for (const i in colLength) { + str += '|' + padStr(colNames[i], colLength[i]) + } + str += '|' + + // eslint-disable-next-line + console.log(str) + + // Write each profile entry + for (const entry of logs) { + let str = '' + let i = 0 + for (const key of colOrder) { + if (entry[key] !== undefined) { + str += '|' + padStr(entry[key]!, colLength[i]) + i++ + } + } + str += '|' + // eslint-disable-next-line + console.log(str) + } + + // Finally, write the footer + const footer = '+' + '-'.repeat(headerLength) + '+' + // eslint-disable-next-line + console.log(footer) +} diff --git a/packages/vm/src/index.ts b/packages/vm/src/index.ts index 715030b3d0..15f81d9347 100644 --- a/packages/vm/src/index.ts +++ b/packages/vm/src/index.ts @@ -1,5 +1,8 @@ export { Bloom } from './bloom/index.js' export { BlockBuilder, BuildStatus } from './buildBlock.js' +export { buildBlock } from './buildBlock.js' export { encodeReceipt } from './runBlock.js' +export { runBlock } from './runBlock.js' +export { runTx } from './runTx.js' export * from './types.js' export { VM } from './vm.js' diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 206b097b2c..8d43cb381f 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -27,8 +27,11 @@ import { import debugDefault from 'debug' import { Bloom } from './bloom/index.js' +import { emitEVMProfile } from './emitEVMProfile.js' import { accumulateRequests } from './requests.js' +import { runTx } from './index.js' + import type { AfterBlockEvent, ApplyBlockResult, @@ -58,16 +61,24 @@ const withdrawalsRewardsCommitLabel = 'Withdrawals, Rewards, EVM journal commit' const entireBlockLabel = 'Entire block' /** - * @ignore + * Processes the `block` running all of the transactions it contains and updating the miner's account + * + * vm method modifies the state. If `generate` is `true`, the state modifications will be + * reverted if an exception is raised. If it's `false`, it won't revert if the block's header is + * invalid. If an error is thrown from an event handler, the state may or may not be reverted. + * + * @param {VM} vm + * @param {RunBlockOpts} opts - Default values for options: + * - `generate`: false */ -export async function runBlock(this: VM, opts: RunBlockOpts): Promise { - if (this._opts.profilerOpts?.reportAfterBlock === true) { +export async function runBlock(vm: VM, opts: RunBlockOpts): Promise { + if (vm['_opts'].profilerOpts?.reportAfterBlock === true) { enableProfiler = true // eslint-disable-next-line no-console console.time(entireBlockLabel) } - const stateManager = this.stateManager + const stateManager = vm.stateManager const { root } = opts const clearCache = opts.clearCache ?? true @@ -92,17 +103,17 @@ export async function runBlock(this: VM, opts: RunBlockOpts): Promise[] | undefined if (block.common.isActivatedEIP(7685)) { - requests = await accumulateRequests(this, result.results) + requests = await accumulateRequests(vm, result.results) requestsRoot = await genRequestsTrieRoot(requests) } // Persist state - await this.evm.journal.commit() - if (this.DEBUG) { + await vm.evm.journal.commit() + if (vm.DEBUG) { debug(`block checkpoint committed`) } @@ -243,55 +254,55 @@ export async function runBlock(this: VM, opts: RunBlockOpts): Promisethis.evm).getPerformanceLogs() + const logs = (vm.evm).getPerformanceLogs() if (logs.precompiles.length === 0 && logs.opcodes.length === 0) { // eslint-disable-next-line no-console console.log('No block txs with precompile or opcode execution.') } - this.emitEVMProfile(logs.precompiles, 'Precompile performance') - this.emitEVMProfile(logs.opcodes, 'Opcodes performance') - ;(this.evm).clearPerformanceLogs() + emitEVMProfile(logs.precompiles, 'Precompile performance') + emitEVMProfile(logs.opcodes, 'Opcodes performance') + ;(vm.evm).clearPerformanceLogs() } return results @@ -370,26 +381,26 @@ export async function runBlock(this: VM, opts: RunBlockOpts): Promise { +async function applyBlock(vm: VM, block: Block, opts: RunBlockOpts): Promise { // Validate block if (opts.skipBlockValidation !== true) { if (block.header.gasLimit >= BigInt('0x8000000000000000')) { - const msg = _errorMsg('Invalid block with gas limit greater than (2^63 - 1)', this, block) + const msg = _errorMsg('Invalid block with gas limit greater than (2^63 - 1)', vm, block) throw new Error(msg) } else { - if (this.DEBUG) { + if (vm.DEBUG) { debug(`Validate block`) } // TODO: decide what block validation method is appropriate here if (opts.skipHeaderValidation !== true) { - if (typeof (this.blockchain).validateHeader === 'function') { - await (this.blockchain).validateHeader(block.header) + if (typeof (vm.blockchain).validateHeader === 'function') { + await (vm.blockchain).validateHeader(block.header) } else { throw new Error('cannot validate header: blockchain has no `validateHeader` method') } @@ -397,21 +408,22 @@ async function applyBlock(this: VM, block: Block, opts: RunBlockOpts): Promise ${gasUsed})`) } @@ -665,7 +673,7 @@ async function applyTransactions(this: VM, block: Block, opts: RunBlockOpts) { } } -async function assignWithdrawals(this: VM, block: Block): Promise { +async function assignWithdrawals(vm: VM, block: Block): Promise { const withdrawals = block.withdrawals! for (const withdrawal of withdrawals) { const { address, amount } = withdrawal @@ -673,7 +681,7 @@ async function assignWithdrawals(this: VM, block: Block): Promise { // converted to wei // Note: event if amount is 0, still reward the account // such that the account is touched and marked for cleanup if it is empty - await rewardAccount(this.evm, address, amount * GWEI_TO_WEI, this.common) + await rewardAccount(vm.evm, address, amount * GWEI_TO_WEI, vm.common) } } @@ -681,24 +689,24 @@ async function assignWithdrawals(this: VM, block: Block): Promise { * Calculates block rewards for miner and ommers and puts * the updated balances of their accounts to state. */ -async function assignBlockRewards(this: VM, block: Block): Promise { - if (this.DEBUG) { +async function assignBlockRewards(vm: VM, block: Block): Promise { + if (vm.DEBUG) { debug(`Assign block rewards`) } - const minerReward = this.common.param('pow', 'minerReward') + const minerReward = vm.common.param('pow', 'minerReward') const ommers = block.uncleHeaders // Reward ommers for (const ommer of ommers) { const reward = calculateOmmerReward(ommer.number, block.header.number, minerReward) - const account = await rewardAccount(this.evm, ommer.coinbase, reward, this.common) - if (this.DEBUG) { + const account = await rewardAccount(vm.evm, ommer.coinbase, reward, vm.common) + if (vm.DEBUG) { debug(`Add uncle reward ${reward} to account ${ommer.coinbase} (-> ${account.balance})`) } } // Reward miner const reward = calculateMinerReward(minerReward, ommers.length) - const account = await rewardAccount(this.evm, block.header.coinbase, reward, this.common) - if (this.DEBUG) { + const account = await rewardAccount(vm.evm, block.header.coinbase, reward, vm.common) + if (vm.DEBUG) { debug(`Add miner reward ${reward} to account ${block.header.coinbase} (-> ${account.balance})`) } } @@ -743,7 +751,7 @@ export async function rewardAccount( await evm.journal.putAccount(address, account) if (common?.isActivatedEIP(6800) === true) { - // use this utility to build access but the computed gas is not charged and hence free + // use vm utility to build access but the computed gas is not charged and hence free ;(evm.stateManager as StatelessVerkleStateManager).accessWitness!.touchTxTargetAndComputeGas( address, { sendsValue: true } diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 10c2217f4b..8d7c5b2c32 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -22,6 +22,7 @@ import debugDefault from 'debug' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { Bloom } from './bloom/index.js' +import { emitEVMProfile } from './emitEVMProfile.js' import type { AfterTxEvent, @@ -77,10 +78,17 @@ function execHardfork( } /** - * @ignore + * Process a transaction. Run the vm. Transfers eth. Checks balances. + * + * This method modifies the state. If an error is thrown, the modifications are reverted, except + * when the error is thrown from an event handler. In the latter case the state may or may not be + * reverted. + * + * @param {VM} vm + * @param {RunTxOpts} opts */ -export async function runTx(this: VM, opts: RunTxOpts): Promise { - if (this._opts.profilerOpts?.reportAfterTx === true) { +export async function runTx(vm: VM, opts: RunTxOpts): Promise { + if (vm['_opts'].profilerOpts?.reportAfterTx === true) { enableProfiler = true } @@ -95,11 +103,11 @@ export async function runTx(this: VM, opts: RunTxOpts): Promise { } // create a reasonable default if no block is given - opts.block = opts.block ?? createBlockFromBlockData({}, { common: this.common }) + opts.block = opts.block ?? createBlockFromBlockData({}, { common: vm.common }) if (opts.skipHardForkValidation !== true) { // Find and set preMerge hf for easy access later - const hfs = this.common.hardforks() + const hfs = vm.common.hardforks() const preMergeIndex = hfs.findIndex((hf) => hf.ttd !== null && hf.ttd !== undefined) - 1 // If no pre merge hf found, set it to first hf even if its merge const preMergeHf = preMergeIndex >= 0 ? hfs[preMergeIndex].name : hfs[0].name @@ -113,54 +121,54 @@ export async function runTx(this: VM, opts: RunTxOpts): Promise { } if ( execHardfork(opts.block.common.hardfork(), preMergeHf) !== - execHardfork(this.common.hardfork(), preMergeHf) + execHardfork(vm.common.hardfork(), preMergeHf) ) { // Block and VM's hardfork should match as well - const msg = _errorMsg('block has a different hardfork than the vm', this, opts.block, opts.tx) + const msg = _errorMsg('block has a different hardfork than the vm', vm, opts.block, opts.tx) throw new Error(msg) } } if (opts.skipBlockGasLimitValidation !== true && opts.block.header.gasLimit < opts.tx.gasLimit) { - const msg = _errorMsg('tx has a higher gas limit than the block', this, opts.block, opts.tx) + const msg = _errorMsg('tx has a higher gas limit than the block', vm, opts.block, opts.tx) throw new Error(msg) } // Ensure we start with a clear warmed accounts Map - await this.evm.journal.cleanup() + await vm.evm.journal.cleanup() if (opts.reportAccessList === true) { - this.evm.journal.startReportingAccessList() + vm.evm.journal.startReportingAccessList() } if (opts.reportPreimages === true) { - this.evm.journal.startReportingPreimages!() + vm.evm.journal.startReportingPreimages!() } - await this.evm.journal.checkpoint() - if (this.DEBUG) { + await vm.evm.journal.checkpoint() + if (vm.DEBUG) { debug('-'.repeat(100)) debug(`tx checkpoint`) } // Typed transaction specific setup tasks - if (opts.tx.supports(Capability.EIP2718TypedTransaction) && this.common.isActivatedEIP(2718)) { + if (opts.tx.supports(Capability.EIP2718TypedTransaction) && vm.common.isActivatedEIP(2718)) { // Is it an Access List transaction? - if (!this.common.isActivatedEIP(2930)) { - await this.evm.journal.revert() + if (!vm.common.isActivatedEIP(2930)) { + await vm.evm.journal.revert() const msg = _errorMsg( 'Cannot run transaction: EIP 2930 is not activated.', - this, + vm, opts.block, opts.tx ) throw new Error(msg) } - if (opts.tx.supports(Capability.EIP1559FeeMarket) && !this.common.isActivatedEIP(1559)) { - await this.evm.journal.revert() + if (opts.tx.supports(Capability.EIP1559FeeMarket) && !vm.common.isActivatedEIP(1559)) { + await vm.evm.journal.revert() const msg = _errorMsg( 'Cannot run transaction: EIP 1559 is not activated.', - this, + vm, opts.block, opts.tx ) @@ -170,55 +178,55 @@ export async function runTx(this: VM, opts: RunTxOpts): Promise { const castedTx = opts.tx for (const accessListItem of castedTx.AccessListJSON) { - this.evm.journal.addAlwaysWarmAddress(accessListItem.address, true) + vm.evm.journal.addAlwaysWarmAddress(accessListItem.address, true) for (const storageKey of accessListItem.storageKeys) { - this.evm.journal.addAlwaysWarmSlot(accessListItem.address, storageKey, true) + vm.evm.journal.addAlwaysWarmSlot(accessListItem.address, storageKey, true) } } } try { - const result = await _runTx.bind(this)(opts) - await this.evm.journal.commit() - if (this.DEBUG) { + const result = await _runTx(vm, opts) + await vm.evm.journal.commit() + if (vm.DEBUG) { debug(`tx checkpoint committed`) } return result } catch (e: any) { - await this.evm.journal.revert() - if (this.DEBUG) { + await vm.evm.journal.revert() + if (vm.DEBUG) { debug(`tx checkpoint reverted`) } throw e } finally { - if (this.common.isActivatedEIP(2929)) { - this.evm.journal.cleanJournal() + if (vm.common.isActivatedEIP(2929)) { + vm.evm.journal.cleanJournal() } - this.evm.stateManager.originalStorageCache.clear() + vm.evm.stateManager.originalStorageCache.clear() if (enableProfiler) { // eslint-disable-next-line no-console console.timeEnd(entireTxLabel) - const logs = (this.evm).getPerformanceLogs() + const logs = (vm.evm).getPerformanceLogs() if (logs.precompiles.length === 0 && logs.opcodes.length === 0) { // eslint-disable-next-line no-console console.log('No precompile or opcode execution.') } - this.emitEVMProfile(logs.precompiles, 'Precompile performance') - this.emitEVMProfile(logs.opcodes, 'Opcodes performance') - ;(this.evm).clearPerformanceLogs() + emitEVMProfile(logs.precompiles, 'Precompile performance') + emitEVMProfile(logs.opcodes, 'Opcodes performance') + ;(vm.evm).clearPerformanceLogs() } } } -async function _runTx(this: VM, opts: RunTxOpts): Promise { - const state = this.stateManager +async function _runTx(vm: VM, opts: RunTxOpts): Promise { + const state = vm.stateManager let stateAccesses - if (this.common.isActivatedEIP(6800)) { - if (!(this.stateManager instanceof StatelessVerkleStateManager)) { + if (vm.common.isActivatedEIP(6800)) { + if (!(vm.stateManager instanceof StatelessVerkleStateManager)) { throw Error(`StatelessVerkleStateManager needed for execution of verkle blocks`) } - stateAccesses = (this.stateManager as StatelessVerkleStateManager).accessWitness + stateAccesses = (vm.stateManager as StatelessVerkleStateManager).accessWitness } const txAccesses = stateAccesses?.shallowCopy() @@ -235,10 +243,10 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { * @type {Object} * @property {Transaction} tx emits the Transaction that is about to be processed */ - await this._emit('beforeTx', tx) + await vm._emit('beforeTx', tx) const caller = tx.getSenderAddress() - if (this.DEBUG) { + if (vm.DEBUG) { debug( `New tx run hash=${ opts.tx.isSigned() ? bytesToHex(opts.tx.hash()) : 'unsigned' @@ -246,19 +254,19 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { ) } - if (this.common.isActivatedEIP(2929)) { + if (vm.common.isActivatedEIP(2929)) { // Add origin and precompiles to warm addresses - const activePrecompiles = this.evm.precompiles + const activePrecompiles = vm.evm.precompiles for (const [addressStr] of activePrecompiles.entries()) { - this.evm.journal.addAlwaysWarmAddress(addressStr) + vm.evm.journal.addAlwaysWarmAddress(addressStr) } - this.evm.journal.addAlwaysWarmAddress(caller.toString()) + vm.evm.journal.addAlwaysWarmAddress(caller.toString()) if (tx.to !== undefined) { - // Note: in case we create a contract, we do this in EVMs `_executeCreate` (this is also correct in inner calls, per the EIP) - this.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(tx.to.bytes)) + // Note: in case we create a contract, we do vm in EVMs `_executeCreate` (vm is also correct in inner calls, per the EIP) + vm.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(tx.to.bytes)) } - if (this.common.isActivatedEIP(3651)) { - this.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(block.header.coinbase.bytes)) + if (vm.common.isActivatedEIP(3651)) { + vm.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(block.header.coinbase.bytes)) } } @@ -270,18 +278,18 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { `tx gas limit ${Number(gasLimit)} is lower than the minimum gas limit of ${Number( txBaseFee )}`, - this, + vm, block, tx ) throw new Error(msg) } gasLimit -= txBaseFee - if (this.DEBUG) { + if (vm.DEBUG) { debugGas(`Subtracting base fee (${txBaseFee}) from gasLimit (-> ${gasLimit})`) } - if (this.common.isActivatedEIP(1559)) { + if (vm.common.isActivatedEIP(1559)) { // EIP-1559 spec: // Ensure that the user was willing to at least pay the base fee // assert transaction.max_fee_per_gas >= block.base_fee_per_gas @@ -292,7 +300,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { `Transaction's ${ 'maxFeePerGas' in tx ? 'maxFeePerGas' : 'gasPrice' } (${maxFeePerGas}) is less than the block's baseFeePerGas (${baseFeePerGas})`, - this, + vm, block, tx ) @@ -312,12 +320,12 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { fromAccount = new Account() } const { nonce, balance } = fromAccount - if (this.DEBUG) { + if (vm.DEBUG) { debug(`Sender's pre-tx balance is ${balance}`) } // EIP-3607: Reject transactions from senders with deployed code - if (this.common.isActivatedEIP(3607) && !equalsBytes(fromAccount.codeHash, KECCAK256_NULL)) { - const msg = _errorMsg('invalid sender address, address is not EOA (EIP-3607)', this, block, tx) + if (vm.common.isActivatedEIP(3607) && !equalsBytes(fromAccount.codeHash, KECCAK256_NULL)) { + const msg = _errorMsg('invalid sender address, address is not EOA (EIP-3607)', vm, block, tx) throw new Error(msg) } @@ -328,12 +336,12 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (tx.supports(Capability.EIP1559FeeMarket) === false) { // if skipBalance and not EIP1559 transaction, ensure caller balance is enough to run transaction fromAccount.balance = upFrontCost - await this.evm.journal.putAccount(caller, fromAccount) + await vm.evm.journal.putAccount(caller, fromAccount) } } else { const msg = _errorMsg( `sender doesn't have enough funds to send tx. The upfront cost is: ${upFrontCost} and the sender's account (${caller}) only has: ${balance}`, - this, + vm, block, tx ) @@ -353,8 +361,8 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { } if (tx instanceof BlobEIP4844Transaction) { - if (!this.common.isActivatedEIP(4844)) { - const msg = _errorMsg('blob transactions are only valid with EIP4844 active', this, block, tx) + if (!vm.common.isActivatedEIP(4844)) { + const msg = _errorMsg('blob transactions are only valid with EIP4844 active', vm, block, tx) throw new Error(msg) } // EIP-4844 spec @@ -368,7 +376,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (opts.block === undefined) { const msg = _errorMsg( `Block option must be supplied to compute blob gas price`, - this, + vm, block, tx ) @@ -378,7 +386,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (castTx.maxFeePerBlobGas < blobGasPrice) { const msg = _errorMsg( `Transaction's maxFeePerBlobGas ${castTx.maxFeePerBlobGas}) is less than block blobGasPrice (${blobGasPrice}).`, - this, + vm, block, tx ) @@ -390,11 +398,11 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (opts.skipBalance === true && fromAccount.balance < maxCost) { // if skipBalance, ensure caller balance is enough to run transaction fromAccount.balance = maxCost - await this.evm.journal.putAccount(caller, fromAccount) + await vm.evm.journal.putAccount(caller, fromAccount) } else { const msg = _errorMsg( `sender doesn't have enough funds to send tx. The max cost is: ${maxCost} and the sender's account (${caller}) only has: ${balance}`, - this, + vm, block, tx ) @@ -406,7 +414,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (nonce !== tx.nonce) { const msg = _errorMsg( `the tx doesn't have the correct nonce. account has nonce of: ${nonce} tx has nonce of: ${tx.nonce}`, - this, + vm, block, tx ) @@ -426,7 +434,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { } else { // Have to cast as legacy tx since EIP1559 tx does not have gas price gasPrice = (tx).gasPrice - if (this.common.isActivatedEIP(1559)) { + if (vm.common.isActivatedEIP(1559)) { const baseFee = block.header.baseFeePerGas! inclusionFeePerGas = (tx).gasPrice - baseFee } @@ -446,7 +454,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (opts.skipBalance === true && fromAccount.balance < BIGINT_0) { fromAccount.balance = BIGINT_0 } - await this.evm.journal.putAccount(caller, fromAccount) + await vm.evm.journal.putAccount(caller, fromAccount) const writtenAddresses = new Set() if (tx.supports(Capability.EIP7702EOACode)) { @@ -458,7 +466,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { const data = authorizationList[i] const chainId = data[0] const chainIdBN = bytesToBigInt(chainId) - if (chainIdBN !== BIGINT_0 && chainIdBN !== this.common.chainId()) { + if (chainIdBN !== BIGINT_0 && chainIdBN !== vm.common.chainId()) { // Chain id does not match, continue continue } @@ -474,11 +482,11 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { const pubKey = ecrecover(toSign, yParity, r, s) // Address to set code to const authority = new Address(publicToAddress(pubKey)) - const account = (await this.stateManager.getAccount(authority)) ?? new Account() + const account = (await vm.stateManager.getAccount(authority)) ?? new Account() if (account.isContract()) { - // Note: this also checks if the code has already been set once by a previous tuple - // So, if there are multiply entires for the same address, then this is fine + // Note: vm also checks if the code has already been set once by a previous tuple + // So, if there are multiply entires for the same address, then vm is fine continue } if (nonceList.length !== 0 && account.nonce !== bytesToBigInt(nonceList[0])) { @@ -486,15 +494,15 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { } const addressConverted = new Address(address) - const addressCode = await this.stateManager.getContractCode(addressConverted) - await this.stateManager.putContractCode(authority, addressCode) + const addressCode = await vm.stateManager.getContractCode(addressConverted) + await vm.stateManager.putContractCode(authority, addressCode) writtenAddresses.add(authority.toString()) - this.evm.journal.addAlwaysWarmAddress(authority.toString()) + vm.evm.journal.addAlwaysWarmAddress(authority.toString()) } } - if (this.DEBUG) { + if (vm.DEBUG) { debug(`Update fromAccount (caller) balance (-> ${fromAccount.balance}))`) } let executionTimerPrecise: number @@ -509,7 +517,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { */ const { value, data, to } = tx - if (this.DEBUG) { + if (vm.DEBUG) { debug( `Running tx=${ tx.isSigned() ? bytesToHex(tx.hash()) : 'unsigned' @@ -519,7 +527,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { ) } - const results = (await this.evm.runCall({ + const results = (await vm.evm.runCall({ block, gasPrice, caller, @@ -531,7 +539,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { accessWitness: txAccesses, })) as RunTxResult - if (this.common.isActivatedEIP(6800)) { + if (vm.common.isActivatedEIP(6800)) { stateAccesses?.merge(txAccesses!) } @@ -544,11 +552,11 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { console.time(logsGasBalanceLabel) } - if (this.DEBUG) { + if (vm.DEBUG) { debug(`Update fromAccount (caller) nonce (-> ${fromAccount.nonce})`) } - if (this.DEBUG) { + if (vm.DEBUG) { const { executionGasUsed, exceptionError, returnValue } = results.execResult debug('-'.repeat(100)) debug( @@ -562,14 +570,14 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { * Parse results */ // Generate the bloom for the tx - results.bloom = txLogsBloom(results.execResult.logs, this.common) - if (this.DEBUG) { + results.bloom = txLogsBloom(results.execResult.logs, vm.common) + if (vm.DEBUG) { debug(`Generated tx bloom with logs=${results.execResult.logs?.length}`) } // Calculate the total gas used results.totalGasSpent = results.execResult.executionGasUsed + txBaseFee - if (this.DEBUG) { + if (vm.DEBUG) { debugGas(`tx add baseFee ${txBaseFee} to totalGasSpent (-> ${results.totalGasSpent})`) } @@ -581,16 +589,16 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Process any gas refund let gasRefund = results.execResult.gasRefund ?? BIGINT_0 results.gasRefund = gasRefund - const maxRefundQuotient = this.common.param('gasConfig', 'maxRefundQuotient') + const maxRefundQuotient = vm.common.param('gasConfig', 'maxRefundQuotient') if (gasRefund !== BIGINT_0) { const maxRefund = results.totalGasSpent / maxRefundQuotient gasRefund = gasRefund < maxRefund ? gasRefund : maxRefund results.totalGasSpent -= gasRefund - if (this.DEBUG) { + if (vm.DEBUG) { debug(`Subtract tx gasRefund (${gasRefund}) from totalGasSpent (-> ${results.totalGasSpent})`) } } else { - if (this.DEBUG) { + if (vm.DEBUG) { debug(`No tx gasRefund`) } } @@ -604,8 +612,8 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { const actualTxCost = results.totalGasSpent * gasPrice const txCostDiff = txCost - actualTxCost fromAccount.balance += txCostDiff - await this.evm.journal.putAccount(caller, fromAccount) - if (this.DEBUG) { + await vm.evm.journal.putAccount(caller, fromAccount) + if (vm.DEBUG) { debug( `Refunded txCostDiff (${txCostDiff}) to fromAccount (caller) balance (-> ${fromAccount.balance})` ) @@ -613,7 +621,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Update miner's balance let miner - if (this.common.consensusType() === ConsensusType.ProofOfAuthority) { + if (vm.common.consensusType() === ConsensusType.ProofOfAuthority) { miner = block.header.cliqueSigner() } else { miner = block.header.coinbase @@ -621,29 +629,29 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { let minerAccount = await state.getAccount(miner) if (minerAccount === undefined) { - if (this.common.isActivatedEIP(6800)) { + if (vm.common.isActivatedEIP(6800)) { ;(state as StatelessVerkleStateManager).accessWitness!.touchAndChargeProofOfAbsence(miner) } minerAccount = new Account() } // add the amount spent on gas to the miner's account - results.minerValue = this.common.isActivatedEIP(1559) + results.minerValue = vm.common.isActivatedEIP(1559) ? results.totalGasSpent * inclusionFeePerGas! : results.amountSpent minerAccount.balance += results.minerValue - if (this.common.isActivatedEIP(6800)) { - // use this utility to build access but the computed gas is not charged and hence free + if (vm.common.isActivatedEIP(6800)) { + // use vm utility to build access but the computed gas is not charged and hence free ;(state as StatelessVerkleStateManager).accessWitness!.touchTxTargetAndComputeGas(miner, { sendsValue: true, }) } // Put the miner account into the state. If the balance of the miner account remains zero, note that - // the state.putAccount function puts this into the "touched" accounts. This will thus be removed when + // the state.putAccount function puts vm into the "touched" accounts. This will thus be removed when // we clean the touched accounts below in case we are in a fork >= SpuriousDragon - await this.evm.journal.putAccount(miner, minerAccount) - if (this.DEBUG) { + await vm.evm.journal.putAccount(miner, minerAccount) + if (vm.DEBUG) { debug(`tx update miner account (${miner}) balance (-> ${minerAccount.balance})`) } @@ -660,14 +668,14 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (results.execResult.selfdestruct !== undefined) { for (const addressToSelfdestructHex of results.execResult.selfdestruct) { const address = new Address(hexToBytes(addressToSelfdestructHex)) - if (this.common.isActivatedEIP(6780)) { + if (vm.common.isActivatedEIP(6780)) { // skip cleanup of addresses not in createdAddresses if (!results.execResult.createdAddresses!.has(address.toString())) { continue } } - await this.evm.journal.deleteAccount(address) - if (this.DEBUG) { + await vm.evm.journal.deleteAccount(address) + if (vm.DEBUG) { debug(`tx selfdestruct on address=${address}`) } } @@ -679,7 +687,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { for (const str of writtenAddresses) { const address = Address.fromString(str) - await this.stateManager.putContractCode(address, new Uint8Array()) + await vm.stateManager.putContractCode(address, new Uint8Array()) } if (enableProfiler) { @@ -689,10 +697,10 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { console.time(accessListLabel) } - if (opts.reportAccessList === true && this.common.isActivatedEIP(2930)) { + if (opts.reportAccessList === true && vm.common.isActivatedEIP(2930)) { // Convert the Map to the desired type const accessList: AccessList = [] - for (const [address, set] of this.evm.journal.accessList!) { + for (const [address, set] of vm.evm.journal.accessList!) { const item: AccessListItem = { address: `0x${address}`, storageKeys: [], @@ -713,11 +721,11 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { console.time(journalCacheCleanUpLabel) } - if (opts.reportPreimages === true && this.evm.journal.preimages !== undefined) { - results.preimages = this.evm.journal.preimages + if (opts.reportPreimages === true && vm.evm.journal.preimages !== undefined) { + results.preimages = vm.evm.journal.preimages } - await this.evm.journal.cleanup() + await vm.evm.journal.cleanup() state.originalStorageCache.clear() if (enableProfiler) { @@ -730,7 +738,8 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Generate the tx receipt const gasUsed = opts.blockGasUsed !== undefined ? opts.blockGasUsed : block.header.gasUsed const cumulativeGasUsed = gasUsed + results.totalGasSpent - results.receipt = await generateTxReceipt.bind(this)( + results.receipt = await generateTxReceipt( + vm, tx, results, cumulativeGasUsed, @@ -751,8 +760,8 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { * @property {Object} result result of the transaction */ const event: AfterTxEvent = { transaction: tx, ...results } - await this._emit('afterTx', event) - if (this.DEBUG) { + await vm._emit('afterTx', event) + if (vm.DEBUG) { debug( `tx run finished hash=${ opts.tx.isSigned() ? bytesToHex(opts.tx.hash()) : 'unsigned' @@ -786,15 +795,15 @@ function txLogsBloom(logs?: any[], common?: Common): Bloom { /** * Returns the tx receipt. - * @param this The vm instance + * @param vm The vm instance * @param tx The transaction * @param txResult The tx result - * @param cumulativeGasUsed The gas used in the block including this tx + * @param cumulativeGasUsed The gas used in the block including vm tx * @param blobGasUsed The blob gas used in the tx - * @param blobGasPrice The blob gas price for the block including this tx + * @param blobGasPrice The blob gas price for the block including vm tx */ export async function generateTxReceipt( - this: VM, + vm: VM, tx: TypedTransaction, txResult: RunTxResult, cumulativeGasUsed: bigint, @@ -808,7 +817,7 @@ export async function generateTxReceipt( } let receipt - if (this.DEBUG) { + if (vm.DEBUG) { debug( `Generate tx receipt transactionType=${ tx.type @@ -820,7 +829,7 @@ export async function generateTxReceipt( if (!tx.supports(Capability.EIP2718TypedTransaction)) { // Legacy transaction - if (this.common.gteHardfork(Hardfork.Byzantium)) { + if (vm.common.gteHardfork(Hardfork.Byzantium)) { // Post-Byzantium receipt = { status: txResult.execResult.exceptionError !== undefined ? 0 : 1, // Receipts have a 0 as status on error @@ -828,7 +837,7 @@ export async function generateTxReceipt( } as PostByzantiumTxReceipt } else { // Pre-Byzantium - const stateRoot = await this.stateManager.getStateRoot() + const stateRoot = await vm.stateManager.getStateRoot() receipt = { stateRoot, ...baseReceipt, diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index c4d0cefa5a..ddd6242b57 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -4,23 +4,10 @@ import { createEVM, getActivePrecompiles } from '@ethereumjs/evm' import { DefaultStateManager } from '@ethereumjs/statemanager' import { Account, Address, AsyncEventEmitter, unprefixedHexToBytes } from '@ethereumjs/util' -import { buildBlock } from './buildBlock.js' -import { runBlock } from './runBlock.js' -import { runTx } from './runTx.js' - -import type { BlockBuilder } from './buildBlock.js' -import type { - BuildBlockOpts, - RunBlockOpts, - RunBlockResult, - RunTxOpts, - RunTxResult, - VMEvents, - VMOpts, -} from './types.js' +import type { VMEvents, VMOpts } from './types.js' import type { BlockchainInterface } from '@ethereumjs/blockchain' import type { EVMStateManagerInterface } from '@ethereumjs/common' -import type { EVMInterface, EVMPerformanceLogOutput } from '@ethereumjs/evm' +import type { EVMInterface } from '@ethereumjs/evm' import type { BigIntLike } from '@ethereumjs/util' /** @@ -181,51 +168,6 @@ export class VM { typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false } - /** - * Processes the `block` running all of the transactions it contains and updating the miner's account - * - * This method modifies the state. If `generate` is `true`, the state modifications will be - * reverted if an exception is raised. If it's `false`, it won't revert if the block's header is - * invalid. If an error is thrown from an event handler, the state may or may not be reverted. - * - * @param {RunBlockOpts} opts - Default values for options: - * - `generate`: false - */ - async runBlock(opts: RunBlockOpts): Promise { - return runBlock.bind(this)(opts) - } - - /** - * Process a transaction. Run the vm. Transfers eth. Checks balances. - * - * This method modifies the state. If an error is thrown, the modifications are reverted, except - * when the error is thrown from an event handler. In the latter case the state may or may not be - * reverted. - * - * @param {RunTxOpts} opts - */ - async runTx(opts: RunTxOpts): Promise { - return runTx.bind(this)(opts) - } - - /** - * Build a block on top of the current state - * by adding one transaction at a time. - * - * Creates a checkpoint on the StateManager and modifies the state - * as transactions are run. The checkpoint is committed on {@link BlockBuilder.build} - * or discarded with {@link BlockBuilder.revert}. - * - * @param {BuildBlockOpts} opts - * @returns An instance of {@link BlockBuilder} with methods: - * - {@link BlockBuilder.addTransaction} - * - {@link BlockBuilder.build} - * - {@link BlockBuilder.revert} - */ - async buildBlock(opts: BuildBlockOpts): Promise { - return buildBlock.bind(this)(opts) - } - /** * Returns a copy of the {@link VM} instance. * @@ -274,154 +216,4 @@ export class VM { const errorStr = `vm hf=${hf}` return errorStr } - - /** - * Emit EVM profile logs - * @param logs - * @param profileTitle - * @hidden - */ - emitEVMProfile(logs: EVMPerformanceLogOutput[], profileTitle: string) { - if (logs.length === 0) { - return - } - - // Track total calls / time (ms) / gas - - let calls = 0 - let totalMs = 0 - let totalGas = 0 - - // Order of columns to report (see `EVMPerformanceLogOutput` type) - - const colOrder: (keyof EVMPerformanceLogOutput)[] = [ - 'tag', - 'calls', - 'avgTimePerCall', - 'totalTime', - 'staticGasUsed', - 'dynamicGasUsed', - 'gasUsed', - 'staticGas', - 'millionGasPerSecond', - 'blocksPerSlot', - ] - - // The name of this column to report (saves space) - const colNames = [ - 'tag', - 'calls', - 'ms/call', - 'total (ms)', - 'sgas', - 'dgas', - 'total (s+d)', - 'static fee', - 'Mgas/s', - 'BpS', - ] - - // Special padStr method which inserts whitespace left and right - // This ensures that there is at least one whitespace between the columns (denoted by pipe `|` chars) - function padStr(str: string | number, leftpad: number) { - return ' ' + str.toString().padStart(leftpad, ' ') + ' ' - } - // Returns the string length of this column. Used to calculate how big the header / footer should be - function strLen(str: string | number) { - return padStr(str, 0).length - 2 - } - - // Step one: calculate the length of each colum - const colLength: number[] = [] - - for (const entry of logs) { - let ins = 0 - colLength[ins] = Math.max(colLength[ins] ?? 0, strLen(colNames[ins])) - for (const key of colOrder) { - if (entry[key] !== undefined) { - // If entry is available, max out the current column length (this will be the longest string of this column) - colLength[ins] = Math.max(colLength[ins] ?? 0, strLen(entry[key]!)) - ins++ - // In this switch statement update the total calls / time / gas used - switch (key) { - case 'calls': - calls += entry[key] - break - case 'totalTime': - totalMs += entry[key] - break - case 'gasUsed': - totalGas += entry[key] - break - } - } - } - } - - // Ensure that the column names also fit on the column length - for (const i in colLength) { - colLength[i] = Math.max(colLength[i] ?? 0, strLen(colNames[i])) - } - - // Calculate the total header length - // This is done by summing all columns together, plus adding three extra chars per column (two whitespace, one pipe) - // Remove the final pipe character since this is included in the header string (so subtract one) - const headerLength = colLength.reduce((pv, cv) => pv + cv, 0) + colLength.length * 3 - 1 - - const blockGasLimit = 30_000_000 // Block gas limit - const slotTime = 12000 // Time in milliseconds (!) per slot - - // Normalize constant to check if execution time is above one block per slot (>=1) or not (<1) - const bpsNormalizer = blockGasLimit / slotTime - - const avgGas = totalGas / totalMs // Gas per millisecond - const mGasSAvg = Math.round(avgGas) / 1e3 - const bpSAvg = Math.round((avgGas / bpsNormalizer) * 1e3) / 1e3 - - // Write the profile title - // eslint-disable-next-line - console.log('+== ' + profileTitle + ' ==+') - // Write the summary of this profile - // eslint-disable-next-line - console.log( - `+== Calls: ${calls}, Total time: ${ - Math.round(totalMs * 1e3) / 1e3 - }ms, Total gas: ${totalGas}, MGas/s: ${mGasSAvg}, Blocks per Slot (BpS): ${bpSAvg} ==+` - ) - - // Generate and write the header - const header = '|' + '-'.repeat(headerLength) + '|' - // eslint-disable-next-line - console.log(header) - - // Write the columns - let str = '' - for (const i in colLength) { - str += '|' + padStr(colNames[i], colLength[i]) - } - str += '|' - - // eslint-disable-next-line - console.log(str) - - // Write each profile entry - for (const entry of logs) { - let str = '' - let i = 0 - for (const key of colOrder) { - if (entry[key] !== undefined) { - str += '|' + padStr(entry[key]!, colLength[i]) - i++ - } - } - str += '|' - // eslint-disable-next-line - console.log(str) - } - - // Finally, write the footer - const footer = '+' + '-'.repeat(headerLength) + '+' - // eslint-disable-next-line - console.log(footer) - } } diff --git a/packages/vm/test/api/EIPs/eip-1153.spec.ts b/packages/vm/test/api/EIPs/eip-1153.spec.ts index d59e588852..2bd33912a9 100644 --- a/packages/vm/test/api/EIPs/eip-1153.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1153.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, bytesToInt, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { TypedTransaction } from '@ethereumjs/tx' import type { PrefixedHexString } from '@ethereumjs/util' @@ -61,7 +61,7 @@ describe('EIP 1153: transient storage', () => { await vm.stateManager.putAccount(fromAddress, new Account(BigInt(0), BigInt(0xfffffffff))) const results = [] for (const tx of test.transactions) { - const result = await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) results.push(result) } diff --git a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts index f00dee5af1..c2809098bf 100644 --- a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts @@ -2,8 +2,8 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, bigIntToBytes, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' -import { createAccount } from '../utils' +import { VM } from '../../../src/index.js' +import { createAccount } from '../utils.js' import type { PrefixedHexString } from '@ethereumjs/util' diff --git a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts index df2d83d671..406f5fa7a3 100644 --- a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts @@ -15,7 +15,7 @@ import { } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { TransactionType, TypedTransaction } from '@ethereumjs/tx' @@ -88,7 +88,7 @@ describe('EIP1559 tests', () => { const balance = GWEI * BigInt(21000) * BigInt(10) account!.balance = balance await vm.stateManager.putAccount(sender, account!) - const results = await vm.runTx({ + const results = await runTx(vm, { tx: block.transactions[0], block, }) @@ -121,7 +121,7 @@ describe('EIP1559 tests', () => { const block2 = makeBlock(GWEI, tx2, 1) await vm.stateManager.modifyAccountFields(sender, { balance }) await vm.stateManager.modifyAccountFields(coinbase, { balance: BigInt(0) }) - const results2 = await vm.runTx({ + const results2 = await runTx(vm, { tx: block2.transactions[0], block: block2, skipNonce: true, @@ -149,7 +149,7 @@ describe('EIP1559 tests', () => { const block3 = makeBlock(GWEI, tx3, 0) await vm.stateManager.modifyAccountFields(sender, { balance }) await vm.stateManager.modifyAccountFields(coinbase, { balance: BigInt(0) }) - const results3 = await vm.runTx({ + const results3 = await runTx(vm, { tx: block3.transactions[0], block: block3, skipNonce: true, @@ -198,7 +198,7 @@ describe('EIP1559 tests', () => { const code = hexToBytes('0x3A60005260206000F3') await vm.stateManager.putContractCode(contractAddress, code) - const result = await vm.runTx({ tx: block.transactions[0], block }) + const result = await runTx(vm, { tx: block.transactions[0], block }) const returnValue = result.execResult.returnValue const expectedCost = GWEI * BigInt(3) diff --git a/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts b/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts index 602e76f7ec..1a11905235 100644 --- a/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts @@ -3,7 +3,7 @@ import { Address, bytesToHex, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' // eslint-disable-next-line import/order -import { VM } from '../../../src/vm.js' +import { VM } from '../../../src/index.js' // See https://github.com/holiman/go-ethereum/blob/2c99023b68c573ba24a5b01db13e000bd9b82417/core/vm/testdata/precompiles/modexp_eip2565.json import testData from '../testdata/eip-2565.json' diff --git a/packages/vm/test/api/EIPs/eip-2929.spec.ts b/packages/vm/test/api/EIPs/eip-2929.spec.ts index e1da4ae26a..fe9f897b64 100644 --- a/packages/vm/test/api/EIPs/eip-2929.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2929.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -56,7 +56,7 @@ describe('EIP 2929: gas cost tests', () => { const tx = unsignedTx.sign(senderKey) - const result = await vm.runTx({ tx, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, skipHardForkValidation: true }) const totalGasUsed = initialGas - currentGas assert.equal(true, totalGasUsed === BigInt(test.totalGasUsed) + BigInt(21000)) // Add tx upfront cost. @@ -93,7 +93,7 @@ describe('EIP 2929: gas cost tests', () => { Account.fromAccountData({ ...account, balance: initialBalance }) ) - const result = await vm.runTx({ tx, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, skipHardForkValidation: true }) assert.equal(result.totalGasSpent, expectedGasUsed) } diff --git a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts index 13bbfb92b8..87d78685a5 100644 --- a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts @@ -3,7 +3,7 @@ import { AccessListEIP2930Transaction } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' const common = new Common({ eips: [2718, 2929, 2930], @@ -65,13 +65,13 @@ describe('EIP-2930 Optional Access Lists tests', () => { trace.push([o.opcode.name, o.gasLeft]) }) - await vm.runTx({ tx: txnWithAccessList }) + await runTx(vm, { tx: txnWithAccessList }) assert.ok(trace[1][0] === 'SLOAD') let gasUsed = trace[1][1] - trace[2][1] assert.equal(gasUsed, 100, 'charge warm sload gas') trace = [] - await vm.runTx({ tx: txnWithoutAccessList, skipNonce: true }) + await runTx(vm, { tx: txnWithoutAccessList, skipNonce: true }) assert.ok(trace[1][0] === 'SLOAD') gasUsed = trace[1][1] - trace[2][1] assert.equal(gasUsed, 2100, 'charge cold sload gas') 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 0518294d21..34d4bd2824 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 @@ -19,7 +19,7 @@ import { assert, describe, it } from 'vitest' import { bytesToBigInt } from '../../../../util/src/bytes.js' import { BIGINT_0 } from '../../../../util/src/constants.js' -import { VM } from '../../../src/vm.js' +import { VM, buildBlock, runBlock, runTx } from '../../../src/index.js' import type { Block } from '@ethereumjs/block' @@ -133,7 +133,7 @@ describe('EIP 2935: historical block hashes', () => { await vm.stateManager.putAccount(callerAddress, account!) await vm.stateManager.putContractCode(historyAddress, contract2935Code) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const blockHashi = result.execResult.returnValue return blockHashi } @@ -180,7 +180,7 @@ describe('EIP 2935: historical block hashes', () => { }) const genesis = await vm.blockchain.getBlock(0) const block = await ( - await vm.buildBlock({ + await buildBlock(vm, { parentBlock: genesis, blockOpts: { putBlockIntoBlockchain: false, @@ -188,7 +188,7 @@ describe('EIP 2935: historical block hashes', () => { }) ).build() await vm.blockchain.putBlock(block) - await vm.runBlock({ block, generate: true }) + await runBlock(vm, { block, generate: true }) const storage = await vm.stateManager.getContractStorage( historyAddress, @@ -215,7 +215,7 @@ describe('EIP 2935: historical block hashes', () => { let lastBlock = await vm.blockchain.getBlock(0) for (let i = 1; i <= blocksToBuild; i++) { lastBlock = await ( - await vm.buildBlock({ + await buildBlock(vm, { parentBlock: lastBlock, blockOpts: { putBlockIntoBlockchain: false, @@ -227,7 +227,7 @@ describe('EIP 2935: historical block hashes', () => { }) ).build() await vm.blockchain.putBlock(lastBlock) - await vm.runBlock({ + await runBlock(vm, { block: lastBlock, generate: true, skipHeaderValidation: true, @@ -280,7 +280,7 @@ describe('EIP 2935: historical block hashes', () => { } // validate the contract code cases - // const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + // const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const block = createBlockFromBlockData( { header: { diff --git a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts index 6bab91c1a4..90651d883c 100644 --- a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts @@ -20,7 +20,7 @@ import { import { keccak256 } from 'ethereum-cryptography/keccak' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' import type { ECDSASignature } from '@ethereumjs/util' @@ -251,7 +251,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue.slice(31) assert.deepEqual(buf, hexToBytes('0x01'), 'auth should return 1') }) @@ -275,7 +275,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue assert.deepEqual(buf, zeros(32), 'auth puts 0 on stack on invalid signature') }) @@ -300,7 +300,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue assert.deepEqual(buf, zeros(32), 'auth puts 0') }) @@ -323,7 +323,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue assert.deepEqual(buf, zeros(32), 'auth puts 0') }) @@ -347,7 +347,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue assert.deepEqual(buf, zeros(32), 'auth puts 0') }) @@ -376,7 +376,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue.slice(31) assert.deepEqual(buf, hexToBytes('0x01'), 'auth returned right address') }) @@ -402,7 +402,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(10000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue.slice(31) assert.deepEqual(buf, hexToBytes('0x01'), 'auth returned right address') }) @@ -425,7 +425,7 @@ describe('EIP-3074 AUTH', () => { account!.balance = BigInt(20000000) await vm.stateManager.putAccount(callerAddress, account!) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.deepEqual( result.execResult.returnValue.slice(31), @@ -447,7 +447,7 @@ describe('EIP-3074 AUTH', () => { nonce: 1, }).sign(callerPrivateKey) - const result2 = await vm.runTx({ tx: tx2, block, skipHardForkValidation: true }) + const result2 = await runTx(vm, { tx: tx2, block, skipHardForkValidation: true }) // the memory size in AUTH is 0x90 (so extra 16 bytes), but memory expands with words (32 bytes) // so the correct amount of msize is 0xa0, not 0x90 @@ -491,7 +491,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const buf = result.execResult.returnValue.slice(31) assert.deepEqual(buf, hexToBytes('0x01'), 'authcall success') @@ -525,7 +525,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - await vm.runTx({ tx, block, skipHardForkValidation: true }) + await runTx(vm, { tx, block, skipHardForkValidation: true }) const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, @@ -568,7 +568,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - await vm.runTx({ tx, block, skipHardForkValidation: true }) + await runTx(vm, { tx, block, skipHardForkValidation: true }) const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, @@ -613,7 +613,7 @@ describe('EIP-3074 AUTHCALL', () => { value: 1, }).sign(callerPrivateKey) - await vm.runTx({ tx, block, skipHardForkValidation: true }) + await runTx(vm, { tx, block, skipHardForkValidation: true }) const gasBigInt = gas! - gasAfterCall! const expected = @@ -657,7 +657,7 @@ describe('EIP-3074 AUTHCALL', () => { value, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, @@ -707,7 +707,7 @@ describe('EIP-3074 AUTHCALL', () => { value, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.ok(result.execResult.exceptionError?.error === EVMErrorMessage.OUT_OF_GAS) }) @@ -727,7 +727,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.equal( result.execResult.exceptionError?.error, EVMErrorMessage.AUTHCALL_UNSET, @@ -763,7 +763,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.equal( result.execResult.exceptionError?.error, EVMErrorMessage.AUTHCALL_UNSET, @@ -791,7 +791,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.equal(result.amountSpent, tx.gasLimit * tx.gasPrice, 'spent all gas') assert.equal( result.execResult.exceptionError?.error, @@ -819,7 +819,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - await vm.runTx({ tx, block, skipHardForkValidation: true }) + await runTx(vm, { tx, block, skipHardForkValidation: true }) const gas = await vm.stateManager.getContractStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}01`) @@ -852,7 +852,7 @@ describe('EIP-3074 AUTHCALL', () => { gasPrice: 10, }).sign(callerPrivateKey) - const result = await vm.runTx({ tx, block, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const callInput = await vm.stateManager.getContractStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}02`) diff --git a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts index 45cf5f2587..90a91fa843 100644 --- a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts @@ -4,7 +4,7 @@ import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { Address, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' import type { TypedTransaction } from '@ethereumjs/tx' @@ -87,7 +87,7 @@ describe('EIP3198 tests', () => { } }) - const results = await vm.runTx({ + const results = await runTx(vm, { tx: block.transactions[0], block, }) diff --git a/packages/vm/test/api/EIPs/eip-3529.spec.ts b/packages/vm/test/api/EIPs/eip-3529.spec.ts index 3e4b4fdb53..b41f1acbf1 100644 --- a/packages/vm/test/api/EIPs/eip-3529.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3529.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' import type { PrefixedHexString } from '@ethereumjs/util' @@ -165,7 +165,7 @@ describe('EIP-3529 tests', () => { gasLimit: 100000, }).sign(pkey) - const result = await vm.runTx({ + const result = await runTx(vm, { tx, skipHardForkValidation: true, }) @@ -217,7 +217,7 @@ describe('EIP-3529 tests', () => { gasLimit: 10000000, }).sign(pkey) - const result = await vm.runTx({ tx, skipHardForkValidation: true }) + const result = await runTx(vm, { tx, skipHardForkValidation: true }) const actualGasUsed = startGas! - finalGas! + BigInt(21000) const maxRefund = actualGasUsed / BigInt(5) diff --git a/packages/vm/test/api/EIPs/eip-3541.spec.ts b/packages/vm/test/api/EIPs/eip-3541.spec.ts index afe9a8efe7..53d49464ed 100644 --- a/packages/vm/test/api/EIPs/eip-3541.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3541.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' import type { Address } from '@ethereumjs/util' @@ -23,7 +23,7 @@ describe('EIP 3541 tests', () => { let vm = await VM.create({ common }) - let result = await vm.runTx({ tx, skipHardForkValidation: true }) + let result = await runTx(vm, { tx, skipHardForkValidation: true }) let created = result.createdAddress let code = await vm.stateManager.getContractCode(created!) @@ -39,7 +39,7 @@ describe('EIP 3541 tests', () => { nonce: 1, }).sign(pkey) - result = await vm.runTx({ tx: tx1, skipHardForkValidation: true }) + result = await runTx(vm, { tx: tx1, skipHardForkValidation: true }) created = result.createdAddress code = await vm.stateManager.getContractCode(created!) @@ -54,7 +54,7 @@ describe('EIP 3541 tests', () => { gasLimit: 1000000, }).sign(pkey) - result = await vm.runTx({ tx: tx2, skipHardForkValidation: true }) + result = await runTx(vm, { tx: tx2, skipHardForkValidation: true }) created = result.createdAddress code = await vm.stateManager.getContractCode(created!) @@ -77,7 +77,7 @@ describe('EIP 3541 tests', () => { } }) - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) let code = await vm.stateManager.getContractCode(address!) @@ -90,7 +90,7 @@ describe('EIP 3541 tests', () => { nonce: 1, }).sign(pkey) - await vm.runTx({ tx: tx1, skipHardForkValidation: true }) + await runTx(vm, { tx: tx1, skipHardForkValidation: true }) code = await vm.stateManager.getContractCode(address!) @@ -112,7 +112,7 @@ describe('EIP 3541 tests', () => { } }) - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) let code = await vm.stateManager.getContractCode(address!) @@ -125,7 +125,7 @@ describe('EIP 3541 tests', () => { nonce: 1, }).sign(pkey) - await vm.runTx({ tx: tx1, skipHardForkValidation: true }) + await runTx(vm, { tx: tx1, skipHardForkValidation: true }) code = await vm.stateManager.getContractCode(address!) diff --git a/packages/vm/test/api/EIPs/eip-3607.spec.ts b/packages/vm/test/api/EIPs/eip-3607.spec.ts index 27a5a6d275..af86803aab 100644 --- a/packages/vm/test/api/EIPs/eip-3607.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3607.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' describe('EIP-3607 tests', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin, eips: [3607] }) @@ -16,7 +16,7 @@ describe('EIP-3607 tests', () => { const tx = LegacyTransaction.fromTxData({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) assert.fail('runTx should have thrown') } catch (error: any) { if ((error.message as string).includes('EIP-3607')) { @@ -33,7 +33,7 @@ describe('EIP-3607 tests', () => { const tx = LegacyTransaction.fromTxData({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) assert.ok('runTx successfully ran') } catch (error: any) { assert.fail('threw an unexpected error') diff --git a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts index 6baa7b004d..6bdba6452c 100644 --- a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts @@ -4,7 +4,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' const pkey = hexToBytes(`0x${'20'.repeat(32)}`) const GWEI = BigInt(1000000000) const sender = new Address(privateToAddress(pkey)) @@ -53,7 +53,7 @@ describe('EIP 3651 tests', () => { gasPrice: 10, }).sign(pkey) - const result = await vm.runTx({ + const result = await runTx(vm, { block, tx, skipHardForkValidation: true, @@ -66,7 +66,7 @@ describe('EIP 3651 tests', () => { }) ) - const result2 = await vm2.runTx({ block, tx, skipHardForkValidation: true }) + const result2 = await runTx(vm2, { block, tx, skipHardForkValidation: true }) const expectedDiff = common.param('gasPrices', 'coldaccountaccess')! - common.param('gasPrices', 'warmstorageread')! diff --git a/packages/vm/test/api/EIPs/eip-3855.spec.ts b/packages/vm/test/api/EIPs/eip-3855.spec.ts index 4a5e9ebdea..13bf664890 100644 --- a/packages/vm/test/api/EIPs/eip-3855.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3855.spec.ts @@ -3,7 +3,7 @@ import { EVMErrorMessage } from '@ethereumjs/evm' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' diff --git a/packages/vm/test/api/EIPs/eip-3860.spec.ts b/packages/vm/test/api/EIPs/eip-3860.spec.ts index 27569f7bbf..af2687df0b 100644 --- a/packages/vm/test/api/EIPs/eip-3860.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3860.spec.ts @@ -3,7 +3,7 @@ import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' const pkey = hexToBytes(`0x${'20'.repeat(32)}`) const GWEI = BigInt('1000000000') const sender = new Address(privateToAddress(pkey)) @@ -38,7 +38,7 @@ describe('EIP 3860 tests', () => { }, { common: txCommon } ).sign(pkey) - const result = await vm.runTx({ tx }) + const result = await runTx(vm, { tx }) assert.ok( (result.execResult.exceptionError?.error as string) === 'initcode exceeds max initcode size', 'initcode exceeds max size' diff --git a/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts b/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts index 92c765feca..2d1a1cb9d6 100644 --- a/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts @@ -3,7 +3,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' import type { InterpreterStep } from '@ethereumjs/evm' diff --git a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts index f654211127..c4479ee1b8 100644 --- a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts @@ -24,6 +24,7 @@ import { import { assert, describe, it } from 'vitest' import { VM } from '../../../src' +import { runBlock as runBlockVM } from '../../../src/index.js' import type { Block } from '@ethereumjs/block' import type { BigIntLike, PrefixedHexString } from '@ethereumjs/util' @@ -108,7 +109,7 @@ async function runBlock(block: Block) { await vm.stateManager.putContractCode(contractAddress, hexToBytes(CODE)) await vm.stateManager.putContractCode(BROOT_Address, hexToBytes(BROOT_CODE)) return { - vmResult: await vm.runBlock({ + vmResult: await runBlockVM(vm, { block, skipBalance: true, skipBlockValidation: true, diff --git a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts index 5afdeba5c0..7e5ff94266 100644 --- a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts @@ -17,7 +17,7 @@ import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' import * as genesisJSON from '../../../../client/test/testdata/geth-genesis/eip4844.json' -import { VM } from '../../../src/vm.js' +import { VM, buildBlock, runBlock } from '../../../src/index.js' import { setBalance } from '../utils.js' const pk = hexToBytes(`0x${'20'.repeat(32)}`) @@ -48,7 +48,7 @@ describe('EIP4844 tests', () => { await setBalance(vm, address, 14680063125000000000n) const vmCopy = await vm.shallowCopy() - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, withdrawals: [], blockOpts: { @@ -94,7 +94,7 @@ describe('EIP4844 tests', () => { assert.equal(block.header.blobGasUsed, blobGasPerBlob, 'blob gas used for 1 blob should match') // block should successfully execute with VM.runBlock and have same outputs - const result = await vmCopy.runBlock({ block, skipBlockValidation: true }) + const result = await runBlock(vmCopy, { block, skipBlockValidation: true }) assert.equal(result.gasUsed, block.header.gasUsed) assert.deepEqual(result.receiptsRoot, block.header.receiptTrie) assert.deepEqual(result.stateRoot, block.header.stateRoot) diff --git a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts index 5fa48e09ce..adec4770bf 100644 --- a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts @@ -17,7 +17,7 @@ import { import { assert, describe, it } from 'vitest' import * as genesisJSON from '../../../../client/test/testdata/geth-genesis/withdrawals.json' -import { VM } from '../../../src/vm' +import { VM, buildBlock, runBlock } from '../../../src/index.js' import type { Block } from '@ethereumjs/block' import type { WithdrawalBytes, WithdrawalData } from '@ethereumjs/util' @@ -112,7 +112,7 @@ describe('EIP4895 tests', () => { result = e.execResult.returnValue }) - await vm.runBlock({ block, generate: true }) + await runBlock(vm, { block, generate: true }) for (let i = 0; i < addresses.length; i++) { const address = new Address(hexToBytes(`0x${addresses[i]}`)) @@ -161,7 +161,7 @@ describe('EIP4895 tests', () => { ) postState = bytesToHex(await vm.stateManager.getStateRoot()) - await vm.runBlock({ block, generate: true }) + await runBlock(vm, { block, generate: true }) assert.equal( postState, '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45', @@ -181,7 +181,7 @@ describe('EIP4895 tests', () => { }, { common: vm.common } ) - await vm.runBlock({ block, generate: true }) + await runBlock(vm, { block, generate: true }) postState = bytesToHex(await vm.stateManager.getStateRoot()) assert.equal( postState, @@ -217,7 +217,7 @@ describe('EIP4895 tests', () => { ) const td = await blockchain.getTotalDifficulty(genesisBlock.hash()) - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, withdrawals, blockOpts: { @@ -236,7 +236,7 @@ describe('EIP4895 tests', () => { ) // block should successfully execute with VM.runBlock and have same outputs - const result = await vmCopy.runBlock({ block }) + const result = await runBlock(vmCopy, { block }) assert.equal(result.gasUsed, block.header.gasUsed) assert.deepEqual(result.receiptsRoot, block.header.receiptTrie) assert.deepEqual(result.stateRoot, block.header.stateRoot) diff --git a/packages/vm/test/api/EIPs/eip-6110.spec.ts b/packages/vm/test/api/EIPs/eip-6110.spec.ts index 4da632d9c3..10f14edf62 100644 --- a/packages/vm/test/api/EIPs/eip-6110.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6110.spec.ts @@ -5,6 +5,7 @@ import { Account, Address, bytesToHex, hexToBytes, randomBytes } from '@ethereum import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' +import { buildBlock, runBlock } from '../../../src/index.js' import { setupVM } from '../utils.js' import type { DepositRequest } from '../../../../util/src/requests.js' @@ -57,7 +58,7 @@ describe('EIP-6110 runBlock tests', () => { }, { common } ) - const res = await vm.runBlock({ block, generate: true, skipBlockValidation: true }) + const res = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) assert.equal(res.requests?.length, 1) const reqPubkey = (res.requests![0] as DepositRequest).pubkey assert.equal(bytesToHex(reqPubkey), pubkey) @@ -89,7 +90,7 @@ describe('EIP-7685 buildBlock tests', () => { ) const block = createBlockFromBlockData({}, { common }) ;(vm.blockchain as any)['dbManager']['getHeader'] = () => block.header - const blockBuilder = await vm.buildBlock({ parentBlock: block }) + const blockBuilder = await buildBlock(vm, { parentBlock: block }) await blockBuilder.addTransaction(depositTx) const res = await blockBuilder.build() assert.equal(res.requests?.length, 1) diff --git a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts index aec0d55338..8a97911208 100644 --- a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts @@ -3,7 +3,7 @@ import { LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, equalsBytes, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' const pkey = hexToBytes(`0x${'20'.repeat(32)}`) @@ -48,7 +48,7 @@ describe('EIP 6780 tests', () => { data: payload, }).sign(pkey) - const result = await vm.runTx({ tx }) + const result = await runTx(vm, { tx }) const createdAddress = result.createdAddress! const contract = (await vm.stateManager.getAccount(createdAddress)) ?? new Account() @@ -85,7 +85,7 @@ describe('EIP 6780 tests', () => { to: target, }).sign(pkey) - await vm.runTx({ tx }) + await runTx(vm, { tx }) const contract = (await vm.stateManager.getAccount(target)) ?? new Account() assert.equal(contract.balance, BigInt(0), 'value sent') diff --git a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts index 86792cce4a..d767053055 100644 --- a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts @@ -9,6 +9,7 @@ import { describe, it } from 'vitest' import * as verkleBlockJSON from '../../../../statemanager/test/testdata/verkleKaustinen6Block72.json' import { VM } from '../../../src' +import { runBlock } from '../../../src/index.js' import type { BlockData } from '@ethereumjs/block' import type { PrefixedHexString } from '@ethereumjs/util' @@ -46,6 +47,6 @@ describe('EIP 6800 tests', () => { // We need to skip validation of the header validation // As otherwise the vm will attempt retrieving the parent block, which is not available in a stateless context - await vm.runBlock({ block, skipHeaderValidation: true, parentStateRoot }) + await runBlock(vm, { block, skipHeaderValidation: true, parentStateRoot }) }) }) diff --git a/packages/vm/test/api/EIPs/eip-7002.spec.ts b/packages/vm/test/api/EIPs/eip-7002.spec.ts index a3815d348f..6d70872d06 100644 --- a/packages/vm/test/api/EIPs/eip-7002.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7002.spec.ts @@ -16,6 +16,7 @@ import { import { assert, describe, it } from 'vitest' import { bytesToBigInt } from '../../../../util/src/bytes.js' +import { runBlock } from '../../../src/index.js' import { setupVM } from '../utils.js' import type { Block } from '@ethereumjs/block' @@ -82,7 +83,7 @@ describe('EIP-7002 tests', () => { await vm.stateManager.putAccount(addr, acc) // Deploy withdrawals contract - const results = await vm.runBlock({ + const results = await runBlock(vm, { block, skipHeaderValidation: true, skipBlockValidation: true, @@ -110,7 +111,7 @@ describe('EIP-7002 tests', () => { generatedBlock = e.block }) - await vm.runBlock({ + await runBlock(vm, { block: block2, skipHeaderValidation: true, skipBlockValidation: true, @@ -133,7 +134,7 @@ describe('EIP-7002 tests', () => { // off the amountBytes because it was serialized in request from bigint assert.equal(bytesToBigInt(amountBytes), bytesToBigInt(amountRequest)) - await vm.runBlock({ block: generatedBlock!, skipHeaderValidation: true, root }) + await runBlock(vm, { block: generatedBlock!, skipHeaderValidation: true, root }) // Run block with 2 requests @@ -151,7 +152,7 @@ describe('EIP-7002 tests', () => { { common } ) - await vm.runBlock({ + await runBlock(vm, { block: block3, skipHeaderValidation: true, skipBlockValidation: true, @@ -174,7 +175,7 @@ describe('EIP-7002 tests', () => { { common } ) try { - await vm.runBlock({ + await runBlock(vm, { block, skipHeaderValidation: true, skipBlockValidation: true, diff --git a/packages/vm/test/api/EIPs/eip-7685.spec.ts b/packages/vm/test/api/EIPs/eip-7685.spec.ts index 1053058f4c..c910d73f23 100644 --- a/packages/vm/test/api/EIPs/eip-7685.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7685.spec.ts @@ -10,7 +10,7 @@ import { } from '@ethereumjs/util' import { assert, describe, expect, it } from 'vitest' -import { VM } from '../../../src/vm.js' +import { VM, buildBlock, runBlock } from '../../../src/index.js' import { setupVM } from '../utils.js' import type { CLRequest, CLRequestType } from '@ethereumjs/util' @@ -35,7 +35,7 @@ describe('EIP-7685 runBlock tests', () => { it('should not error when a valid requestsRoot is provided', async () => { const vm = await setupVM({ common }) const emptyBlock = createBlockFromBlockData({}, { common }) - const res = await vm.runBlock({ + const res = await runBlock(vm, { block: emptyBlock, generate: true, }) @@ -49,7 +49,7 @@ describe('EIP-7685 runBlock tests', () => { { common } ) await expect(async () => - vm.runBlock({ + runBlock(vm, { block: emptyBlock, }) ).rejects.toThrow('invalid requestsRoot') @@ -65,7 +65,7 @@ describe('EIP-7685 runBlock tests', () => { }, { common } ) - await expect(async () => vm.runBlock({ block })).rejects.toThrow(/invalid requestsRoot/) + await expect(async () => runBlock(vm, { block })).rejects.toThrow(/invalid requestsRoot/) }) it('should error when requestsRoot does not match requests provided', async () => { const vm = await setupVM({ common }) @@ -77,7 +77,7 @@ describe('EIP-7685 runBlock tests', () => { }, { common } ) - await expect(() => vm.runBlock({ block })).rejects.toThrow('invalid requestsRoot') + await expect(() => runBlock(vm, { block })).rejects.toThrow('invalid requestsRoot') }) }) @@ -94,7 +94,7 @@ describe('EIP 7685 buildBlock tests', () => { ) const blockchain = await createBlockchain({ genesisBlock, common, validateConsensus: false }) const vm = await VM.create({ common, blockchain }) - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, blockOpts: { calcDifficultyFromHeader: genesisBlock.header, freeze: false }, }) diff --git a/packages/vm/test/api/EIPs/eip-7702.spec.ts b/packages/vm/test/api/EIPs/eip-7702.spec.ts index d2c3e23b14..70afc3bc80 100644 --- a/packages/vm/test/api/EIPs/eip-7702.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7702.spec.ts @@ -17,7 +17,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak' import { equalsBytes } from 'ethereum-cryptography/utils' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM, runTx } from '../../../src/index.js' import type { AuthorizationListBytesItem } from '@ethereumjs/common' @@ -87,7 +87,7 @@ async function runTest( acc.balance = BigInt(1_000_000_000) await vm.stateManager.putAccount(defaultSenderAddr, acc) - await vm.runTx({ tx }) + await runTx(vm, { tx }) const slot = hexToBytes('0x' + '00'.repeat(31) + '01') const value = await vm.stateManager.getContractStorage(defaultAuthAddr, slot) @@ -225,7 +225,7 @@ describe('EIP 7702: set code to EOA accounts', () => { acc.balance = BigInt(1_000_000_000) await vm.stateManager.putAccount(defaultSenderAddr, acc) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.ok(res.execResult.executionGasUsed === BigInt(115)) }) @@ -260,7 +260,7 @@ describe('EIP 7702: set code to EOA accounts', () => { acc.balance = BigInt(1_000_000_000) await vm.stateManager.putAccount(defaultSenderAddr, acc) - await vm.runTx({ tx }) + await runTx(vm, { tx }) // Note: due to EIP-161, defaultAuthAddr is now deleted const account = await vm.stateManager.getAccount(defaultAuthAddr) diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index 9b385469ee..f5845415f9 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -12,6 +12,7 @@ import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' import { Account, Address, concatBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' +import { buildBlock, runBlock } from '../../src/index.js' import { VM } from '../../src/vm.js' import { setBalance } from './utils.js' @@ -32,7 +33,7 @@ describe('BlockBuilder', () => { const vmCopy = await vm.shallowCopy() - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, headerData: { coinbase: '0x96dc73c8b5969608c77375f085949744b5177660' }, blockOpts: { calcDifficultyFromHeader: genesisBlock.header, freeze: false }, @@ -51,7 +52,7 @@ describe('BlockBuilder', () => { 1, 'should have the correct number of tx receipts' ) - const result = await vmCopy.runBlock({ block }) + const result = await runBlock(vmCopy, { block }) assert.equal(result.gasUsed, block.header.gasUsed) assert.deepEqual(result.receiptsRoot, block.header.receiptTrie) assert.deepEqual(result.stateRoot, block.header.stateRoot) @@ -63,7 +64,7 @@ describe('BlockBuilder', () => { const vm = await VM.create({ common }) const genesis = createBlockFromBlockData({}, { common }) - const blockBuilder = await vm.buildBlock({ parentBlock: genesis }) + const blockBuilder = await buildBlock(vm, { parentBlock: genesis }) const gasLimit = genesis.header.gasLimit + BigInt(1) const tx = LegacyTransaction.fromTxData({ gasLimit }, { common }) try { @@ -103,7 +104,7 @@ describe('BlockBuilder', () => { await setBalance(vm, pKeyAddress) - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, blockOpts: { calcDifficultyFromHeader: genesisBlock.header, freeze: false }, }) @@ -201,7 +202,7 @@ describe('BlockBuilder', () => { // add balance for tx await vm.stateManager.putAccount(signer.address, Account.fromAccountData({ balance: 100000 })) - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, headerData: { difficulty: 2, extraData: new Uint8Array(97) }, blockOpts: { cliqueSigner, freeze: false }, @@ -233,7 +234,7 @@ describe('BlockBuilder', () => { await setBalance(vm, pKeyAddress) - let blockBuilder = await vm.buildBlock({ + let blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, blockOpts: { calcDifficultyFromHeader: genesisBlock.header }, }) @@ -257,7 +258,7 @@ describe('BlockBuilder', () => { assert.fail('shoud not throw') } - blockBuilder = await vm.buildBlock({ parentBlock: genesisBlock }) + blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock }) const tx2 = LegacyTransaction.fromTxData( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1, nonce: 1 }, @@ -286,7 +287,7 @@ describe('BlockBuilder', () => { const vm = await VM.create({ common, blockchain }) const vmCopy = await vm.shallowCopy() - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, blockOpts: { calcDifficultyFromHeader: genesisBlock.header, freeze: false }, }) @@ -294,7 +295,7 @@ describe('BlockBuilder', () => { const block = await blockBuilder.build() // block should successfully execute with VM.runBlock and have same outputs - const result = await vmCopy.runBlock({ block }) + const result = await runBlock(vmCopy, { block }) assert.equal(result.gasUsed, block.header.gasUsed) assert.deepEqual(result.receiptsRoot, block.header.receiptTrie) assert.deepEqual(result.stateRoot, block.header.stateRoot) @@ -314,7 +315,7 @@ describe('BlockBuilder', () => { const vmCopy = await vm.shallowCopy() - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, headerData: { coinbase: '0x96dc73c8b5969608c77375f085949744b5177660' }, blockOpts: { calcDifficultyFromHeader: genesisBlock.header, freeze: false }, @@ -371,7 +372,7 @@ describe('BlockBuilder', () => { "baseFeePerGas should equal parentHeader's calcNextBaseFee" ) - const result = await vmCopy.runBlock({ block }) + const result = await runBlock(vmCopy, { block }) assert.equal(result.gasUsed, block.header.gasUsed) assert.deepEqual(result.receiptsRoot, block.header.receiptTrie) assert.deepEqual(result.stateRoot, block.header.stateRoot) diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index 1c86fa56ea..f70127f53e 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -6,7 +6,8 @@ import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { Interface } from '@ethersproject/abi' import { assert, describe, it } from 'vitest' -import { VM } from '../../src/vm' +import { runTx } from '../../src/index.js' +import { VM } from '../../src/vm.js' import * as testChain from './testdata/testnet.json' import * as testnetMerge from './testdata/testnetMerge.json' @@ -78,7 +79,7 @@ describe('VM initialized with custom state', () => { common, } ).sign(privateKey) - const result = await vm.runTx({ + const result = await runTx(vm, { tx, block, }) diff --git a/packages/vm/test/api/events.spec.ts b/packages/vm/test/api/events.spec.ts index 6c411f05fc..3226f73609 100644 --- a/packages/vm/test/api/events.spec.ts +++ b/packages/vm/test/api/events.spec.ts @@ -3,7 +3,8 @@ import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { Account, Address, bytesToHex, toBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../src/vm' +import { runBlock, runTx } from '../../src/index.js' +import { VM } from '../../src/vm.js' describe('VM events', () => { const privKey = toBytes('0xa5737ecdc1b89ca0091647e727ba082ed8953f29182e94adc397210dda643b07') @@ -18,7 +19,7 @@ describe('VM events', () => { const block = new Block() - await vm.runBlock({ + await runBlock(vm, { block, generate: true, skipBlockValidation: true, @@ -37,7 +38,7 @@ describe('VM events', () => { const block = new Block() - await vm.runBlock({ + await runBlock(vm, { block, generate: true, skipBlockValidation: true, @@ -61,7 +62,7 @@ describe('VM events', () => { to: '0x1111111111111111111111111111111111111111', }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal(emitted, tx) }) @@ -82,7 +83,7 @@ describe('VM events', () => { value: 1, }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal(bytesToHex(emitted.execResult.returnValue), '0x') }) @@ -103,7 +104,7 @@ describe('VM events', () => { value: 1, }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal(emitted.to.toString(), '0x1111111111111111111111111111111111111111') assert.equal(bytesToHex(emitted.code), '0x') @@ -125,7 +126,7 @@ describe('VM events', () => { value: 1, }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal(bytesToHex(emitted.createdAddress), '0x') }) @@ -147,7 +148,7 @@ describe('VM events', () => { data: '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3', }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal(lastEmitted.opcode.name, 'RETURN') }) @@ -169,7 +170,7 @@ describe('VM events', () => { data: '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3', }).sign(privKey) - await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.equal( bytesToHex(emitted.code), diff --git a/packages/vm/test/api/istanbul/eip-1108.spec.ts b/packages/vm/test/api/istanbul/eip-1108.spec.ts index fbcc13f1be..ce7a429b1d 100644 --- a/packages/vm/test/api/istanbul/eip-1108.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1108.spec.ts @@ -3,7 +3,7 @@ import { getActivePrecompiles } from '@ethereumjs/evm' import { hexToBytes } from '@ethereumjs/util' import { assert, beforeAll, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' describe('Istanbul: EIP-1108 tests', () => { let vm: VM diff --git a/packages/vm/test/api/istanbul/eip-1344.spec.ts b/packages/vm/test/api/istanbul/eip-1344.spec.ts index 0f6be13ce4..f6eab50835 100644 --- a/packages/vm/test/api/istanbul/eip-1344.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1344.spec.ts @@ -3,7 +3,7 @@ import { EVMErrorMessage } from '@ethereumjs/evm' import { bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' const testCases = [ { chain: Chain.Mainnet, hardfork: Hardfork.Istanbul, chainId: BigInt(1) }, diff --git a/packages/vm/test/api/istanbul/eip-152.deactivated.ts b/packages/vm/test/api/istanbul/eip-152.deactivated.ts index a02daec8ca..50a8ed98c5 100644 --- a/packages/vm/test/api/istanbul/eip-152.deactivated.ts +++ b/packages/vm/test/api/istanbul/eip-152.deactivated.ts @@ -8,7 +8,7 @@ import { F, precompile09 } from '@ethereumjs/evm/dist/precompiles/09-blake2f' import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' // Test cases from: // https://github.com/keep-network/go-ethereum/blob/1bccafe5ef54ba849e414ce7c90f7b7130634a9a/core/vm/contracts_test.go diff --git a/packages/vm/test/api/istanbul/eip-1884.spec.ts b/packages/vm/test/api/istanbul/eip-1884.spec.ts index 36a8db84de..0cebb06a1a 100644 --- a/packages/vm/test/api/istanbul/eip-1884.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1884.spec.ts @@ -3,8 +3,8 @@ import { EVMErrorMessage } from '@ethereumjs/evm' import { Address, bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' -import { createAccount } from '../utils' +import { VM } from '../../../src/index.js' +import { createAccount } from '../utils.js' const testCases = [ { chain: Chain.Mainnet, hardfork: Hardfork.Istanbul, selfbalance: '0xf1' }, diff --git a/packages/vm/test/api/istanbul/eip-2200.spec.ts b/packages/vm/test/api/istanbul/eip-2200.spec.ts index 5041fb5f49..004e8ab249 100644 --- a/packages/vm/test/api/istanbul/eip-2200.spec.ts +++ b/packages/vm/test/api/istanbul/eip-2200.spec.ts @@ -2,8 +2,8 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' -import { createAccount } from '../utils' +import { VM } from '../../../src/index.js' +import { createAccount } from '../utils.js' const testCases = [ { diff --git a/packages/vm/test/api/muirGlacier/index.spec.ts b/packages/vm/test/api/muirGlacier/index.spec.ts index 53b8288ee2..9c2c23589c 100644 --- a/packages/vm/test/api/muirGlacier/index.spec.ts +++ b/packages/vm/test/api/muirGlacier/index.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { KECCAK256_RLP } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' describe('General MuirGlacier VM tests', () => { it('should accept muirGlacier harfork option for supported chains', async () => { diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 27b76b0a0a..788cffffc6 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -31,6 +31,7 @@ import { import { keccak256 } from 'ethereum-cryptography/keccak' import { assert, describe, it } from 'vitest' +import { runBlock } from '../../src/index.js' import { VM } from '../../src/vm' import { getDAOCommon, setupPreConditions } from '../util' @@ -68,7 +69,7 @@ describe('runBlock() -> successful API parameter usage', async () => { 'genesis state root should match calculated state root' ) - const res = await vm.runBlock({ + const res = await runBlock(vm, { block, root: (vm.stateManager as DefaultStateManager)['_trie'].root(), skipBlockValidation: true, @@ -90,7 +91,7 @@ describe('runBlock() -> successful API parameter usage', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const block1Rlp = hexToBytes(testData.blocks[0].rlp as PrefixedHexString) const block1 = createBlockFromRLPSerializedBlock(block1Rlp, { common }) - await vm.runBlock({ + await runBlock(vm, { block: block1, root: (vm.stateManager as DefaultStateManager)['_trie'].root(), skipBlockValidation: true, @@ -99,7 +100,7 @@ describe('runBlock() -> successful API parameter usage', async () => { const block2Rlp = hexToBytes(testData.blocks[1].rlp as PrefixedHexString) const block2 = createBlockFromRLPSerializedBlock(block2Rlp, { common }) - await vm.runBlock({ + await runBlock(vm, { block: block2, root: (vm.stateManager as DefaultStateManager)['_trie'].root(), @@ -109,7 +110,7 @@ describe('runBlock() -> successful API parameter usage', async () => { const block3Rlp = toBytes(testData.blocks[2].rlp as PrefixedHexString) const block3 = createBlockFromRLPSerializedBlock(block3Rlp, { common }) - await vm.runBlock({ + await runBlock(vm, { block: block3, root: (vm.stateManager as DefaultStateManager)['_trie'].root(), @@ -194,12 +195,12 @@ describe('runBlock() -> successful API parameter usage', async () => { const vm = await VM.create({ common: common1, setHardfork: true }) const vm_noSelect = await VM.create({ common: common2 }) - const txResultMuirGlacier = await vm.runBlock({ + const txResultMuirGlacier = await runBlock(vm, { block: getBlock(common1), skipBlockValidation: true, generate: true, }) - const txResultChainstart = await vm_noSelect.runBlock({ + const txResultChainstart = await runBlock(vm_noSelect, { block: getBlock(common2), skipBlockValidation: true, generate: true, @@ -227,8 +228,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { // The mocked VM uses a mocked runTx // which always returns an error. - await vm - .runBlock({ block, skipBlockValidation: true, skipHardForkValidation: true }) + await runBlock(vm, { block, skipBlockValidation: true, skipHardForkValidation: true }) .then(() => assert.fail('should have returned error')) .catch((e) => assert.ok(e.message.includes("sender doesn't have enough funds to send tx"))) }) @@ -241,8 +241,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { gasLimit: hexToBytes('0x8000000000000000'), }, }) - await vm - .runBlock({ block }) + await runBlock(vm, { block }) .then(() => assert.fail('should have returned error')) .catch((e) => assert.ok(e.message.includes('Invalid block'))) }) @@ -253,8 +252,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { const blockRlp = hexToBytes(testData.blocks[0].rlp as PrefixedHexString) const block = Object.create(createBlockFromRLPSerializedBlock(blockRlp, { common })) - await vm - .runBlock({ block }) + await runBlock(vm, { block }) .then(() => assert.fail('should have returned error')) .catch((e) => { assert.ok( @@ -270,7 +268,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { const block = Object.create(createBlockFromRLPSerializedBlock(blockRlp, { common })) ;(vm.blockchain as any).validateHeader = undefined try { - await vm.runBlock({ block }) + await runBlock(vm, { block }) } catch (err: any) { assert.equal( err.message, @@ -295,8 +293,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { opts ) - await vm - .runBlock({ block, skipBlockValidation: true }) + await runBlock(vm, { block, skipBlockValidation: true }) .then(() => assert.fail('should have returned error')) .catch((e) => assert.ok(e.message.includes('higher gas limit'))) }) @@ -335,7 +332,7 @@ describe('runBlock() -> runtime behavior', async () => { const accountRefund = createAccount(BigInt(0), fundBalanceRefund) await vm.stateManager.putAccount(DAORefundAddress, accountRefund) - await vm.runBlock({ + await runBlock(vm, { block, skipBlockValidation: true, generate: true, @@ -388,7 +385,7 @@ describe('runBlock() -> runtime behavior', async () => { { common, cliqueSigner: signer.privateKey } ) - await vm.runBlock({ block, skipNonce: true, skipBlockValidation: true, generate: true }) + await runBlock(vm, { block, skipNonce: true, skipBlockValidation: true, generate: true }) const account = await vm.stateManager.getAccount(signer.address) assert.equal( account!.balance, @@ -409,7 +406,7 @@ async function runBlockAndGetAfterBlockEvent( try { vm.events.once('afterBlock', handler) - await vm.runBlock(runBlockOpts) + await runBlock(vm, runBlockOpts) } finally { // We need this in case `runBlock` throws before emitting the event. // Otherwise we'd be leaking the listener until the next call to runBlock. @@ -451,7 +448,7 @@ async function runWithHf(hardfork: string) { await setupPreConditions(vm.stateManager, testData) - const res = await vm.runBlock({ + const res = await runBlock(vm, { block, generate: true, skipBlockValidation: true, @@ -495,7 +492,7 @@ describe('runBlock() -> tx types', async () => { await setupPreConditions(vm.stateManager, testData) - const res = await vm.runBlock({ + const res = await runBlock(vm, { block, skipBlockValidation: true, generate: true, @@ -671,7 +668,7 @@ describe('runBlock() -> tx types', async () => { { common, setHardfork: false, skipConsensusFormatValidation: true } ) - await vm.runBlock({ block, skipBlockValidation: true, generate: true }) + await runBlock(vm, { block, skipBlockValidation: true, generate: true }) const storage = await vm.stateManager.getContractStorage(defaultAuthAddr, zeros(32)) assert.ok(equalsBytes(storage, new Uint8Array([2]))) }) diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index 824bcaa8d9..9e4adc4947 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -21,9 +21,10 @@ import { import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' -import { VM } from '../../src/vm' +import { runTx } from '../../src/index.js' +import { VM } from '../../src/vm.js' -import { createAccount, getTransaction, setBalance } from './utils' +import { createAccount, getTransaction, setBalance } from './utils.js' import type { FeeMarketEIP1559TxData, TypedTxData } from '@ethereumjs/tx' @@ -61,7 +62,7 @@ describe('runTx() -> successful API parameter usage', async () => { ) } - const res = await vm.runTx({ tx, block }) + const res = await runTx(vm, { tx, block }) assert.isTrue(res.totalGasSpent > BigInt(0), `${msg} (${txType.name})`) } } @@ -90,7 +91,7 @@ describe('runTx() -> successful API parameter usage', async () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) const block = createBlockFromBlockData({}, { common: vm.common.copy() }) - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) assert.ok(true, 'matched hardfork should run without throwing') }) @@ -108,7 +109,7 @@ describe('runTx() -> successful API parameter usage', async () => { block.common.setHardfork(Hardfork.Paris) try { - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) assert.fail('vm/block mismatched hardfork should have failed') } catch (e) { assert.equal( @@ -122,7 +123,7 @@ describe('runTx() -> successful API parameter usage', async () => { tx.common.setHardfork(Hardfork.London) block.common.setHardfork(Hardfork.Paris) try { - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) assert.fail('vm/tx mismatched hardfork should have failed') } catch (e) { assert.equal( @@ -133,7 +134,7 @@ describe('runTx() -> successful API parameter usage', async () => { assert.ok(true, 'vm/tx mismatched hardfork correctly failed') } - await vm.runTx({ tx, block, skipHardForkValidation: true }) + await runTx(vm, { tx, block, skipHardForkValidation: true }) assert.ok(true, 'runTx should not fail with mismatching hardforks if validation skipped') }) @@ -152,7 +153,7 @@ describe('runTx() -> successful API parameter usage', async () => { tx.common.setHardfork(Hardfork.GrayGlacier) block.common.setHardfork(Hardfork.GrayGlacier) try { - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) assert.ok(true, 'successfully ignored merge hf while hf matching in runTx') } catch (e) { assert.fail('should have ignored merge hf while matching in runTx') @@ -170,7 +171,7 @@ describe('runTx() -> successful API parameter usage', async () => { await vm.stateManager.putAccount(caller, acc) const blockGasUsed = BigInt(1000) - const res = await vm.runTx({ tx, blockGasUsed }) + const res = await runTx(vm, { tx, blockGasUsed }) assert.equal( res.receipt.cumulativeBlockGasUsed, blockGasUsed + res.totalGasSpent, @@ -188,7 +189,7 @@ describe('runTx() -> successful API parameter usage', async () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.isTrue( res.totalGasSpent > BigInt(0), `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})` @@ -238,7 +239,7 @@ describe('runTx() -> successful API parameter usage', async () => { { common } ) - const result = await vm.runTx({ + const result = await runTx(vm, { tx, block, skipBlockGasLimitValidation: true, @@ -289,7 +290,7 @@ describe('runTx() -> API parameter usage/data errors', () => { await vm.stateManager.putAccount(caller, acc) try { - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) // TODO uncomment: // assert.fail('should throw error') } catch (e: any) { @@ -309,7 +310,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) - const res = await vm.runTx({ tx, reportAccessList: true }) + const res = await runTx(vm, { tx, reportAccessList: true }) assert.isTrue( res.totalGasSpent > BigInt(0), `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})` @@ -326,7 +327,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) - const res = await vm.runTx({ tx, reportPreimages: true }) + const res = await runTx(vm, { tx, reportPreimages: true }) const hashedCallerKey = vm.stateManager.getAppliedKey!(caller.bytes) @@ -340,7 +341,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const vm = await VM.create({ common }) const tx = getTransaction(vm.common, txType.type, false) try { - await vm.runTx({ tx }) + await runTx(vm, { tx }) assert.fail('should throw error') } catch (e: any) { assert.ok( @@ -357,7 +358,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const vm = await VM.create({ common }) const tx = getTransaction(vm.common, txType.type, true) try { - await vm.runTx({ tx }) + await runTx(vm, { tx }) } catch (e: any) { assert.ok( e.message.toLowerCase().includes('enough funds'), @@ -375,7 +376,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const maxCost: bigint = tx.gasLimit * tx.maxFeePerGas await vm.stateManager.putAccount(address, createAccount(BigInt(0), maxCost - BigInt(1))) try { - await vm.runTx({ tx }) + await runTx(vm, { tx }) assert.fail('should throw error') } catch (e: any) { assert.ok( @@ -385,7 +386,7 @@ describe('runTx() -> API parameter usage/data errors', () => { } // set sufficient balance await vm.stateManager.putAccount(address, createAccount(BigInt(0), maxCost)) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.ok(res, 'should pass if balance is sufficient') }) @@ -397,12 +398,12 @@ describe('runTx() -> API parameter usage/data errors', () => { const account = await vm.stateManager.getAccount(address) account!.balance = BigInt(9000000) // This is the maxFeePerGas multiplied with the gasLimit of 90000 await vm.stateManager.putAccount(address, account!) - await vm.runTx({ tx }) + await runTx(vm, { tx }) account!.balance = BigInt(9000000) await vm.stateManager.putAccount(address, account!) const tx2 = getTransaction(common, 2, true, '0x64', false) // Send 100 wei; now balance < maxFeePerGas*gasLimit + callvalue try { - await vm.runTx({ tx: tx2 }) + await runTx(vm, { tx: tx2 }) assert.fail('cannot reach this') } catch (e: any) { assert.ok(true, 'successfully threw on insufficient balance for transaction') @@ -419,7 +420,7 @@ describe('runTx() -> API parameter usage/data errors', () => { account!.nonce = BigInt(1) await vm.stateManager.putAccount(address, account!) try { - await vm.runTx({ tx }) + await runTx(vm, { tx }) assert.fail('cannot reach this') } catch (e: any) { assert.ok(true, 'successfully threw on wrong nonces') @@ -434,7 +435,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const tx = getTransaction(vm.common, txType.type, true) const block = createBlockFromBlockData({ header: { baseFeePerGas: 100000 } }, { common }) try { - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) assert.fail('should fail') } catch (e: any) { assert.ok( @@ -483,7 +484,7 @@ describe('runTx() -> runtime behavior', () => { await vm.stateManager.putAccount(tx.getSenderAddress(), createAccount()) - await vm.runTx({ tx }) // this tx will fail, but we have to ensure that the cache is cleared + await runTx(vm, { tx }) // this tx will fail, but we have to ensure that the cache is cleared assert.equal( (vm.stateManager).originalStorageCache.map.size, @@ -507,7 +508,7 @@ describe('runTx() -> runtime errors', () => { const to = createAccount(BigInt(0), MAX_INTEGER) await vm.stateManager.putAccount(tx.to!, to) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.equal( res.execResult!.exceptionError!.error, @@ -535,7 +536,7 @@ describe('runTx() -> runtime errors', () => { const to = createAccount(BigInt(0), MAX_INTEGER) await vm.stateManager.putAccount(contractAddress, to) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.equal( res.execResult!.exceptionError!.error, @@ -562,7 +563,7 @@ describe('runTx() -> API return values', () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.equal( res.execResult.executionGasUsed, BigInt(0), @@ -591,7 +592,7 @@ describe('runTx() -> API return values', () => { const acc = createAccount() await vm.stateManager.putAccount(caller, acc) - const res = await vm.runTx({ tx }) + const res = await runTx(vm, { tx }) assert.equal( res.totalGasSpent, @@ -676,7 +677,7 @@ describe('runTx() -> consensus bugs', () => { await vm.stateManager.putAccount(addr, acc!) const tx = LegacyTransaction.fromTxData(txData, { common }) - await vm.runTx({ tx }) + await runTx(vm, { tx }) const newBalance = (await vm.stateManager.getAccount(addr))!.balance assert.equal(newBalance, afterBalance) @@ -715,7 +716,7 @@ describe('runTx() -> consensus bugs', () => { const tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }).sign(pkey) const block = createBlockFromBlockData({ header: { baseFeePerGas: 0x0c } }, { common }) - const result = await vm.runTx({ tx, block }) + const result = await runTx(vm, { tx, block }) assert.equal( result.totalGasSpent, @@ -737,7 +738,7 @@ describe('runTx() -> RunTxOptions', () => { for (const skipBalance of [true, false]) { try { - await vm.runTx({ + await runTx(vm, { tx, skipBalance, }) @@ -769,7 +770,7 @@ it('runTx() -> skipBalance behavior', async () => { to: Address.zero(), }).sign(senderKey) - const res = await vm.runTx({ tx, skipBalance: true, skipHardForkValidation: true }) + const res = await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) assert.ok(true, 'runTx should not throw with no balance and skipBalance') const afterTxBalance = (await vm.stateManager.getAccount(sender))!.balance assert.equal( @@ -804,7 +805,7 @@ it('Validate EXTCODEHASH puts KECCAK256_NULL on stack if calling account has no const acc = await vm.stateManager.getAccount(addr) acc!.balance = BigInt(tx.gasLimit * tx.gasPrice) await vm.stateManager.putAccount(addr, acc!) - await vm.runTx({ tx, skipHardForkValidation: true }) + await runTx(vm, { tx, skipHardForkValidation: true }) const hash = await vm.stateManager.getContractStorage(codeAddr, zeros(32)) assert.deepEqual(hash, KECCAK256_NULL, 'hash ok') @@ -839,7 +840,7 @@ it('Validate CALL does not charge new account gas when calling CALLER and caller acc!.balance = BigInt(tx.gasLimit * tx.gasPrice + tx.value) await vm.stateManager.putAccount(addr, acc!) assert.equal( - (await vm.runTx({ tx, skipHardForkValidation: true })).totalGasSpent, + (await runTx(vm, { tx, skipHardForkValidation: true })).totalGasSpent, BigInt(27818), 'did not charge callNewAccount' ) @@ -870,7 +871,7 @@ it('Validate SELFDESTRUCT does not charge new account gas when calling CALLER an acc!.balance = BigInt(tx.gasLimit * tx.gasPrice + tx.value) await vm.stateManager.putAccount(addr, acc!) assert.equal( - (await vm.runTx({ tx, skipHardForkValidation: true })).totalGasSpent, + (await runTx(vm, { tx, skipHardForkValidation: true })).totalGasSpent, BigInt(13001), 'did not charge callNewAccount' ) @@ -936,7 +937,7 @@ describe('EIP 4844 transaction tests', () => { }, { common, skipConsensusFormatValidation: true } ) - const res = await vm.runTx({ tx, block, skipBalance: true }) + const res = await runTx(vm, { tx, block, skipBalance: true }) assert.ok(res.execResult.exceptionError === undefined, 'simple blob tx run succeeds') assert.equal(res.blobGasUsed, 131072n, 'returns correct blob gas used for 1 blob') Blockchain.prototype.getBlock = oldGetBlockFunction diff --git a/packages/vm/test/api/state/accountExists.spec.ts b/packages/vm/test/api/state/accountExists.spec.ts index 042dba70ad..8e3da9c557 100644 --- a/packages/vm/test/api/state/accountExists.spec.ts +++ b/packages/vm/test/api/state/accountExists.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Account, Address, hexToBytes, toBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src/vm' +import { VM } from '../../../src/index.js' import type { DefaultStateManager } from '@ethereumjs/statemanager' diff --git a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts index 9e6bcf5ed7..10af87c5cb 100644 --- a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts +++ b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts @@ -16,7 +16,7 @@ import { toBytes, } from '@ethereumjs/util' -import { VM } from '../../../src/vm.js' +import { VM, buildBlock, runBlock } from '../../../src/index.js' import { setupPreConditions, verifyPostConditions } from '../../util.js' import type { Block } from '@ethereumjs/block' @@ -163,7 +163,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes // To run this field we try to import them on the current state. if (raw.transactionSequence !== undefined) { const parentBlock = await vm.blockchain.getIteratorHead() - const blockBuilder = await vm.buildBlock({ + const blockBuilder = await buildBlock(vm, { parentBlock, blockOpts: { calcDifficultyFromHeader: parentBlock.header }, }) @@ -206,7 +206,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes const parentState = parentBlock.header.stateRoot // run block, update head if valid try { - await vm.runBlock({ block, root: parentState, setHardfork: TD }) + await runBlock(vm, { block, root: parentState, setHardfork: TD }) // set as new head block } catch (error: any) { // remove invalid block diff --git a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts index 28edd7bf30..94f70a2007 100644 --- a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts +++ b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts @@ -5,7 +5,7 @@ import { DefaultStateManager } from '@ethereumjs/statemanager' import { Trie } from '@ethereumjs/trie' import { Account, Address, bytesToHex, equalsBytes, toBytes } from '@ethereumjs/util' -import { VM } from '../../../src/index.js' +import { VM, runTx } from '../../../src/index.js' import { makeBlockFromEnv, makeTx, setupPreConditions } from '../../util.js' import type * as tape from 'tape' @@ -143,7 +143,7 @@ async function runTestCase(options: any, testData: any, t: tape.Test) { vm.events.on('afterTx', afterTxHandler) } try { - await vm.runTx({ tx, block }) + await runTx(vm, { tx, block }) execInfo = 'successful tx run' } catch (e: any) { console.log(e) diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 8b7cd25c77..9bc35a8391 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -112,7 +112,7 @@ export function format(a: any, toZero: boolean = false, isHex: boolean = false): * Make a tx using JSON from tests repo * @param {Object} txData The tx object from tests repo * @param {TxOptions} opts Tx opts that can include an @ethereumjs/common object - * @returns {BlobEIP4844Transaction | FeeMarketEIP1559Transaction | AccessListEIP2930Transaction | LegacyTransaction} Transaction to be passed to VM.runTx function + * @returns {BlobEIP4844Transaction | FeeMarketEIP1559Transaction | AccessListEIP2930Transaction | LegacyTransaction} Transaction to be passed to runTx() function */ export function makeTx( txData: any, From 0e18cb29cf3f72d192c4a3b2502aa392d7ff58a4 Mon Sep 17 00:00:00 2001 From: Scotty <66335769+ScottyPoi@users.noreply.github.com> Date: Tue, 23 Jul 2024 02:43:28 -0600 Subject: [PATCH 14/58] util: Replace account static constructors (#3524) * Account: move static constructors to functions * update downstream * update examples * util: account constructors: use naming conventions --------- Co-authored-by: Jochem Brouwer Co-authored-by: Holger Drewes --- .../src/sync/fetcher/trienodefetcher.ts | 6 +- packages/statemanager/src/rpcStateManager.ts | 10 +- packages/statemanager/src/stateManager.ts | 14 +- .../src/statelessVerkleStateManager.ts | 18 +- .../statemanager/test/cache/account.spec.ts | 8 +- .../test/checkpointing.account.spec.ts | 13 +- .../statemanager/test/rpcStateManager.spec.ts | 4 +- .../test/stateManager.account.spec.ts | 12 +- .../test/stateManager.code.spec.ts | 12 +- .../test/stateManager.storage.spec.ts | 16 +- .../test/statelessVerkleStateManager.spec.ts | 4 +- packages/statemanager/test/util.ts | 2 +- packages/util/examples/account.ts | 4 +- packages/util/src/account.ts | 286 +++++++++--------- packages/util/test/account.spec.ts | 19 +- packages/vm/examples/helpers/account-utils.ts | 4 +- packages/vm/examples/run-blockchain.ts | 11 +- packages/vm/src/vm.ts | 10 +- .../EIPs/eip-1283-net-gas-metering.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 4 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-6110.spec.ts | 16 +- packages/vm/test/api/buildBlock.spec.ts | 4 +- packages/vm/test/api/copy.spec.ts | 4 +- .../vm/test/api/istanbul/eip-1884.spec.ts | 4 +- .../vm/test/api/istanbul/eip-2200.spec.ts | 4 +- packages/vm/test/api/runBlock.spec.ts | 8 +- packages/vm/test/api/runTx.spec.ts | 44 +-- packages/vm/test/api/utils.ts | 4 +- packages/vm/test/util.ts | 8 +- 30 files changed, 290 insertions(+), 271 deletions(-) diff --git a/packages/client/src/sync/fetcher/trienodefetcher.ts b/packages/client/src/sync/fetcher/trienodefetcher.ts index 3bf1a9c6a2..2d43589507 100644 --- a/packages/client/src/sync/fetcher/trienodefetcher.ts +++ b/packages/client/src/sync/fetcher/trienodefetcher.ts @@ -9,10 +9,10 @@ import { pathToHexKey, } from '@ethereumjs/trie' import { - Account, BIGINT_0, KECCAK256_NULL, KECCAK256_RLP, + createAccountFromRLP, unprefixedHexToBytes, } from '@ethereumjs/util' import { OrderedMap } from '@js-sdsl/ordered-map' @@ -253,7 +253,7 @@ export class TrieNodeFetcher extends Fetcher this.debug('leaf node found') if (storagePath === undefined) { this.debug('account leaf node found') - const account = Account.fromRlpSerializedAccount(node.value()) + const account = createAccountFromRLP(node.value()) const storageRoot: Uint8Array = account.storageRoot if (equalsBytes(storageRoot, KECCAK256_RLP) === false) { this.debug('storage component found') @@ -366,7 +366,7 @@ export class TrieNodeFetcher extends Fetcher } await storageTrie.batch(storageTrieOps, true) await storageTrie.persistRoot() - const a = Account.fromRlpSerializedAccount(node.value()) + const a = createAccountFromRLP(node.value()) this.debug( `Stored storageTrie with root actual=${bytesToHex( storageTrie.root() diff --git a/packages/statemanager/src/rpcStateManager.ts b/packages/statemanager/src/rpcStateManager.ts index 6aae3469af..8b6862891a 100644 --- a/packages/statemanager/src/rpcStateManager.ts +++ b/packages/statemanager/src/rpcStateManager.ts @@ -5,6 +5,8 @@ import { Account, bigIntToHex, bytesToHex, + createAccount, + createAccountFromRLP, equalsBytes, fetchFromProvider, hexToBytes, @@ -257,9 +259,7 @@ export class RPCStateManager implements EVMStateManagerInterface { async getAccount(address: Address): Promise { const elem = this._accountCache?.get(address) if (elem !== undefined) { - return elem.accountRLP !== undefined - ? Account.fromRlpSerializedAccount(elem.accountRLP) - : undefined + return elem.accountRLP !== undefined ? createAccountFromRLP(elem.accountRLP) : undefined } const accountFromProvider = await this.getAccountFromProvider(address) @@ -267,7 +267,7 @@ export class RPCStateManager implements EVMStateManagerInterface { equalsBytes(accountFromProvider.codeHash, new Uint8Array(32).fill(0)) || equalsBytes(accountFromProvider.serialize(), KECCAK256_RLP_EMPTY_ACCOUNT) ? undefined - : Account.fromRlpSerializedAccount(accountFromProvider.serialize()) + : createAccountFromRLP(accountFromProvider.serialize()) this._accountCache?.put(address, account) @@ -285,7 +285,7 @@ export class RPCStateManager implements EVMStateManagerInterface { method: 'eth_getProof', params: [address.toString(), [] as any, this._blockTag], }) - const account = Account.fromAccountData({ + const account = createAccount({ balance: BigInt(accountData.balance), nonce: BigInt(accountData.nonce), codeHash: toBytes(accountData.codeHash), diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 6ba58ebfd7..84a0da6e8a 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -13,6 +13,8 @@ import { bytesToHex, bytesToUnprefixedHex, concatBytes, + createAccount, + createAccountFromRLP, equalsBytes, hexToBytes, setLengthLeft, @@ -274,14 +276,12 @@ export class DefaultStateManager implements EVMStateManagerInterface { if (!this._accountCacheSettings.deactivate) { const elem = this._accountCache!.get(address) if (elem !== undefined) { - return elem.accountRLP !== undefined - ? Account.fromRlpSerializedAccount(elem.accountRLP) - : undefined + return elem.accountRLP !== undefined ? createAccountFromRLP(elem.accountRLP) : undefined } } const rlp = await this._trie.get(address.bytes) - const account = rlp !== null ? Account.fromRlpSerializedAccount(rlp) : undefined + const account = rlp !== null ? createAccountFromRLP(rlp) : undefined if (this.DEBUG) { this._debug(`Get account ${address} from DB (${account ? 'exists' : 'non-existent'})`) } @@ -896,7 +896,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { throw new Error(`${notEmptyErrorMsg} (codeHash does not equal KECCAK256_NULL)`) } } else { - const account = Account.fromRlpSerializedAccount(value) + const account = createAccountFromRLP(value) const { nonce, balance, storageRoot, codeHash } = account const invalidErrorMsg = 'Invalid proof provided:' if (nonce !== BigInt(proof.nonce)) { @@ -1085,12 +1085,12 @@ export class DefaultStateManager implements EVMStateManagerInterface { const state = initState[address] if (!Array.isArray(state)) { // Prior format: address -> balance - const account = Account.fromAccountData({ balance: state }) + const account = createAccount({ balance: state }) await this.putAccount(addr, account) } else { // New format: address -> [balance, code, storage] const [balance, code, storage, nonce] = state - const account = Account.fromAccountData({ balance, nonce }) + const account = createAccount({ balance, nonce }) await this.putAccount(addr, account) if (code !== undefined) { await this.putContractCode(addr, toBytes(code)) diff --git a/packages/statemanager/src/statelessVerkleStateManager.ts b/packages/statemanager/src/statelessVerkleStateManager.ts index 877a4fd273..b3b604d19c 100644 --- a/packages/statemanager/src/statelessVerkleStateManager.ts +++ b/packages/statemanager/src/statelessVerkleStateManager.ts @@ -7,6 +7,8 @@ import { bytesToBigInt, bytesToHex, bytesToInt32, + createPartialAccount, + createPartialAccountFromRLP, getVerkleKey, getVerkleStem, getVerkleTreeKeyForCodeChunk, @@ -423,9 +425,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const elem = this._accountCache!.get(address) if (elem !== undefined) { const account = - elem.accountRLP !== undefined - ? Account.fromRlpSerializedPartialAccount(elem.accountRLP) - : undefined + elem.accountRLP !== undefined ? createPartialAccountFromRLP(elem.accountRLP) : undefined if (account === undefined) { const errorMsg = `account=${account} in cache` debug(errorMsg) @@ -514,7 +514,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const elem = this._accountCache!.get(address) if (elem !== undefined) { return elem.accountRLP !== undefined - ? Account.fromRlpSerializedPartialAccount(elem.accountRLP) + ? createPartialAccountFromRLP(elem.accountRLP) : undefined } } @@ -572,7 +572,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { throw Error(errorMsg) } - const account = Account.fromPartialAccountData({ + const account = createPartialAccount({ version: typeof versionRaw === 'string' ? bytesToInt32(hexToBytes(versionRaw), true) : null, balance: typeof balanceRaw === 'string' ? bytesToBigInt(hexToBytes(balanceRaw), true) : null, nonce: typeof nonceRaw === 'string' ? bytesToBigInt(hexToBytes(nonceRaw), true) : null, @@ -777,7 +777,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { return null } - const balanceBigint = Account.fromRlpSerializedPartialAccount(encodedAccount).balance + const balanceBigint = createPartialAccountFromRLP(encodedAccount).balance return bytesToHex(setLengthRight(bigIntToBytes(balanceBigint, true), 32)) } @@ -786,7 +786,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { if (encodedAccount === undefined) { return null } - const nonceBigint = Account.fromRlpSerializedPartialAccount(encodedAccount).nonce + const nonceBigint = createPartialAccountFromRLP(encodedAccount).nonce return bytesToHex(setLengthRight(bigIntToBytes(nonceBigint, true), 32)) } @@ -795,7 +795,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { if (encodedAccount === undefined) { return null } - return bytesToHex(Account.fromRlpSerializedPartialAccount(encodedAccount).codeHash) + return bytesToHex(createPartialAccountFromRLP(encodedAccount).codeHash) } case AccessedStateType.CodeSize: { @@ -807,7 +807,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { return null } - const account = Account.fromRlpSerializedPartialAccount(encodedAccount) + const account = createPartialAccountFromRLP(encodedAccount) if (account.isContract()) { const errorMsg = `Code cache not found for address=${address.toString()}` debug(errorMsg) diff --git a/packages/statemanager/test/cache/account.spec.ts b/packages/statemanager/test/cache/account.spec.ts index a4cdffe844..6570b3f62f 100644 --- a/packages/statemanager/test/cache/account.spec.ts +++ b/packages/statemanager/test/cache/account.spec.ts @@ -2,7 +2,7 @@ import { Account, Address, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { AccountCache, CacheType } from '../../src/cache/index.js' -import { createAccount } from '../util.js' +import { createAccountWithDefaults } from '../util.js' describe('Account Cache: initialization', () => { for (const type of [CacheType.LRU, CacheType.ORDERED_MAP]) { @@ -19,7 +19,7 @@ describe('Account Cache: put and get account', () => { const cache = new AccountCache({ size: 100, type }) const addr = new Address(hexToBytes(`0x${'10'.repeat(20)}`)) - const acc: Account = createAccount(BigInt(1), BigInt(0xff11)) + const acc: Account = createAccountWithDefaults(BigInt(1), BigInt(0xff11)) const accRLP = acc.serialize() it('should return undefined for CacheElement if account not present in the cache', async () => { @@ -52,10 +52,10 @@ describe('Account Cache: checkpointing', () => { const cache = new AccountCache({ size: 100, type }) const addr = new Address(hexToBytes(`0x${'10'.repeat(20)}`)) - const acc = createAccount(BigInt(1), BigInt(0xff11)) + const acc = createAccountWithDefaults(BigInt(1), BigInt(0xff11)) const accRLP = acc.serialize() - const updatedAcc = createAccount(BigInt(0x00), BigInt(0xff00)) + const updatedAcc = createAccountWithDefaults(BigInt(0x00), BigInt(0xff00)) const updatedAccRLP = updatedAcc.serialize() it(`should revert to correct state`, async () => { diff --git a/packages/statemanager/test/checkpointing.account.spec.ts b/packages/statemanager/test/checkpointing.account.spec.ts index 95074d2d59..5222174b2c 100644 --- a/packages/statemanager/test/checkpointing.account.spec.ts +++ b/packages/statemanager/test/checkpointing.account.spec.ts @@ -1,9 +1,10 @@ -import { Account, Address, hexToBytes } from '@ethereumjs/util' +import { Address, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { DefaultStateManager, SimpleStateManager } from '../src/index.js' import type { StateManagerInterface } from '@ethereumjs/common' +import type { Account } from '@ethereumjs/util' /** * Compares account read to none or undefined @@ -33,31 +34,31 @@ describe('StateManager -> Account Checkpointing', () => { const stateManagers = [DefaultStateManager, SimpleStateManager] const accountN1: CompareList = [ - Account.fromAccountData({ + createAccount({ nonce: 1, }), 1n, ] const accountN2: CompareList = [ - Account.fromAccountData({ + createAccount({ nonce: 2, }), 2n, ] const accountN3: CompareList = [ - Account.fromAccountData({ + createAccount({ nonce: 3, }), 3n, ] const accountN4: CompareList = [ - Account.fromAccountData({ + createAccount({ nonce: 4, }), 4n, ] const accountN5: CompareList = [ - Account.fromAccountData({ + createAccount({ nonce: 5, }), 5n, diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index bcdcb0f29c..c8b50311a5 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -3,11 +3,11 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { type EVMRunCallOpts, createEVM } from '@ethereumjs/evm' import { FeeMarketEIP1559Transaction, createTxFromRPC } from '@ethereumjs/tx' import { - Account, Address, bigIntToBytes, bytesToHex, bytesToUnprefixedHex, + createAccountFromRLP, equalsBytes, hexToBytes, setLengthLeft, @@ -85,7 +85,7 @@ describe('RPC State Manager API tests', () => { await state.putAccount(vitalikDotEth, account!) - const retrievedVitalikAccount = Account.fromRlpSerializedAccount( + const retrievedVitalikAccount = createAccountFromRLP( (state as any)._accountCache.get(vitalikDotEth)!.accountRLP ) diff --git a/packages/statemanager/test/stateManager.account.spec.ts b/packages/statemanager/test/stateManager.account.spec.ts index e98256c146..5da058107b 100644 --- a/packages/statemanager/test/stateManager.account.spec.ts +++ b/packages/statemanager/test/stateManager.account.spec.ts @@ -3,7 +3,7 @@ import { assert, describe, it } from 'vitest' import { DefaultStateManager } from '../src/index.js' -import { createAccount } from './util.js' +import { createAccountWithDefaults } from './util.js' describe('StateManager -> General/Account', () => { for (const accountCacheOpts of [ @@ -17,7 +17,7 @@ describe('StateManager -> General/Account', () => { // commit some data to the trie const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount(BigInt(0), BigInt(1000)) + const account = createAccountWithDefaults(BigInt(0), BigInt(1000)) await stateManager.checkpoint() await stateManager.putAccount(address, account) await stateManager.commit() @@ -34,7 +34,7 @@ describe('StateManager -> General/Account', () => { it(`should clear the cache when the state root is set`, async () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount() + const account = createAccountWithDefaults() // test account storage cache const initialStateRoot = await stateManager.getStateRoot() @@ -76,7 +76,7 @@ describe('StateManager -> General/Account', () => { it('should put and get account, and add to the underlying cache if the account is not found', async () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) - const account = createAccount() + const account = createAccountWithDefaults() const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) await stateManager.putAccount(address, account) @@ -104,7 +104,7 @@ describe('StateManager -> General/Account', () => { it(`should return undefined for an existent account`, async () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) - const account = createAccount(BigInt(0x1), BigInt(0x1)) + const account = createAccountWithDefaults(BigInt(0x1), BigInt(0x1)) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) await stateManager.putAccount(address, account) @@ -116,7 +116,7 @@ describe('StateManager -> General/Account', () => { it(`should modify account fields correctly`, async () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) - const account = createAccount() + const account = createAccountWithDefaults() const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) await stateManager.putAccount(address, account) diff --git a/packages/statemanager/test/stateManager.code.spec.ts b/packages/statemanager/test/stateManager.code.spec.ts index fd5dca0faf..3ceea7791c 100644 --- a/packages/statemanager/test/stateManager.code.spec.ts +++ b/packages/statemanager/test/stateManager.code.spec.ts @@ -1,9 +1,9 @@ -import { Account, Address, equalsBytes, hexToBytes } from '@ethereumjs/util' +import { Address, createAccount, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { DefaultStateManager } from '../src/index.js' -import { createAccount } from './util.js' +import { createAccountWithDefaults } from './util.js' import type { AccountData } from '@ethereumjs/util' @@ -28,7 +28,7 @@ describe('StateManager -> Code', () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) const codeStateManager = new DefaultStateManager({ accountCacheOpts }) const address1 = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount() + const account = createAccountWithDefaults() const key1 = hexToBytes(`0x${'00'.repeat(32)}`) const key2 = hexToBytes(`0x${'00'.repeat(31)}01`) @@ -91,7 +91,7 @@ describe('StateManager -> Code', () => { balance: '0x03e7', codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4', } - const account = Account.fromAccountData(raw) + const account = createAccount(raw) await stateManager.putAccount(address, account) await stateManager.putContractCode(address, code) const codeRetrieved = await stateManager.getContractCode(address) @@ -105,7 +105,7 @@ describe('StateManager -> Code', () => { nonce: '0x0', balance: '0x03e7', } - const account = Account.fromAccountData(raw) + const account = createAccount(raw) await stateManager.putAccount(address, account) const code = await stateManager.getContractCode(address) assert.ok(equalsBytes(code, new Uint8Array(0))) @@ -118,7 +118,7 @@ describe('StateManager -> Code', () => { nonce: '0x0', balance: '0x03e7', } - const account = Account.fromAccountData(raw) + const account = createAccount(raw) const code = new Uint8Array(0) await stateManager.putAccount(address, account) await stateManager.putContractCode(address, code) diff --git a/packages/statemanager/test/stateManager.storage.spec.ts b/packages/statemanager/test/stateManager.storage.spec.ts index 48212138dd..d3829a1028 100644 --- a/packages/statemanager/test/stateManager.storage.spec.ts +++ b/packages/statemanager/test/stateManager.storage.spec.ts @@ -12,7 +12,7 @@ import { assert, describe, it } from 'vitest' import { DefaultStateManager } from '../src/index.js' -import { createAccount } from './util.js' +import { createAccountWithDefaults } from './util.js' const isBrowser = new Function('try {return this===window;}catch(e){ return false;}') describe('StateManager -> Storage', () => { @@ -25,7 +25,7 @@ describe('StateManager -> Storage', () => { it.skipIf(isBrowser() === true)(`should dump storage`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) @@ -41,7 +41,7 @@ describe('StateManager -> Storage', () => { it("should validate the key's length when modifying a contract's storage", async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) try { @@ -57,7 +57,7 @@ describe('StateManager -> Storage', () => { it("should validate the key's length when reading a contract's storage", async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) try { @@ -73,7 +73,7 @@ describe('StateManager -> Storage', () => { it(`should throw on storage values larger than 32 bytes`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = Address.zero() - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) const key = zeros(32) @@ -89,7 +89,7 @@ describe('StateManager -> Storage', () => { it(`should strip zeros of storage values`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = Address.zero() - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) const key0 = zeros(32) @@ -118,7 +118,7 @@ describe('StateManager -> Storage', () => { for (const length of zeroLengths) { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) const value = zeros(length) @@ -139,7 +139,7 @@ describe('StateManager -> Storage', () => { it(`should not strip trailing zeros`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) const address = Address.zero() - const account = createAccount() + const account = createAccountWithDefaults() await stateManager.putAccount(address, account) const key = zeros(32) diff --git a/packages/statemanager/test/statelessVerkleStateManager.spec.ts b/packages/statemanager/test/statelessVerkleStateManager.spec.ts index f11144c905..e78030455e 100644 --- a/packages/statemanager/test/statelessVerkleStateManager.spec.ts +++ b/packages/statemanager/test/statelessVerkleStateManager.spec.ts @@ -2,11 +2,11 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createCommonFromGethGenesis } from '@ethereumjs/common' import { createTxFromSerializedData } from '@ethereumjs/tx' import { - Account, Address, VerkleLeafType, bytesToBigInt, bytesToHex, + createAccount, getVerkleKey, getVerkleStem, hexToBytes, @@ -84,7 +84,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { ) } - const account = Account.fromAccountData({ + const account = createAccount({ nonce: BigInt(2), }) diff --git a/packages/statemanager/test/util.ts b/packages/statemanager/test/util.ts index 8683e08dc6..708c7e2b81 100644 --- a/packages/statemanager/test/util.ts +++ b/packages/statemanager/test/util.ts @@ -1,5 +1,5 @@ import { Account } from '@ethereumjs/util' -export function createAccount(nonce = BigInt(0), balance = BigInt(0xfff384)) { +export function createAccountWithDefaults(nonce = BigInt(0), balance = BigInt(0xfff384)) { return new Account(nonce, balance) } diff --git a/packages/util/examples/account.ts b/packages/util/examples/account.ts index 088e793049..b0d1f25cbb 100644 --- a/packages/util/examples/account.ts +++ b/packages/util/examples/account.ts @@ -1,6 +1,6 @@ -import { Account } from '@ethereumjs/util' +import { createAccount } from '@ethereumjs/util' -const account = Account.fromAccountData({ +const account = createAccount({ nonce: '0x02', balance: '0x0384', storageRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', diff --git a/packages/util/src/account.ts b/packages/util/src/account.ts index 0397805c7e..2ade70908d 100644 --- a/packages/util/src/account.ts +++ b/packages/util/src/account.ts @@ -124,148 +124,6 @@ export class Account { this._codeSize = _codeSize } - static fromAccountData(accountData: AccountData) { - const { nonce, balance, storageRoot, codeHash } = accountData - if (nonce === null || balance === null || storageRoot === null || codeHash === null) { - throw Error(`Partial fields not supported in fromAccountData`) - } - - return new Account( - nonce !== undefined ? bytesToBigInt(toBytes(nonce)) : undefined, - balance !== undefined ? bytesToBigInt(toBytes(balance)) : undefined, - storageRoot !== undefined ? toBytes(storageRoot) : undefined, - codeHash !== undefined ? toBytes(codeHash) : undefined - ) - } - - static fromPartialAccountData(partialAccountData: PartialAccountData) { - const { nonce, balance, storageRoot, codeHash, codeSize, version } = partialAccountData - - if ( - nonce === null && - balance === null && - storageRoot === null && - codeHash === null && - codeSize === null && - version === null - ) { - throw Error(`All partial fields null`) - } - - return new Account( - nonce !== undefined && nonce !== null ? bytesToBigInt(toBytes(nonce)) : nonce, - balance !== undefined && balance !== null ? bytesToBigInt(toBytes(balance)) : balance, - storageRoot !== undefined && storageRoot !== null ? toBytes(storageRoot) : storageRoot, - codeHash !== undefined && codeHash !== null ? toBytes(codeHash) : codeHash, - codeSize !== undefined && codeSize !== null ? bytesToInt(toBytes(codeSize)) : codeSize, - version !== undefined && version !== null ? bytesToInt(toBytes(version)) : version - ) - } - - public static fromRlpSerializedAccount(serialized: Uint8Array) { - const values = RLP.decode(serialized) as Uint8Array[] - - if (!Array.isArray(values)) { - throw new Error('Invalid serialized account input. Must be array') - } - - return this.fromValuesArray(values) - } - - public static fromRlpSerializedPartialAccount(serialized: Uint8Array) { - const values = RLP.decode(serialized) as Uint8Array[][] - - if (!Array.isArray(values)) { - throw new Error('Invalid serialized account input. Must be array') - } - - let nonce = null - if (!Array.isArray(values[0])) { - throw new Error('Invalid partial nonce encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[0][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for nonce`) - } - if (isNotNullIndicator === 1) { - nonce = bytesToBigInt(values[0][1]) - } - } - - let balance = null - if (!Array.isArray(values[1])) { - throw new Error('Invalid partial balance encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[1][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for balance`) - } - if (isNotNullIndicator === 1) { - balance = bytesToBigInt(values[1][1]) - } - } - - let storageRoot = null - if (!Array.isArray(values[2])) { - throw new Error('Invalid partial storageRoot encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[2][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for storageRoot`) - } - if (isNotNullIndicator === 1) { - storageRoot = values[2][1] - } - } - - let codeHash = null - if (!Array.isArray(values[3])) { - throw new Error('Invalid partial codeHash encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[3][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for codeHash`) - } - if (isNotNullIndicator === 1) { - codeHash = values[3][1] - } - } - - let codeSize = null - if (!Array.isArray(values[4])) { - throw new Error('Invalid partial codeSize encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[4][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for codeSize`) - } - if (isNotNullIndicator === 1) { - codeSize = bytesToInt(values[4][1]) - } - } - - let version = null - if (!Array.isArray(values[5])) { - throw new Error('Invalid partial version encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[5][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for version`) - } - if (isNotNullIndicator === 1) { - version = bytesToInt(values[5][1]) - } - } - - return this.fromPartialAccountData({ balance, nonce, storageRoot, codeHash, codeSize, version }) - } - - public static fromValuesArray(values: Uint8Array[]) { - const [nonce, balance, storageRoot, codeHash] = values - - return new Account(bytesToBigInt(nonce), bytesToBigInt(balance), storageRoot, codeHash) - } - /** * This constructor assigns and validates the values. * Use the static factory methods to assist in creating an Account from varying data types. @@ -410,6 +268,150 @@ export class Account { } } +// Account constructors + +export function createAccount(accountData: AccountData) { + const { nonce, balance, storageRoot, codeHash } = accountData + if (nonce === null || balance === null || storageRoot === null || codeHash === null) { + throw Error(`Partial fields not supported in fromAccountData`) + } + + return new Account( + nonce !== undefined ? bytesToBigInt(toBytes(nonce)) : undefined, + balance !== undefined ? bytesToBigInt(toBytes(balance)) : undefined, + storageRoot !== undefined ? toBytes(storageRoot) : undefined, + codeHash !== undefined ? toBytes(codeHash) : undefined + ) +} + +export function createAccountFromBytesArray(values: Uint8Array[]) { + const [nonce, balance, storageRoot, codeHash] = values + + return new Account(bytesToBigInt(nonce), bytesToBigInt(balance), storageRoot, codeHash) +} + +export function createPartialAccount(partialAccountData: PartialAccountData) { + const { nonce, balance, storageRoot, codeHash, codeSize, version } = partialAccountData + + if ( + nonce === null && + balance === null && + storageRoot === null && + codeHash === null && + codeSize === null && + version === null + ) { + throw Error(`All partial fields null`) + } + + return new Account( + nonce !== undefined && nonce !== null ? bytesToBigInt(toBytes(nonce)) : nonce, + balance !== undefined && balance !== null ? bytesToBigInt(toBytes(balance)) : balance, + storageRoot !== undefined && storageRoot !== null ? toBytes(storageRoot) : storageRoot, + codeHash !== undefined && codeHash !== null ? toBytes(codeHash) : codeHash, + codeSize !== undefined && codeSize !== null ? bytesToInt(toBytes(codeSize)) : codeSize, + version !== undefined && version !== null ? bytesToInt(toBytes(version)) : version + ) +} + +export function createAccountFromRLP(serialized: Uint8Array) { + const values = RLP.decode(serialized) as Uint8Array[] + + if (!Array.isArray(values)) { + throw new Error('Invalid serialized account input. Must be array') + } + + return createAccountFromBytesArray(values) +} + +export function createPartialAccountFromRLP(serialized: Uint8Array) { + const values = RLP.decode(serialized) as Uint8Array[][] + + if (!Array.isArray(values)) { + throw new Error('Invalid serialized account input. Must be array') + } + + let nonce = null + if (!Array.isArray(values[0])) { + throw new Error('Invalid partial nonce encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[0][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for nonce`) + } + if (isNotNullIndicator === 1) { + nonce = bytesToBigInt(values[0][1]) + } + } + + let balance = null + if (!Array.isArray(values[1])) { + throw new Error('Invalid partial balance encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[1][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for balance`) + } + if (isNotNullIndicator === 1) { + balance = bytesToBigInt(values[1][1]) + } + } + + let storageRoot = null + if (!Array.isArray(values[2])) { + throw new Error('Invalid partial storageRoot encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[2][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for storageRoot`) + } + if (isNotNullIndicator === 1) { + storageRoot = values[2][1] + } + } + + let codeHash = null + if (!Array.isArray(values[3])) { + throw new Error('Invalid partial codeHash encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[3][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for codeHash`) + } + if (isNotNullIndicator === 1) { + codeHash = values[3][1] + } + } + + let codeSize = null + if (!Array.isArray(values[4])) { + throw new Error('Invalid partial codeSize encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[4][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for codeSize`) + } + if (isNotNullIndicator === 1) { + codeSize = bytesToInt(values[4][1]) + } + } + + let version = null + if (!Array.isArray(values[5])) { + throw new Error('Invalid partial version encoding. Must be array') + } else { + const isNotNullIndicator = bytesToInt(values[5][0]) + if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { + throw new Error(`Invalid isNullIndicator=${isNotNullIndicator} for version`) + } + if (isNotNullIndicator === 1) { + version = bytesToInt(values[5][1]) + } + } + + return createPartialAccount({ balance, nonce, storageRoot, codeHash, codeSize, version }) +} + /** * Checks if the address is a valid. Accepts checksummed addresses too. */ diff --git a/packages/util/test/account.spec.ts b/packages/util/test/account.spec.ts index 4d2bca3d4b..b7a37eb53d 100644 --- a/packages/util/test/account.spec.ts +++ b/packages/util/test/account.spec.ts @@ -10,6 +10,9 @@ import { accountBodyToSlim, bytesToBigInt, bytesToHex, + createAccount, + createAccountFromBytesArray, + createAccountFromRLP, equalsBytes, generateAddress, generateAddress2, @@ -61,7 +64,7 @@ describe('Account', () => { '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', // storageRoot '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', // codeHash ] - const account = Account.fromValuesArray(raw.map((el) => hexToBytes(el))) + const account = createAccountFromBytesArray(raw.map((el) => hexToBytes(el))) assert.equal(account.nonce, BigInt(2), 'should have correct nonce') assert.equal(account.balance, BigInt(900), 'should have correct balance') @@ -84,7 +87,7 @@ describe('Account', () => { storageRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', codeHash: '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', } - const account = Account.fromAccountData(raw) + const account = createAccount(raw) assert.equal(account.nonce, BigInt(2), 'should have correct nonce') assert.equal(account.balance, BigInt(900), 'should have correct balance') assert.equal( @@ -103,7 +106,7 @@ describe('Account', () => { const accountRlp = hexToBytes( '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' ) - const account = Account.fromRlpSerializedAccount(accountRlp) + const account = createAccountFromRLP(accountRlp) assert.equal(account.nonce, BigInt(2), 'should have correct nonce') assert.equal(account.balance, BigInt(900), 'should have correct balance') assert.equal( @@ -125,7 +128,7 @@ describe('Account', () => { storageRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', codeHash: '0xc5d2461236f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', } - const account = Account.fromAccountData(raw) + const account = createAccount(raw) const accountRlp = RLP.encode([raw.nonce, raw.balance, raw.storageRoot, raw.codeHash] as Input) assert.ok(equalsBytes(account.serialize(), accountRlp), 'should serialize correctly') @@ -135,7 +138,7 @@ describe('Account', () => { const accountRlp = hexToBytes( '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' ) - let account = Account.fromRlpSerializedAccount(accountRlp) + let account = createAccountFromRLP(accountRlp) assert.notOk(account.isContract(), 'should return false for a non-contract account') const raw: AccountData = { @@ -144,7 +147,7 @@ describe('Account', () => { storageRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', codeHash: '0xc5d2461236f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', } - account = Account.fromAccountData(raw) + account = createAccount(raw) assert.ok(account.isContract(), 'should return true for a contract account') }) @@ -158,7 +161,7 @@ describe('Account', () => { storageRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', codeHash: '0xd748bf26ab37599c944babfdbeecf6690801bd61bf2670efb0a34adfc6dca10b', } - account = Account.fromAccountData(raw) + account = createAccount(raw) assert.notOk(account.isEmpty(), 'should return false for a non-empty account') }) @@ -184,7 +187,7 @@ describe('Account', () => { const data = { balance: BigInt(5) } assert.throws( () => { - Account.fromRlpSerializedAccount(data as any) + createAccountFromRLP(data as any) }, undefined, undefined, diff --git a/packages/vm/examples/helpers/account-utils.ts b/packages/vm/examples/helpers/account-utils.ts index c5db9a3c3e..97d56a10af 100644 --- a/packages/vm/examples/helpers/account-utils.ts +++ b/packages/vm/examples/helpers/account-utils.ts @@ -1,5 +1,5 @@ import { VM } from '@ethereumjs/vm' -import { Account, Address } from '@ethereumjs/util' +import { Account, createAccount, Address } from '@ethereumjs/util' export const keyPair = { secretKey: '0x3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', @@ -12,7 +12,7 @@ export const insertAccount = async (vm: VM, address: Address) => { nonce: 0, balance: BigInt(10) ** BigInt(18), // 1 eth } - const account = Account.fromAccountData(acctData) + const account = createAccount(acctData) await vm.stateManager.putAccount(address, account) } diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index 02f18cc383..b50a1d44e3 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -6,7 +6,14 @@ // 4. Puts the blocks from ../utils/blockchain-mock-data "blocks" attribute into the Blockchain // 5. Runs the Blockchain on the VM. -import { Account, Address, toBytes, setLengthLeft, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { + Address, + toBytes, + setLengthLeft, + bytesToHex, + hexToBytes, + createAccount, +} from '@ethereumjs/util' import { Block, createBlockFromBlockData, @@ -68,7 +75,7 @@ async function setupPreConditions(vm: VM, data: any) { const { nonce, balance, storage, code } = acct as any const address = new Address(hexToBytes(addr)) - const account = Account.fromAccountData({ nonce, balance }) + const account = createAccount({ nonce, balance }) await vm.stateManager.putAccount(address, account) for (const [key, val] of Object.entries(storage)) { diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index ddd6242b57..b41b7e8f12 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -2,7 +2,13 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common } from '@ethereumjs/common' import { createEVM, getActivePrecompiles } from '@ethereumjs/evm' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { Account, Address, AsyncEventEmitter, unprefixedHexToBytes } from '@ethereumjs/util' +import { + Account, + Address, + AsyncEventEmitter, + createAccount, + unprefixedHexToBytes, +} from '@ethereumjs/util' import type { VMEvents, VMOpts } from './types.js' import type { BlockchainInterface } from '@ethereumjs/blockchain' @@ -129,7 +135,7 @@ export class VM { // Note: in the case that custom genesis has storage fields, this is preserved if (account === undefined) { account = new Account() - const newAccount = Account.fromAccountData({ + const newAccount = createAccount({ balance: 1, storageRoot: account.storageRoot, }) diff --git a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts index c2809098bf..f772db6d6f 100644 --- a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts @@ -3,7 +3,7 @@ import { Address, bigIntToBytes, hexToBytes, setLengthLeft } from '@ethereumjs/u import { assert, describe, it } from 'vitest' import { VM } from '../../../src/index.js' -import { createAccount } from '../utils.js' +import { createAccountWithDefaults } from '../utils.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -40,7 +40,7 @@ describe('Constantinople: EIP-1283', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Constantinople }) const vm = await VM.create({ common }) - const account = createAccount(BigInt(0), BigInt(0)) + const account = createAccountWithDefaults(BigInt(0), BigInt(0)) await vm.stateManager.putAccount(addr, account) await vm.stateManager.putContractCode(addr, hexToBytes(testCase.code as PrefixedHexString)) if (testCase.original !== BigInt(0)) { diff --git a/packages/vm/test/api/EIPs/eip-2929.spec.ts b/packages/vm/test/api/EIPs/eip-2929.spec.ts index fe9f897b64..1d983ca078 100644 --- a/packages/vm/test/api/EIPs/eip-2929.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2929.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { LegacyTransaction } from '@ethereumjs/tx' -import { Account, Address, hexToBytes } from '@ethereumjs/util' +import { Address, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { VM, runTx } from '../../../src/index.js' @@ -90,7 +90,7 @@ describe('EIP 2929: gas cost tests', () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - Account.fromAccountData({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }) ) const result = await runTx(vm, { tx, skipHardForkValidation: true }) diff --git a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts index 87d78685a5..8ba549f17c 100644 --- a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { AccessListEIP2930Transaction } from '@ethereumjs/tx' -import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { Address, bytesToHex, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { VM, runTx } from '../../../src/index.js' @@ -56,7 +56,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - Account.fromAccountData({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }) ) let trace: any = [] diff --git a/packages/vm/test/api/EIPs/eip-6110.spec.ts b/packages/vm/test/api/EIPs/eip-6110.spec.ts index 10f14edf62..2dd631d6a9 100644 --- a/packages/vm/test/api/EIPs/eip-6110.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6110.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork, getInitializedChains } from '@ethereumjs/common' import { createTxFromTxData } from '@ethereumjs/tx' -import { Account, Address, bytesToHex, hexToBytes, randomBytes } from '@ethereumjs/util' +import { Address, bytesToHex, createAccount, hexToBytes, randomBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' @@ -42,16 +42,13 @@ describe('EIP-6110 runBlock tests', () => { type: 2, to: DEPOSIT_CONTRACT_ADDRESS, }).sign(pk) - const beaconContractAccount = Account.fromAccountData({ + const beaconContractAccount = createAccount({ codeHash: keccak256(depositContractByteCode), }) const beaconContractAddress = Address.fromString(DEPOSIT_CONTRACT_ADDRESS) await vm.stateManager.putAccount(beaconContractAddress, beaconContractAccount) await vm.stateManager.putContractCode(beaconContractAddress, depositContractByteCode) - await vm.stateManager.putAccount( - sender, - Account.fromAccountData({ balance: 540000000030064771065n }) - ) + await vm.stateManager.putAccount(sender, createAccount({ balance: 540000000030064771065n })) const block = createBlockFromBlockData( { transactions: [depositTx], @@ -78,16 +75,13 @@ describe('EIP-7685 buildBlock tests', () => { type: 2, to: DEPOSIT_CONTRACT_ADDRESS, }).sign(pk) - const beaconContractAccount = Account.fromAccountData({ + const beaconContractAccount = createAccount({ codeHash: keccak256(depositContractByteCode), }) const beaconContractAddress = Address.fromString(DEPOSIT_CONTRACT_ADDRESS) await vm.stateManager.putAccount(beaconContractAddress, beaconContractAccount) await vm.stateManager.putContractCode(beaconContractAddress, depositContractByteCode) - await vm.stateManager.putAccount( - sender, - Account.fromAccountData({ balance: 540000000030064771065n }) - ) + await vm.stateManager.putAccount(sender, createAccount({ balance: 540000000030064771065n })) const block = createBlockFromBlockData({}, { common }) ;(vm.blockchain as any)['dbManager']['getHeader'] = () => block.header const blockBuilder = await buildBlock(vm, { parentBlock: block }) diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index f5845415f9..33cebdfee5 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -9,7 +9,7 @@ import { } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' -import { Account, Address, concatBytes, hexToBytes } from '@ethereumjs/util' +import { Address, concatBytes, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { buildBlock, runBlock } from '../../src/index.js' @@ -200,7 +200,7 @@ describe('BlockBuilder', () => { const vm = await VM.create({ common, blockchain }) // add balance for tx - await vm.stateManager.putAccount(signer.address, Account.fromAccountData({ balance: 100000 })) + await vm.stateManager.putAccount(signer.address, createAccount({ balance: 100000 })) const blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock, diff --git a/packages/vm/test/api/copy.spec.ts b/packages/vm/test/api/copy.spec.ts index 0a5ffa463c..3250cda902 100644 --- a/packages/vm/test/api/copy.spec.ts +++ b/packages/vm/test/api/copy.spec.ts @@ -1,4 +1,4 @@ -import { Account, Address } from '@ethereumjs/util' +import { Address, createAccount } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { setupVM } from './utils' @@ -6,7 +6,7 @@ import { setupVM } from './utils' describe('VM Copy Test', () => { it('should pass copy of state manager', async () => { const vm = await setupVM() - const account = Account.fromAccountData({ + const account = createAccount({ balance: 100n, nonce: 5n, }) diff --git a/packages/vm/test/api/istanbul/eip-1884.spec.ts b/packages/vm/test/api/istanbul/eip-1884.spec.ts index 0cebb06a1a..e4d2c6231a 100644 --- a/packages/vm/test/api/istanbul/eip-1884.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1884.spec.ts @@ -4,7 +4,7 @@ import { Address, bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { VM } from '../../../src/index.js' -import { createAccount } from '../utils.js' +import { createAccountWithDefaults } from '../utils.js' const testCases = [ { chain: Chain.Mainnet, hardfork: Hardfork.Istanbul, selfbalance: '0xf1' }, @@ -28,7 +28,7 @@ describe('Istanbul: EIP-1884', () => { const vm = await VM.create({ common }) const balance = testCase.selfbalance !== undefined ? BigInt(testCase.selfbalance) : undefined - const account = createAccount(BigInt(0), balance) + const account = createAccountWithDefaults(BigInt(0), balance) await vm.stateManager.putAccount(addr, account) diff --git a/packages/vm/test/api/istanbul/eip-2200.spec.ts b/packages/vm/test/api/istanbul/eip-2200.spec.ts index 004e8ab249..66a12856c2 100644 --- a/packages/vm/test/api/istanbul/eip-2200.spec.ts +++ b/packages/vm/test/api/istanbul/eip-2200.spec.ts @@ -3,7 +3,7 @@ import { Address, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { VM } from '../../../src/index.js' -import { createAccount } from '../utils.js' +import { createAccountWithDefaults } from '../utils.js' const testCases = [ { @@ -52,7 +52,7 @@ describe('Istanbul: EIP-2200', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) const vm = await VM.create({ common }) - const account = createAccount(BigInt(0), BigInt(0)) + const account = createAccountWithDefaults(BigInt(0), BigInt(0)) await vm.stateManager.putAccount(addr, account) await vm.stateManager.putContractCode(addr, hexToBytes(`0x${testCase.code}`)) if (testCase.original !== BigInt(0)) { diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 788cffffc6..491c84db70 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -37,7 +37,7 @@ import { getDAOCommon, setupPreConditions } from '../util' import * as testData from './testdata/blockchain.json' import * as testnet from './testdata/testnet.json' -import { createAccount, setBalance, setupVM } from './utils' +import { createAccountWithDefaults, setBalance, setupVM } from './utils.js' import type { AfterBlockEvent, @@ -314,14 +314,14 @@ describe('runBlock() -> runtime behavior', async () => { // fill two original DAO child-contracts with funds and the recovery account with funds in order to verify that the balance gets summed correctly const fundBalance1 = BigInt('0x1111') - const accountFunded1 = createAccount(BigInt(0), fundBalance1) + const accountFunded1 = createAccountWithDefaults(BigInt(0), fundBalance1) const DAOFundedContractAddress1 = new Address( hexToBytes('0xd4fe7bc31cedb7bfb8a345f31e668033056b2728') ) await vm.stateManager.putAccount(DAOFundedContractAddress1, accountFunded1) const fundBalance2 = BigInt('0x2222') - const accountFunded2 = createAccount(BigInt(0), fundBalance2) + const accountFunded2 = createAccountWithDefaults(BigInt(0), fundBalance2) const DAOFundedContractAddress2 = new Address( hexToBytes('0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425') ) @@ -329,7 +329,7 @@ describe('runBlock() -> runtime behavior', async () => { const DAORefundAddress = new Address(hexToBytes('0xbf4ed7b27f1d666546e30d74d50d173d20bca754')) const fundBalanceRefund = BigInt('0x4444') - const accountRefund = createAccount(BigInt(0), fundBalanceRefund) + const accountRefund = createAccountWithDefaults(BigInt(0), fundBalanceRefund) await vm.stateManager.putAccount(DAORefundAddress, accountRefund) await runBlock(vm, { diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index 9e4adc4947..c725748f80 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -14,6 +14,7 @@ import { KECCAK256_NULL, MAX_INTEGER, bytesToHex, + createAccount, equalsBytes, hexToBytes, zeros, @@ -24,7 +25,7 @@ import { assert, describe, it } from 'vitest' import { runTx } from '../../src/index.js' import { VM } from '../../src/vm.js' -import { createAccount, getTransaction, setBalance } from './utils.js' +import { createAccountWithDefaults, getTransaction, setBalance } from './utils.js' import type { FeeMarketEIP1559TxData, TypedTxData } from '@ethereumjs/tx' @@ -51,7 +52,7 @@ describe('runTx() -> successful API parameter usage', async () => { const tx = getTransaction(vm.common, txType.type, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) let block if (vm.common.consensusType() === 'poa') { @@ -88,7 +89,7 @@ describe('runTx() -> successful API parameter usage', async () => { }) const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const block = createBlockFromBlockData({}, { common: vm.common.copy() }) await runTx(vm, { tx, block }) @@ -103,7 +104,7 @@ describe('runTx() -> successful API parameter usage', async () => { }) const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const block = createBlockFromBlockData({}, { common: vm.common.copy() }) @@ -146,7 +147,7 @@ describe('runTx() -> successful API parameter usage', async () => { }) const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const block = createBlockFromBlockData({}, { common: vm.common.copy() }) @@ -167,7 +168,7 @@ describe('runTx() -> successful API parameter usage', async () => { const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const blockGasUsed = BigInt(1000) @@ -186,7 +187,7 @@ describe('runTx() -> successful API parameter usage', async () => { const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const res = await runTx(vm, { tx }) @@ -209,7 +210,7 @@ describe('runTx() -> successful API parameter usage', async () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - Account.fromAccountData({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }) ) const transferCost = 21000 @@ -286,7 +287,7 @@ describe('runTx() -> API parameter usage/data errors', () => { ) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) try { @@ -307,7 +308,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const res = await runTx(vm, { tx, reportAccessList: true }) @@ -324,7 +325,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const tx = getTransaction(vm.common, 0, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const res = await runTx(vm, { tx, reportPreimages: true }) @@ -374,7 +375,10 @@ describe('runTx() -> API parameter usage/data errors', () => { const address = tx.getSenderAddress() tx = Object.create(tx) const maxCost: bigint = tx.gasLimit * tx.maxFeePerGas - await vm.stateManager.putAccount(address, createAccount(BigInt(0), maxCost - BigInt(1))) + await vm.stateManager.putAccount( + address, + createAccountWithDefaults(BigInt(0), maxCost - BigInt(1)) + ) try { await runTx(vm, { tx }) assert.fail('should throw error') @@ -385,7 +389,7 @@ describe('runTx() -> API parameter usage/data errors', () => { ) } // set sufficient balance - await vm.stateManager.putAccount(address, createAccount(BigInt(0), maxCost)) + await vm.stateManager.putAccount(address, createAccountWithDefaults(BigInt(0), maxCost)) const res = await runTx(vm, { tx }) assert.ok(res, 'should pass if balance is sufficient') }) @@ -482,7 +486,7 @@ describe('runTx() -> runtime behavior', () => { } const tx = createTxFromTxData(txParams, { common }).sign(privateKey) - await vm.stateManager.putAccount(tx.getSenderAddress(), createAccount()) + await vm.stateManager.putAccount(tx.getSenderAddress(), createAccountWithDefaults()) await runTx(vm, { tx }) // this tx will fail, but we have to ensure that the cache is cleared @@ -502,10 +506,10 @@ describe('runTx() -> runtime errors', () => { const tx = getTransaction(vm.common, txType.type, true, '0x01') const caller = tx.getSenderAddress() - const from = createAccount() + const from = createAccountWithDefaults() await vm.stateManager.putAccount(caller, from) - const to = createAccount(BigInt(0), MAX_INTEGER) + const to = createAccountWithDefaults(BigInt(0), MAX_INTEGER) await vm.stateManager.putAccount(tx.to!, to) const res = await runTx(vm, { tx }) @@ -529,11 +533,11 @@ describe('runTx() -> runtime errors', () => { const tx = getTransaction(vm.common, txType.type, true, '0x01', true) const caller = tx.getSenderAddress() - const from = createAccount() + const from = createAccountWithDefaults() await vm.stateManager.putAccount(caller, from) const contractAddress = Address.fromString('0x61de9dc6f6cff1df2809480882cfd3c2364b28f7') - const to = createAccount(BigInt(0), MAX_INTEGER) + const to = createAccountWithDefaults(BigInt(0), MAX_INTEGER) await vm.stateManager.putAccount(contractAddress, to) const res = await runTx(vm, { tx }) @@ -560,7 +564,7 @@ describe('runTx() -> API return values', () => { const tx = getTransaction(vm.common, txType.type, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const res = await runTx(vm, { tx }) @@ -589,7 +593,7 @@ describe('runTx() -> API return values', () => { const tx = getTransaction(vm.common, txType.type, true) const caller = tx.getSenderAddress() - const acc = createAccount() + const acc = createAccountWithDefaults() await vm.stateManager.putAccount(caller, acc) const res = await runTx(vm, { tx }) diff --git a/packages/vm/test/api/utils.ts b/packages/vm/test/api/utils.ts index 5262c6eb8a..3e88786b3c 100644 --- a/packages/vm/test/api/utils.ts +++ b/packages/vm/test/api/utils.ts @@ -18,12 +18,12 @@ import type { Block } from '@ethereumjs/block' import type { Common } from '@ethereumjs/common' import type { Address } from '@ethereumjs/util' -export function createAccount(nonce = BigInt(0), balance = BigInt(0xfff384)) { +export function createAccountWithDefaults(nonce = BigInt(0), balance = BigInt(0xfff384)) { return new Account(nonce, balance) } export async function setBalance(vm: VM, address: Address, balance = BigInt(100000000)) { - const account = createAccount(BigInt(0), balance) + const account = createAccountWithDefaults(BigInt(0), balance) await vm.stateManager.checkpoint() await vm.stateManager.putAccount(address, account) await vm.stateManager.commit() diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 9bc35a8391..93bf1d247a 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -14,6 +14,8 @@ import { bigIntToBytes, bytesToBigInt, bytesToHex, + createAccount, + createAccountFromRLP, equalsBytes, hexToBytes, isHexString, @@ -35,7 +37,7 @@ export function dumpState(state: any, cb: Function) { const rs = state.createReadStream() rs.on('data', function (data: any) { const rlp = data.value - const account = Account.fromRlpSerializedAccount(rlp) + const account = createAccountFromRLP(rlp) accounts.push(account) }) rs.on('end', function () { @@ -170,7 +172,7 @@ export async function verifyPostConditions(state: any, testData: any, t: tape.Te stream.on('data', function (data: any) { const rlp = data.value - const account = Account.fromRlpSerializedAccount(rlp) + const account = createAccountFromRLP(rlp) const key = bytesToHex(data.key) const testData = hashedAccounts[key] const address = keyMap[key] @@ -386,7 +388,7 @@ export async function setupPreConditions(state: EVMStateManagerInterface, testDa } // Put account data - const account = Account.fromAccountData({ nonce, balance, codeHash, storageRoot }) + const account = createAccount({ nonce, balance, codeHash, storageRoot }) await state.putAccount(address, account) } await state.commit() From f66a5e0d0ae405323eb06c95b657314085c87d0c Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Tue, 23 Jul 2024 19:20:52 +0200 Subject: [PATCH 15/58] Common Refactor (#3532) * Align gas price names * Throw for parameter accesses on non-existing values instead of implicitly 0-lifying * Gas price fixes * Some fixes * Fixes * Fix client eth_gasPrice RPC call test * Switch to a consistent EIP based structure (remove hybrid HF/EIP parameter structure) * Code simplifications, locally remove topic from param* API in Common, fix tests * Monorepo-wide topic removal * Fixes * Minor * Fix client test --- package.json | 5 + packages/block/src/block.ts | 8 +- packages/block/src/header.ts | 44 +- packages/block/test/eip1559block.spec.ts | 21 +- packages/block/test/eip4844block.spec.ts | 4 +- packages/blockchain/src/blockchain.ts | 2 +- packages/client/src/miner/miner.ts | 3 +- packages/client/src/miner/pendingBlock.ts | 8 +- packages/client/src/rpc/modules/eth.ts | 11 +- packages/client/test/miner/miner.spec.ts | 9 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 2 +- packages/common/examples/common.ts | 4 +- packages/common/src/chains.ts | 2 +- packages/common/src/common.ts | 131 ++--- packages/common/src/eips.ts | 515 ++++++++++++++---- packages/common/src/hardforks.ts | 214 +------- packages/common/src/types.ts | 32 +- packages/common/src/utils.ts | 4 +- packages/common/test/customChains.spec.ts | 10 +- packages/common/test/params.spec.ts | 86 ++- packages/devp2p/package.json | 1 + packages/evm/src/evm.ts | 7 +- packages/evm/src/interpreter.ts | 15 +- packages/evm/src/opcodes/EIP1283.ts | 18 +- packages/evm/src/opcodes/EIP2200.ts | 20 +- packages/evm/src/opcodes/EIP2929.ts | 16 +- packages/evm/src/opcodes/codes.ts | 2 +- packages/evm/src/opcodes/functions.ts | 12 +- packages/evm/src/opcodes/gas.ts | 70 ++- packages/evm/src/opcodes/util.ts | 12 +- packages/evm/src/precompiles/01-ecrecover.ts | 2 +- packages/evm/src/precompiles/02-sha256.ts | 4 +- packages/evm/src/precompiles/03-ripemd160.ts | 4 +- packages/evm/src/precompiles/04-identity.ts | 4 +- packages/evm/src/precompiles/05-modexp.ts | 2 +- packages/evm/src/precompiles/06-ecadd.ts | 2 +- packages/evm/src/precompiles/07-ecmul.ts | 2 +- packages/evm/src/precompiles/08-ecpairing.ts | 3 +- packages/evm/src/precompiles/09-blake2f.ts | 2 +- .../precompiles/0a-kzg-point-evaluation.ts | 6 +- .../evm/src/precompiles/0b-bls12-g1add.ts | 2 +- .../evm/src/precompiles/0c-bls12-g1mul.ts | 2 +- .../evm/src/precompiles/0d-bls12-g1msm.ts | 2 +- .../evm/src/precompiles/0e-bls12-g2add.ts | 2 +- .../evm/src/precompiles/0f-bls12-g2mul.ts | 2 +- .../evm/src/precompiles/10-bls12-g2msm.ts | 2 +- .../evm/src/precompiles/11-bls12-pairing.ts | 5 +- .../src/precompiles/12-bls12-map-fp-to-g1.ts | 2 +- .../src/precompiles/13-bls12-map-fp2-to-g2.ts | 2 +- packages/evm/test/eips/eip-3860.spec.ts | 2 +- packages/tx/src/baseTransaction.ts | 10 +- packages/tx/src/capabilities/eip7702.ts | 2 +- packages/tx/src/eip4844Transaction.ts | 4 +- packages/tx/src/util.ts | 9 +- packages/tx/test/eip3860.spec.ts | 2 +- packages/tx/test/typedTxsAndEIP2930.spec.ts | 14 +- packages/vm/src/buildBlock.ts | 8 +- packages/vm/src/requests.ts | 8 +- packages/vm/src/runBlock.ts | 12 +- packages/vm/src/runTx.ts | 4 +- .../eip-2935-historical-block-hashes.spec.ts | 2 +- .../test/api/EIPs/eip-3074-authcall.spec.ts | 20 +- .../api/EIPs/eip-3651-warm-coinbase.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-3855.spec.ts | 8 +- .../vm/test/api/EIPs/eip-4844-blobs.spec.ts | 2 +- packages/vm/test/api/EIPs/eip-7002.spec.ts | 2 +- packages/vm/test/api/index.spec.ts | 4 +- 67 files changed, 735 insertions(+), 722 deletions(-) diff --git a/package.json b/package.json index 3ce2829e1f..356faf9b30 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,11 @@ "e2e:publish": "./scripts/e2e-publish.sh", "e2e:resolutions": "node ./scripts/e2e-resolutions.js", "examples": "npm run examples --workspaces --if-present", + "lint": "npm run lint --workspaces --if-present", + "lint:fix": "npm run lint:fix --workspaces --if-present", + "test": "npm run test --workspaces --if-present", + "test:node": "npm run test:node --workspaces --if-present", + "test:browser": "npm run test:browser --workspaces --if-present", "preinstall": "npm run checkNpmVersion", "postinstall": "npm run build --workspaces", "prepare": "git config --local core.hooksPath .githooks", diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 0df0fe3a67..725e14879a 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -277,8 +277,6 @@ export class Block { getTransactionsValidationErrors(): string[] { const errors: string[] = [] let blobGasUsed = BIGINT_0 - const blobGasLimit = this.common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = this.common.param('gasConfig', 'blobGasPerBlob') // eslint-disable-next-line prefer-const for (let [i, tx] of this.transactions.entries()) { @@ -297,6 +295,8 @@ export class Block { } } if (this.common.isActivatedEIP(4844)) { + const blobGasLimit = this.common.param('maxblobGasPerBlock') + const blobGasPerBlob = this.common.param('blobGasPerBlob') if (tx instanceof BlobEIP4844Transaction) { blobGasUsed += BigInt(tx.numBlobs()) * blobGasPerBlob if (blobGasUsed > blobGasLimit) { @@ -399,8 +399,8 @@ export class Block { */ validateBlobTransactions(parentHeader: BlockHeader) { if (this.common.isActivatedEIP(4844)) { - const blobGasLimit = this.common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = this.common.param('gasConfig', 'blobGasPerBlob') + const blobGasLimit = this.common.param('maxblobGasPerBlock') + const blobGasPerBlob = this.common.param('blobGasPerBlob') let blobGasUsed = BIGINT_0 const expectedExcessBlobGas = parentHeader.calcNextExcessBlobGas() diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index 189f9ff883..c07740a173 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -227,7 +227,7 @@ export class BlockHeader { const hardforkDefaults = { baseFeePerGas: this.common.isActivatedEIP(1559) ? number === this.common.hardforkBlock(Hardfork.London) - ? this.common.param('gasConfig', 'initialBaseFee') + ? this.common.param('initialBaseFee') : BIGINT_7 : undefined, withdrawalsRoot: this.common.isActivatedEIP(4895) ? KECCAK256_RLP : undefined, @@ -392,7 +392,7 @@ export class BlockHeader { londonHfBlock !== BIGINT_0 && this.number === londonHfBlock ) { - const initialBaseFee = this.common.param('gasConfig', 'initialBaseFee') + const initialBaseFee = this.common.param('initialBaseFee') if (this.baseFeePerGas !== initialBaseFee) { const msg = this._errorMsg('Initial EIP1559 block does not have initial base fee') throw new Error(msg) @@ -446,10 +446,7 @@ export class BlockHeader { // Consensus type dependent checks if (this.common.consensusAlgorithm() === ConsensusAlgorithm.Ethash) { // PoW/Ethash - if ( - number > BIGINT_0 && - this.extraData.length > this.common.param('vm', 'maxExtraDataSize') - ) { + if (number > BIGINT_0 && this.extraData.length > this.common.param('maxExtraDataSize')) { // Check length of data on all post-genesis blocks const msg = this._errorMsg('invalid amount of extra data') throw new Error(msg) @@ -539,12 +536,12 @@ export class BlockHeader { londonHardforkBlock !== BIGINT_0 && this.number === londonHardforkBlock ) { - const elasticity = this.common.param('gasConfig', 'elasticityMultiplier') + const elasticity = this.common.param('elasticityMultiplier') parentGasLimit = parentGasLimit * elasticity } const gasLimit = this.gasLimit - const a = parentGasLimit / this.common.param('gasConfig', 'gasLimitBoundDivisor') + const a = parentGasLimit / this.common.param('gasLimitBoundDivisor') const maxGasLimit = parentGasLimit + a const minGasLimit = parentGasLimit - a @@ -562,10 +559,9 @@ export class BlockHeader { throw new Error(msg) } - if (gasLimit < this.common.param('gasConfig', 'minGasLimit')) { + if (gasLimit < this.common.param('minGasLimit')) { const msg = this._errorMsg( `gas limit decreased below minimum gas limit. Gas limit: ${gasLimit}, minimum gas limit: ${this.common.param( - 'gasConfig', 'minGasLimit' )}` ) @@ -584,27 +580,21 @@ export class BlockHeader { throw new Error(msg) } let nextBaseFee: bigint - const elasticity = this.common.param('gasConfig', 'elasticityMultiplier') + const elasticity = this.common.param('elasticityMultiplier') const parentGasTarget = this.gasLimit / elasticity if (parentGasTarget === this.gasUsed) { nextBaseFee = this.baseFeePerGas! } else if (this.gasUsed > parentGasTarget) { const gasUsedDelta = this.gasUsed - parentGasTarget - const baseFeeMaxChangeDenominator = this.common.param( - 'gasConfig', - 'baseFeeMaxChangeDenominator' - ) + const baseFeeMaxChangeDenominator = this.common.param('baseFeeMaxChangeDenominator') const calculatedDelta = (this.baseFeePerGas! * gasUsedDelta) / parentGasTarget / baseFeeMaxChangeDenominator nextBaseFee = (calculatedDelta > BIGINT_1 ? calculatedDelta : BIGINT_1) + this.baseFeePerGas! } else { const gasUsedDelta = parentGasTarget - this.gasUsed - const baseFeeMaxChangeDenominator = this.common.param( - 'gasConfig', - 'baseFeeMaxChangeDenominator' - ) + const baseFeeMaxChangeDenominator = this.common.param('baseFeeMaxChangeDenominator') const calculatedDelta = (this.baseFeePerGas! * gasUsedDelta) / parentGasTarget / baseFeeMaxChangeDenominator @@ -633,9 +623,9 @@ export class BlockHeader { */ private _getBlobGasPrice(excessBlobGas: bigint) { return fakeExponential( - this.common.param('gasPrices', 'minBlobGasPrice'), + this.common.param('minBlobGas'), excessBlobGas, - this.common.param('gasConfig', 'blobGasPriceUpdateFraction') + this.common.param('blobGasPriceUpdateFraction') ) } @@ -646,7 +636,7 @@ export class BlockHeader { * @returns the total blob gas fee for numBlobs blobs */ calcDataFee(numBlobs: number): bigint { - const blobGasPerBlob = this.common.param('gasConfig', 'blobGasPerBlob') + const blobGasPerBlob = this.common.param('blobGasPerBlob') const blobGasUsed = blobGasPerBlob * BigInt(numBlobs) const blobGasPrice = this.getBlobGasPrice() @@ -659,7 +649,7 @@ export class BlockHeader { public calcNextExcessBlobGas(): bigint { // The validation of the fields and 4844 activation is already taken care in BlockHeader constructor const targetGasConsumed = (this.excessBlobGas ?? BIGINT_0) + (this.blobGasUsed ?? BIGINT_0) - const targetBlobGasPerBlock = this.common.param('gasConfig', 'targetBlobGasPerBlock') + const targetBlobGasPerBlock = this.common.param('targetBlobGasPerBlock') if (targetGasConsumed <= targetBlobGasPerBlock) { return BIGINT_0 @@ -774,8 +764,8 @@ export class BlockHeader { } const blockTs = this.timestamp const { timestamp: parentTs, difficulty: parentDif } = parentBlockHeader - const minimumDifficulty = this.common.param('pow', 'minimumDifficulty') - const offset = parentDif / this.common.param('pow', 'difficultyBoundDivisor') + const minimumDifficulty = this.common.param('minimumDifficulty') + const offset = parentDif / this.common.param('difficultyBoundDivisor') let num = this.number // We use a ! here as TS cannot follow this hardfork-dependent logic, but it always gets assigned @@ -795,7 +785,7 @@ export class BlockHeader { if (this.common.gteHardfork(Hardfork.Byzantium)) { // Get delay as parameter from common - num = num - this.common.param('pow', 'difficultyBombDelay') + num = num - this.common.param('difficultyBombDelay') if (num < BIGINT_0) { num = BIGINT_0 } @@ -810,7 +800,7 @@ export class BlockHeader { dif = parentDif + offset * a } else { // pre-homestead - if (parentTs + this.common.param('pow', 'durationLimit') > blockTs) { + if (parentTs + this.common.param('durationLimit') > blockTs) { dif = offset + parentDif } else { dif = parentDif - offset diff --git a/packages/block/test/eip1559block.spec.ts b/packages/block/test/eip1559block.spec.ts index 328ce8cc36..fcd8355440 100644 --- a/packages/block/test/eip1559block.spec.ts +++ b/packages/block/test/eip1559block.spec.ts @@ -112,7 +112,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), gasLimit: genesis.header.gasLimit * BigInt(2), // Special case on EIP-1559 transition block timestamp: BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, }, { @@ -188,10 +188,9 @@ describe('EIP1559 tests', () => { timestamp: BigInt(1), gasLimit: genesis.header.gasLimit * BigInt(2), // Special case on EIP-1559 transition block gasUsed: - genesis.header.gasLimit * - (common.param('gasConfig', 'elasticityMultiplier') ?? BigInt(0)) + + genesis.header.gasLimit * (common.param('elasticityMultiplier') ?? BigInt(0)) + BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -212,7 +211,7 @@ describe('EIP1559 tests', () => { timestamp: BigInt(1), gasLimit: genesis.header.gasLimit * BigInt(2), // Special case on EIP-1559 transition block gasUsed: genesis.header.gasLimit * BigInt(2), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -230,7 +229,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), gasLimit: genesis.header.gasLimit * BigInt(2), // Special case on EIP-1559 transition block timestamp: BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, }, { @@ -247,7 +246,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), timestamp: BigInt(1), gasLimit: parentGasLimit + parentGasLimit / BigInt(1024) - BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -263,7 +262,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), timestamp: BigInt(1), gasLimit: parentGasLimit - parentGasLimit / BigInt(1024) + BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -315,7 +314,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), timestamp: BigInt(1), gasLimit: parentGasLimit + parentGasLimit, - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -365,7 +364,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), timestamp: BigInt(1), gasLimit: parentGasLimit - parentGasLimit / BigInt(1024), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, { calcDifficultyFromHeader: genesis.header, @@ -422,7 +421,7 @@ describe('EIP1559 tests', () => { parentHash: genesis.hash(), gasLimit: genesis.header.gasLimit * BigInt(2), // Special case on EIP-1559 transition block timestamp: BigInt(1), - baseFeePerGas: common.param('gasConfig', 'initialBaseFee'), + baseFeePerGas: common.param('initialBaseFee'), }, transactions: [ { diff --git a/packages/block/test/eip4844block.spec.ts b/packages/block/test/eip4844block.spec.ts index cb169c07c7..d953090041 100644 --- a/packages/block/test/eip4844block.spec.ts +++ b/packages/block/test/eip4844block.spec.ts @@ -107,7 +107,7 @@ describe('blob gas tests', () => { hardfork: Hardfork.Cancun, customCrypto: { kzg }, }) - blobGasPerBlob = common.param('gasConfig', 'blobGasPerBlob') + blobGasPerBlob = common.param('blobGasPerBlob') }) it('should work', () => { const preShardingHeader = BlockHeader.fromHeaderData({}) @@ -164,7 +164,7 @@ describe('transaction validation tests', () => { hardfork: Hardfork.Cancun, customCrypto: { kzg }, }) - blobGasPerBlob = common.param('gasConfig', 'blobGasPerBlob') + blobGasPerBlob = common.param('blobGasPerBlob') }) it('should work', () => { const blobs = getBlobs('hello world') diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index f07b3dc3ab..8e81b04404 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -527,7 +527,7 @@ export class Blockchain implements BlockchainInterface { const londonHfBlock = this.common.hardforkBlock(Hardfork.London) const isInitialEIP1559Block = number === londonHfBlock if (isInitialEIP1559Block) { - expectedBaseFee = header.common.param('gasConfig', 'initialBaseFee') + expectedBaseFee = header.common.param('initialBaseFee') } else { expectedBaseFee = parentHeader.calcNextBaseFee() } diff --git a/packages/client/src/miner/miner.ts b/packages/client/src/miner/miner.ts index 91b9b19b4f..a9bed0341d 100644 --- a/packages/client/src/miner/miner.ts +++ b/packages/client/src/miner/miner.ts @@ -260,8 +260,7 @@ export class Miner { number === londonHardforkBlock ) { // Get baseFeePerGas from `paramByEIP` since 1559 not currently active on common - baseFeePerGas = - this.config.chainCommon.paramByEIP('gasConfig', 'initialBaseFee', 1559) ?? BIGINT_0 + baseFeePerGas = this.config.chainCommon.paramByEIP('initialBaseFee', 1559) ?? BIGINT_0 // Set initial EIP1559 block gas limit to 2x parent gas limit per logic in `block.validateGasLimit` gasLimit = gasLimit * BIGINT_2 } else if (this.config.chainCommon.isActivatedEIP(1559)) { diff --git a/packages/client/src/miner/pendingBlock.ts b/packages/client/src/miner/pendingBlock.ts index 17963074ec..e5978359fd 100644 --- a/packages/client/src/miner/pendingBlock.ts +++ b/packages/client/src/miner/pendingBlock.ts @@ -198,8 +198,8 @@ export class PendingBlock { // Get if and how many blobs are allowed in the tx let allowedBlobs if (vm.common.isActivatedEIP(4844)) { - const blobGasLimit = vm.common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = vm.common.param('gasConfig', 'blobGasPerBlob') + const blobGasLimit = vm.common.param('maxblobGasPerBlock') + const blobGasPerBlob = vm.common.param('blobGasPerBlob') allowedBlobs = Number(blobGasLimit / blobGasPerBlob) } else { allowedBlobs = 0 @@ -267,8 +267,8 @@ export class PendingBlock { let allowedBlobs if (vm.common.isActivatedEIP(4844)) { const bundle = this.blobsBundles.get(payloadId) ?? { blobs: [], commitments: [], proofs: [] } - const blobGasLimit = vm.common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = vm.common.param('gasConfig', 'blobGasPerBlob') + const blobGasLimit = vm.common.param('maxblobGasPerBlock') + const blobGasPerBlob = vm.common.param('blobGasPerBlob') allowedBlobs = Number(blobGasLimit / blobGasPerBlob) - bundle.blobs.length } else { allowedBlobs = 0 diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index c624f41126..67d2779a8d 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -1164,8 +1164,8 @@ export class Eth { // Blob Transactions sent over RPC are expected to be in Network Wrapper format tx = BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txBuf, { common }) - const blobGasLimit = common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = common.param('gasConfig', 'blobGasPerBlob') + const blobGasLimit = common.param('maxblobGasPerBlock') + const blobGasPerBlob = common.param('blobGasPerBlob') if (BigInt((tx.blobs ?? []).length) * blobGasPerBlob > blobGasLimit) { throw Error( @@ -1320,7 +1320,10 @@ export class Eth { * @returns a hex code of an integer representing the suggested gas price in wei. */ async gasPrice() { - const minGasPrice: bigint = this._chain.config.chainCommon.param('gasConfig', 'minPrice') + // TODO: going more strict on parameter accesses in Common (PR #3532) revealed that this line had + // absolutely no effect by accessing a non-present gas parameter. Someone familiar with the RPC method + // implementation should look over it and recall what was meant to be accomplished here. + const minGasPrice = BIGINT_0 //: bigint = this._chain.config.chainCommon.param('minPrice') let gasPrice = BIGINT_0 const latest = await this._chain.getCanonicalHeadHeader() if (this._vm !== undefined && this._vm.common.isActivatedEIP(1559)) { @@ -1399,7 +1402,7 @@ export class Eth { let blobGasUsedRatio = 0 if (b.header.excessBlobGas !== undefined) { baseFeePerBlobGas = b.header.getBlobGasPrice() - const max = b.common.param('gasConfig', 'maxblobGasPerBlock') + const max = b.common.param('maxblobGasPerBlock') blobGasUsedRatio = Number(blobGasUsed) / Number(max) } diff --git a/packages/client/test/miner/miner.spec.ts b/packages/client/test/miner/miner.spec.ts index 5611ee520f..9373ae032c 100644 --- a/packages/client/test/miner/miner.spec.ts +++ b/packages/client/test/miner/miner.spec.ts @@ -412,7 +412,12 @@ describe('assembleBlocks() -> with saveReceipts', async () => { }) describe('assembleBlocks() -> should not include tx under the baseFee', async () => { - const customChainParams = { hardforks: [{ name: 'london', block: 0 }] } + const customChainParams = { + hardforks: [ + { name: 'chainstart', block: 0 }, + { name: 'london', block: 0 }, + ], + } const common = createCustomCommon(customChainParams, { baseChain: CommonChain.Goerli, hardfork: Hardfork.London, @@ -647,7 +652,7 @@ describe.skip('should handle mining over the london hardfork block', async () => blockHeader3.gasLimit, 'gas limit should be double previous block' ) - const initialBaseFee = config.execCommon.paramByEIP('gasConfig', 'initialBaseFee', 1559)! + const initialBaseFee = config.execCommon.paramByEIP('initialBaseFee', 1559)! assert.equal(blockHeader3.baseFeePerGas!, initialBaseFee, 'baseFee should be initial value') // block 4 diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index 0dd66f9611..211140087b 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -252,7 +252,7 @@ describe(method, () => { hardfork: Hardfork.London, }) - const initialBaseFee = common.param('gasConfig', 'initialBaseFee') + const initialBaseFee = common.param('initialBaseFee') const { server } = await setupChain(gethGenesisStartLondon(pow), 'powLondon') const rpc = getRpcClient(server) diff --git a/packages/common/examples/common.ts b/packages/common/examples/common.ts index b7dcacab5c..4e2ac82506 100644 --- a/packages/common/examples/common.ts +++ b/packages/common/examples/common.ts @@ -8,11 +8,11 @@ const commonWithStrings = new Common({ chain: 'mainnet', hardfork: 'london' }) // Instantiate with the chain (and the default hardfork) let c = new Common({ chain: Chain.Mainnet }) -console.log(`The gas price for ecAdd is ${c.param('gasPrices', 'ecAddGas')}`) // 500 +console.log(`The gas price for ecAdd is ${c.param('ecAddGas')}`) // 500 // Chain and hardfork provided c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) -console.log(`The miner reward under PoW on Byzantium us ${c.param('pow', 'minerReward')}`) // 3000000000000000000 +console.log(`The miner reward under PoW on Byzantium us ${c.param('minerReward')}`) // 3000000000000000000 // Get bootstrap nodes for chain/network console.log('Below are the known bootstrap nodes') diff --git a/packages/common/src/chains.ts b/packages/common/src/chains.ts index 0443442b81..c33819e60d 100644 --- a/packages/common/src/chains.ts +++ b/packages/common/src/chains.ts @@ -4,7 +4,7 @@ type ChainsDict = { [key: string]: ChainConfig } -export const chains: ChainsDict = { +export const chainsDict: ChainsDict = { mainnet: { name: 'mainnet', chainId: 1, diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 014ca2ec9e..2e4aadba31 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -10,9 +10,9 @@ import { import { EventEmitter } from 'events' import { crc32 } from './crc.js' -import { EIPs } from './eips.js' +import { eipsDict } from './eips.js' import { Hardfork } from './enums.js' -import { hardforks as HARDFORK_SPECS } from './hardforks.js' +import { hardforksDict } from './hardforks.js' import { _getChainParams } from './index.js' @@ -25,7 +25,6 @@ import type { CommonOpts, CustomCrypto, EIPConfig, - EIPOrHFConfig, EthashConfig, GenesisBlockConfig, HardforkByOpts, @@ -34,10 +33,9 @@ import type { } from './types.js' import type { BigIntLike, PrefixedHexString } from '@ethereumjs/util' -type HardforkSpecKeys = string // keyof typeof HARDFORK_SPECS -type HardforkSpecValues = typeof HARDFORK_SPECS[HardforkSpecKeys] - -type ParamsCacheConfig = Omit +type ParamsCacheConfig = { + [key: string]: number | bigint | null +} /** * Common class to access chain and hardfork parameters and to provide @@ -60,7 +58,7 @@ export class Common { protected _paramsCache: ParamsCacheConfig = {} protected _activatedEIPsCache: number[] = [] - protected HARDFORK_CHANGES: [HardforkSpecKeys, HardforkSpecValues][] + protected HARDFORK_CHANGES: [string, HardforkConfig][] public events: EventEmitter @@ -72,8 +70,8 @@ export class Common { this.DEFAULT_HARDFORK = this._chainParams.defaultHardfork ?? Hardfork.Shanghai // Assign hardfork changes in the sequence of the applied hardforks this.HARDFORK_CHANGES = this.hardforks().map((hf) => [ - hf.name as HardforkSpecKeys, - HARDFORK_SPECS[hf.name] ?? + hf.name, + hardforksDict[hf.name] ?? (this._chainParams.customHardforks && this._chainParams.customHardforks[hf.name]), ]) this._hardfork = this.DEFAULT_HARDFORK @@ -298,10 +296,10 @@ export class Common { */ setEIPs(eips: number[] = []) { for (const eip of eips) { - if (!(eip in EIPs)) { + if (!(eip in eipsDict)) { throw new Error(`${eip} not supported`) } - const minHF = this.gteHardfork((EIPs as any)[eip]['minimumHardfork']) + const minHF = this.gteHardfork(eipsDict[eip]['minimumHardfork']) if (!minHF) { throw new Error( `${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}` @@ -313,8 +311,8 @@ export class Common { this._buildActivatedEIPsCache() for (const eip of eips) { - if ((EIPs as any)[eip].requiredEIPs !== undefined) { - for (const elem of (EIPs as any)[eip].requiredEIPs) { + if (eipsDict[eip].requiredEIPs !== undefined) { + for (const elem of eipsDict[eip].requiredEIPs) { if (!(eips.includes(elem) || this.isActivatedEIP(elem))) { throw new Error(`${eip} requires EIP ${elem}, but is not included in the EIP list`) } @@ -327,25 +325,9 @@ export class Common { * Internal helper for _buildParamsCache() */ protected _mergeWithParamsCache(params: HardforkConfig | EIPConfig) { - this._paramsCache['gasConfig'] = { - ...this._paramsCache['gasConfig'], - ...params['gasConfig'], - } - this._paramsCache['gasPrices'] = { - ...this._paramsCache['gasPrices'], - ...params['gasPrices'], - } - this._paramsCache['pow'] = { - ...this._paramsCache['pow'], - ...params['pow'], - } - this._paramsCache['sharding'] = { - ...this._paramsCache['sharding'], - ...params['sharding'], - } - this._paramsCache['vm'] = { - ...this._paramsCache['vm'], - ...params['vm'], + this._paramsCache = { + ...this._paramsCache, + ...params['params'], } } @@ -361,34 +343,28 @@ export class Common { if ('eips' in hfChanges[1]) { const hfEIPs = hfChanges[1]['eips'] for (const eip of hfEIPs!) { - if (!(eip in EIPs)) { + if (!(eip in eipsDict)) { throw new Error(`${eip} not supported`) } - this._mergeWithParamsCache(EIPs[eip]) + this._mergeWithParamsCache(eipsDict[eip]) } // Parameter-inlining HF config (e.g. for istanbul) } else { this._mergeWithParamsCache(hfChanges[1]) } - if ( - hfChanges[1].vm || - hfChanges[1].gasConfig || - hfChanges[1].gasPrices || - hfChanges[1].pow || - hfChanges[1].sharding - ) { + if (hfChanges[1].params !== undefined) { this._mergeWithParamsCache(hfChanges[1]) } if (hfChanges[0] === hardfork) break } // Iterate through all additionally activated EIPs for (const eip of this._eips) { - if (!(eip in EIPs)) { + if (!(eip in eipsDict)) { throw new Error(`${eip} not supported`) } - this._mergeWithParamsCache(EIPs[eip]) + this._mergeWithParamsCache(eipsDict[eip]) } } @@ -410,95 +386,88 @@ export class Common { * Otherwise the parameter is taken from the latest applied HF with * a change on the respective parameter. * - * @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow') - * @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic) - * @returns The value requested or `BigInt(0)` if not found + * @param name Parameter name (e.g. 'minGasLimit') + * @returns The value requested (throws if not found) */ - param(topic: string, name: string): bigint { + param(name: string): bigint { // TODO: consider the case that different active EIPs // can change the same parameter - let value = null - if ( - (this._paramsCache as any)[topic] !== undefined && - (this._paramsCache as any)[topic][name] !== undefined - ) { - value = (this._paramsCache as any)[topic][name] + if (!(name in this._paramsCache)) { + throw new Error(`Missing parameter value for ${name}`) } + const value = this._paramsCache[name] return BigInt(value ?? 0) } /** * Returns the parameter corresponding to a hardfork - * @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow') - * @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic) + * @param name Parameter name (e.g. 'minGasLimit') * @param hardfork Hardfork name - * @returns The value requested or `BigInt(0)` if not found + * @returns The value requested (throws if not found) */ - paramByHardfork(topic: string, name: string, hardfork: string | Hardfork): bigint { - let value: bigint | null = null + paramByHardfork(name: string, hardfork: string | Hardfork): bigint { + let value for (const hfChanges of this.HARDFORK_CHANGES) { // EIP-referencing HF config (e.g. for berlin) if ('eips' in hfChanges[1]) { const hfEIPs = hfChanges[1]['eips'] for (const eip of hfEIPs!) { - const valueEIP = this.paramByEIP(topic, name, eip) - value = typeof valueEIP === 'bigint' ? valueEIP : value + const eipParams = eipsDict[eip] + const eipValue = eipParams.params?.[name] + if (eipValue !== undefined) { + value = eipValue + } } // Parameter-inlining HF config (e.g. for istanbul) } else { - if ( - (hfChanges[1] as any)[topic] !== undefined && - (hfChanges[1] as any)[topic][name] !== undefined - ) { - value = (hfChanges[1] as any)[topic][name] + const hfValue = hfChanges[1].params?.[name] + if (hfValue !== undefined) { + value = hfValue } } if (hfChanges[0] === hardfork) break } + if (value === undefined) { + throw new Error(`Missing parameter value for ${name}`) + } return BigInt(value ?? 0) } /** * Returns a parameter corresponding to an EIP - * @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow') * @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic) * @param eip Number of the EIP - * @returns The value requested or `undefined` if not found + * @returns The value requested (throws if not found) */ - paramByEIP(topic: string, name: string, eip: number): bigint | undefined { - if (!(eip in EIPs)) { + paramByEIP(name: string, eip: number): bigint | undefined { + if (!(eip in eipsDict)) { throw new Error(`${eip} not supported`) } - const eipParams = (EIPs as any)[eip] - if (!(topic in eipParams)) { - return undefined + const eipParams = eipsDict[eip] + if (eipParams.params?.[name] === undefined) { + throw new Error(`Missing parameter value for ${name}`) } - if (eipParams[topic][name] === undefined) { - return undefined - } - const value = eipParams[topic][name] - return BigInt(value) + const value = eipParams.params![name] + return BigInt(value ?? 0) } /** * Returns a parameter for the hardfork active on block number or * optional provided total difficulty (Merge HF) - * @param topic Parameter topic * @param name Parameter name * @param blockNumber Block number * @param td Total difficulty * * @returns The value requested or `BigInt(0)` if not found */ paramByBlock( - topic: string, name: string, blockNumber: BigIntLike, td?: BigIntLike, timestamp?: BigIntLike ): bigint { const hardfork = this.getHardforkBy({ blockNumber, td, timestamp }) - return this.paramByHardfork(topic, name, hardfork) + return this.paramByHardfork(name, hardfork) } /** diff --git a/packages/common/src/eips.ts b/packages/common/src/eips.ts index e2d7900be2..31fed75fea 100644 --- a/packages/common/src/eips.ts +++ b/packages/common/src/eips.ts @@ -1,12 +1,281 @@ import { Hardfork } from './enums.js' -import type { EIPConfig } from './types.js' +import type { EIPsDict } from './types.js' -type EIPsDict = { - [key: string]: EIPConfig -} - -export const EIPs: EIPsDict = { +export const eipsDict: EIPsDict = { + /** + * Frontier/Chainstart + * (there is no Meta-EIP currently for Frontier, so 1 was chosen) + */ + 1: { + minimumHardfork: Hardfork.Chainstart, + requiredEIPs: [], + params: { + // gasConfig + minGasLimit: 5000, // Minimum the gas limit may ever be + gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations + maxRefundQuotient: 2, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) + targetBlobGasPerBlock: 0, // Base value needed here since called pre-4844 in BlockHeader.calcNextExcessBlobGas() + blobGasPerBlob: 0, + maxblobGasPerBlock: 0, + // gasPrices + basefeeGas: 2, // Gas base cost, used e.g. for ChainID opcode (Istanbul) + expGas: 10, // Base fee of the EXP opcode + expByteGas: 10, // Times ceil(log256(exponent)) for the EXP instruction + keccak256Gas: 30, // Base fee of the SHA3 opcode + keccak256WordGas: 6, // Once per word of the SHA3 operation's data + sloadGas: 50, // Base fee of the SLOAD opcode + sstoreSetGas: 20000, // Once per SSTORE operation if the zeroness changes from zero + sstoreResetGas: 5000, // Once per SSTORE operation if the zeroness does not change from zero + sstoreRefundGas: 15000, // Once per SSTORE operation if the zeroness changes to zero + jumpdestGas: 1, // Base fee of the JUMPDEST opcode + logGas: 375, // Base fee of the LOG opcode + logDataGas: 8, // Per byte in a LOG* operation's data + logTopicGas: 375, // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas + createGas: 32000, // Base fee of the CREATE opcode + callGas: 40, // Base fee of the CALL opcode + callStipendGas: 2300, // Free gas given at beginning of call + callValueTransferGas: 9000, // Paid for CALL when the value transfor is non-zero + callNewAccountGas: 25000, // Paid for CALL when the destination address didn't exist prior + selfdestructRefundGas: 24000, // Refunded following a selfdestruct operation + memoryGas: 3, // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL + quadCoeffDivGas: 512, // Divisor for the quadratic particle of the memory cost equation + createDataGas: 200, // + txGas: 21000, // Per transaction. NOTE: Not payable on data of calls between transactions + txCreationGas: 32000, // The cost of creating a contract via tx + txDataZeroGas: 4, // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions + txDataNonZeroGas: 68, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions + copyGas: 3, // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added + ecRecoverGas: 3000, + sha256Gas: 60, + sha256WordGas: 12, + ripemd160Gas: 600, + ripemd160WordGas: 120, + identityGas: 15, + identityWordGas: 3, + stopGas: 0, // Base fee of the STOP opcode + addGas: 3, // Base fee of the ADD opcode + mulGas: 5, // Base fee of the MUL opcode + subGas: 3, // Base fee of the SUB opcode + divGas: 5, // Base fee of the DIV opcode + sdivGas: 5, // Base fee of the SDIV opcode + modGas: 5, // Base fee of the MOD opcode + smodGas: 5, // Base fee of the SMOD opcode + addmodGas: 8, // Base fee of the ADDMOD opcode + mulmodGas: 8, // Base fee of the MULMOD opcode + signextendGas: 5, // Base fee of the SIGNEXTEND opcode + ltGas: 3, // Base fee of the LT opcode + gtGas: 3, // Base fee of the GT opcode + sltGas: 3, // Base fee of the SLT opcode + sgtGas: 3, // Base fee of the SGT opcode + eqGas: 3, // Base fee of the EQ opcode + iszeroGas: 3, // Base fee of the ISZERO opcode + andGas: 3, // Base fee of the AND opcode + orGas: 3, // Base fee of the OR opcode + xorGas: 3, // Base fee of the XOR opcode + notGas: 3, // Base fee of the NOT opcode + byteGas: 3, // Base fee of the BYTE opcode + addressGas: 2, // Base fee of the ADDRESS opcode + balanceGas: 20, // Base fee of the BALANCE opcode + originGas: 2, // Base fee of the ORIGIN opcode + callerGas: 2, // Base fee of the CALLER opcode + callvalueGas: 2, // Base fee of the CALLVALUE opcode + calldataloadGas: 3, // Base fee of the CALLDATALOAD opcode + calldatasizeGas: 2, // Base fee of the CALLDATASIZE opcode + calldatacopyGas: 3, // Base fee of the CALLDATACOPY opcode + codesizeGas: 2, // Base fee of the CODESIZE opcode + codecopyGas: 3, // Base fee of the CODECOPY opcode + gaspriceGas: 2, // Base fee of the GASPRICE opcode + extcodesizeGas: 20, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 20, // Base fee of the EXTCODECOPY opcode + blockhashGas: 20, // Base fee of the BLOCKHASH opcode + coinbaseGas: 2, // Base fee of the COINBASE opcode + timestampGas: 2, // Base fee of the TIMESTAMP opcode + numberGas: 2, // Base fee of the NUMBER opcode + difficultyGas: 2, // Base fee of the DIFFICULTY opcode + gaslimitGas: 2, // Base fee of the GASLIMIT opcode + popGas: 2, // Base fee of the POP opcode + mloadGas: 3, // Base fee of the MLOAD opcode + mstoreGas: 3, // Base fee of the MSTORE opcode + mstore8Gas: 3, // Base fee of the MSTORE8 opcode + sstoreGas: 0, // Base fee of the SSTORE opcode + jumpGas: 8, // Base fee of the JUMP opcode + jumpiGas: 10, // Base fee of the JUMPI opcode + pcGas: 2, // Base fee of the PC opcode + msizeGas: 2, // Base fee of the MSIZE opcode + gasGas: 2, // Base fee of the GAS opcode + pushGas: 3, // Base fee of the PUSH opcode + dupGas: 3, // Base fee of the DUP opcode + swapGas: 3, // Base fee of the SWAP opcode + callcodeGas: 40, // Base fee of the CALLCODE opcode + returnGas: 0, // Base fee of the RETURN opcode + invalidGas: 0, // Base fee of the INVALID opcode + selfdestructGas: 0, // Base fee of the SELFDESTRUCT opcode + prevrandaoGas: 0, // TODO: these below 0-gas additons might also point to non-clean implementations in the code base + authGas: 0, // ...allowing access to non-existing gas parameters. Might be worth to fix at some point. + authcallGas: 0, + accessListStorageKeyGas: 0, + accessListAddressGas: 0, + // vm + stackLimit: 1024, // Maximum size of VM stack allowed + callCreateDepth: 1024, // Maximum depth of call/create stack + maxExtraDataSize: 32, // Maximum size extra data may be after Genesis + // pow + minimumDifficulty: 131072, // The minimum that the difficulty may ever be + difficultyBoundDivisor: 2048, // The bound divisor of the difficulty, used in the update calculations + durationLimit: 13, // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not + epochDuration: 30000, // Duration between proof-of-work epochs + timebombPeriod: 100000, // Exponential difficulty timebomb period + minerReward: BigInt('5000000000000000000'), // the amount a miner get rewarded for mining a block + difficultyBombDelay: 0, // the amount of blocks to delay the difficulty bomb with + }, + }, + /** + * Homestead HF Meta EIP + */ + 606: { + minimumHardfork: Hardfork.Chainstart, + requiredEIPs: [], + params: { + // gasPrices + delegatecallGas: 40, // Base fee of the DELEGATECALL opcode + }, + }, + /** + * TangerineWhistle HF Meta EIP + */ + 608: { + minimumHardfork: Hardfork.Homestead, + requiredEIPs: [], + params: { + // gasPrices + sloadGas: 200, // Once per SLOAD operation + callGas: 700, // Once per CALL operation & message call transaction + extcodesizeGas: 700, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 700, // Base fee of the EXTCODECOPY opcode + balanceGas: 400, // Base fee of the BALANCE opcode + delegatecallGas: 700, // Base fee of the DELEGATECALL opcode + callcodeGas: 700, // Base fee of the CALLCODE opcode + selfdestructGas: 5000, // Base fee of the SELFDESTRUCT opcode + }, + }, + /** + * Spurious Dragon HF Meta EIP + */ + 607: { + minimumHardfork: Hardfork.TangerineWhistle, + requiredEIPs: [], + params: { + // gasPrices + expByteGas: 50, // Times ceil(log256(exponent)) for the EXP instruction + // vm + maxCodeSize: 24576, // Maximum length of contract code + }, + }, + /** + * Byzantium HF Meta EIP + */ + 609: { + minimumHardfork: Hardfork.SpuriousDragon, + requiredEIPs: [], + params: { + // gasPrices + modexpGquaddivisorGas: 20, // Gquaddivisor from modexp precompile for gas calculation + ecAddGas: 500, // Gas costs for curve addition precompile + ecMulGas: 40000, // Gas costs for curve multiplication precompile + ecPairingGas: 100000, // Base gas costs for curve pairing precompile + ecPairingWordGas: 80000, // Gas costs regarding curve pairing precompile input length + revertGas: 0, // Base fee of the REVERT opcode + staticcallGas: 700, // Base fee of the STATICCALL opcode + returndatasizeGas: 2, // Base fee of the RETURNDATASIZE opcode + returndatacopyGas: 3, // Base fee of the RETURNDATACOPY opcode + // pow + minerReward: BigInt('3000000000000000000'), // the amount a miner get rewarded for mining a block + difficultyBombDelay: 3000000, // the amount of blocks to delay the difficulty bomb with + }, + }, + /** + * Constantinope HF Meta EIP + */ + 1013: { + minimumHardfork: Hardfork.Constantinople, + requiredEIPs: [], + params: { + // gasPrices + netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change + netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero + netSstoreCleanGas: 5000, // Once per SSTORE operation from clean non-zero + netSstoreDirtyGas: 200, // Once per SSTORE operation from dirty + netSstoreClearRefundGas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot + netSstoreResetRefundGas: 4800, // Once per SSTORE operation for resetting to the original non-zero value + netSstoreResetClearRefundGas: 19800, // Once per SSTORE operation for resetting to the original zero value + shlGas: 3, // Base fee of the SHL opcode + shrGas: 3, // Base fee of the SHR opcode + sarGas: 3, // Base fee of the SAR opcode + extcodehashGas: 400, // Base fee of the EXTCODEHASH opcode + create2Gas: 32000, // Base fee of the CREATE2 opcode + // pow + minerReward: BigInt('2000000000000000000'), // The amount a miner gets rewarded for mining a block + difficultyBombDelay: 5000000, // the amount of blocks to delay the difficulty bomb with + }, + }, + /** + * Petersburg HF Meta EIP + */ + 1716: { + minimumHardfork: Hardfork.Constantinople, + requiredEIPs: [], + params: { + // gasPrices + netSstoreNoopGas: null, // Removed along EIP-1283 + netSstoreInitGas: null, // Removed along EIP-1283 + netSstoreCleanGas: null, // Removed along EIP-1283 + netSstoreDirtyGas: null, // Removed along EIP-1283 + netSstoreClearRefundGas: null, // Removed along EIP-1283 + netSstoreResetRefundGas: null, // Removed along EIP-1283 + netSstoreResetClearRefundGas: null, // Removed along EIP-1283 + }, + }, + /** + * Istanbul HF Meta EIP + */ + 1679: { + minimumHardfork: Hardfork.Constantinople, + requiredEIPs: [], + params: { + // gasPrices + blake2RoundGas: 1, // Gas cost per round for the Blake2 F precompile + ecAddGas: 150, // Gas costs for curve addition precompile + ecMulGas: 6000, // Gas costs for curve multiplication precompile + ecPairingGas: 45000, // Base gas costs for curve pairing precompile + ecPairingWordGas: 34000, // Gas costs regarding curve pairing precompile input length + txDataNonZeroGas: 16, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions + sstoreSentryEIP2200Gas: 2300, // Minimum gas required to be present for an SSTORE call, not consumed + sstoreNoopEIP2200Gas: 800, // Once per SSTORE operation if the value doesn't change + sstoreDirtyEIP2200Gas: 800, // Once per SSTORE operation if a dirty value is changed + sstoreInitEIP2200Gas: 20000, // Once per SSTORE operation from clean zero to non-zero + sstoreInitRefundEIP2200Gas: 19200, // Once per SSTORE operation for resetting to the original zero value + sstoreCleanEIP2200Gas: 5000, // Once per SSTORE operation from clean non-zero to something else + sstoreCleanRefundEIP2200Gas: 4200, // Once per SSTORE operation for resetting to the original non-zero value + sstoreClearRefundEIP2200Gas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot + balanceGas: 700, // Base fee of the BALANCE opcode + extcodehashGas: 700, // Base fee of the EXTCODEHASH opcode + chainidGas: 2, // Base fee of the CHAINID opcode + selfbalanceGas: 5, // Base fee of the SELFBALANCE opcode + sloadGas: 800, // Base fee of the SLOAD opcode + }, + }, + /** + * MuirGlacier HF Meta EIP + */ + 2384: { + minimumHardfork: Hardfork.Istanbul, + requiredEIPs: [], + params: { + // pow + difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with + }, + }, /** * Description : SWAPN, DUPN and EXCHANGE instructions * URL : https://github.com/ethereum/EIPs/blob/bd421962b4e241aa2b00a85d9cf4e57770bdb954/EIPS/eip-663.md @@ -15,10 +284,11 @@ export const EIPs: EIPsDict = { 663: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [3540, 5450], - gasPrices: { - dupn: 3, // Base fee of the DUPN opcode - swapn: 3, // Base fee of the SWAPN opcode - exchange: 3, // Base fee of the EXCHANGE opcode + params: { + // gasPrices + dupnGas: 3, // Base fee of the DUPN opcode + swapnGas: 3, // Base fee of the SWAPN opcode + exchangeGas: 3, // Base fee of the EXCHANGE opcode }, }, /** @@ -29,9 +299,10 @@ export const EIPs: EIPsDict = { 1153: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], - gasPrices: { - tstore: 100, // Base fee of the TSTORE opcode - tload: 100, // Base fee of the TLOAD opcode + params: { + // gasPrices + tstoreGas: 100, // Base fee of the TSTORE opcode + tloadGas: 100, // Base fee of the TLOAD opcode }, }, /** @@ -42,7 +313,8 @@ export const EIPs: EIPsDict = { 1559: { minimumHardfork: Hardfork.Berlin, requiredEIPs: [2930], - gasConfig: { + params: { + // gasConfig baseFeeMaxChangeDenominator: 8, // Maximum base fee change denominator elasticityMultiplier: 2, // Maximum block gas target elasticity initialBaseFee: 1000000000, // Initial base fee on first EIP1559 block @@ -56,8 +328,9 @@ export const EIPs: EIPsDict = { 2565: { minimumHardfork: Hardfork.Byzantium, requiredEIPs: [], - gasPrices: { - modexpGquaddivisor: 3, // Gquaddivisor from modexp precompile for gas calculation + params: { + // gasPrices + modexpGquaddivisorGas: 3, // Gquaddivisor from modexp precompile for gas calculation }, }, /** @@ -68,8 +341,8 @@ export const EIPs: EIPsDict = { 2537: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], - gasConfig: {}, - gasPrices: { + params: { + // gasPrices Bls12381G1AddGas: 500, // Gas cost of a single BLS12-381 G1 addition precompile-call Bls12381G1MulGas: 12000, // Gas cost of a single BLS12-381 G1 multiplication precompile-call Bls12381G2AddGas: 800, // Gas cost of a single BLS12-381 G2 addition precompile-call @@ -79,8 +352,6 @@ export const EIPs: EIPsDict = { Bls12381MapG1Gas: 5500, // Gas cost of BLS12-381 map field element to G1 Bls12381MapG2Gas: 75000, // Gas cost of BLS12-381 map field element to G2 }, - vm: {}, - pow: {}, }, /** * Description : Typed Transaction Envelope @@ -99,25 +370,26 @@ export const EIPs: EIPsDict = { 2929: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], - gasPrices: { - coldsload: 2100, // Gas cost of the first read of storage from a given location (per transaction) - coldaccountaccess: 2600, // Gas cost of the first read of a given address (per transaction) - warmstorageread: 100, // Gas cost of reading storage locations which have already loaded 'cold' - sstoreCleanGasEIP2200: 2900, // Once per SSTORE operation from clean non-zero to something else - sstoreNoopGasEIP2200: 100, // Once per SSTORE operation if the value doesn't change - sstoreDirtyGasEIP2200: 100, // Once per SSTORE operation if a dirty value is changed - sstoreInitRefundEIP2200: 19900, // Once per SSTORE operation for resetting to the original zero value - sstoreCleanRefundEIP2200: 4900, // Once per SSTORE operation for resetting to the original non-zero value - call: 0, // Base fee of the CALL opcode - callcode: 0, // Base fee of the CALLCODE opcode - delegatecall: 0, // Base fee of the DELEGATECALL opcode - staticcall: 0, // Base fee of the STATICCALL opcode - balance: 0, // Base fee of the BALANCE opcode - extcodesize: 0, // Base fee of the EXTCODESIZE opcode - extcodecopy: 0, // Base fee of the EXTCODECOPY opcode - extcodehash: 0, // Base fee of the EXTCODEHASH opcode - sload: 0, // Base fee of the SLOAD opcode - sstore: 0, // Base fee of the SSTORE opcode + params: { + // gasPrices + coldsloadGas: 2100, // Gas cost of the first read of storage from a given location (per transaction) + coldaccountaccessGas: 2600, // Gas cost of the first read of a given address (per transaction) + warmstoragereadGas: 100, // Gas cost of reading storage locations which have already loaded 'cold' + sstoreCleanEIP2200Gas: 2900, // Once per SSTORE operation from clean non-zero to something else + sstoreNoopEIP2200Gas: 100, // Once per SSTORE operation if the value doesn't change + sstoreDirtyEIP2200Gas: 100, // Once per SSTORE operation if a dirty value is changed + sstoreInitRefundEIP2200Gas: 19900, // Once per SSTORE operation for resetting to the original zero value + sstoreCleanRefundEIP2200Gas: 4900, // Once per SSTORE operation for resetting to the original non-zero value + callGas: 0, // Base fee of the CALL opcode + callcodeGas: 0, // Base fee of the CALLCODE opcode + delegatecallGas: 0, // Base fee of the DELEGATECALL opcode + staticcallGas: 0, // Base fee of the STATICCALL opcode + balanceGas: 0, // Base fee of the BALANCE opcode + extcodesizeGas: 0, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 0, // Base fee of the EXTCODECOPY opcode + extcodehashGas: 0, // Base fee of the EXTCODEHASH opcode + sloadGas: 0, // Base fee of the SLOAD opcode + sstoreGas: 0, // Base fee of the SSTORE opcode }, }, /** @@ -128,9 +400,10 @@ export const EIPs: EIPsDict = { 2930: { minimumHardfork: Hardfork.Istanbul, requiredEIPs: [2718, 2929], - gasPrices: { - accessListStorageKeyCost: 1900, // Gas cost per storage key in an Access List transaction - accessListAddressCost: 2400, // Gas cost per storage key in an Access List transaction + params: { + // gasPrices + accessListStorageKeyGas: 1900, // Gas cost per storage key in an Access List transaction + accessListAddressGas: 2400, // Gas cost per storage key in an Access List transaction }, }, /** @@ -141,7 +414,8 @@ export const EIPs: EIPsDict = { 2935: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], - vm: { + params: { + // vm historyStorageAddress: BigInt('0x0aae40965e6800cd9b1f4b05ff21581047e3f91e'), // The address where the historical blockhashes are stored historyServeWindow: BigInt(8192), // The amount of blocks to be served by the historical blockhash contract }, @@ -154,10 +428,11 @@ export const EIPs: EIPsDict = { 3074: { minimumHardfork: Hardfork.London, requiredEIPs: [], - gasPrices: { - auth: 3100, // Gas cost of the AUTH opcode - authcall: 0, // Gas cost of the AUTHCALL opcode - authcallValueTransfer: 6700, // Paid for CALL when the value transfer is non-zero + params: { + // gasPrices + authGas: 3100, // Gas cost of the AUTH opcode + authcallGas: 0, // Gas cost of the AUTHCALL opcode + authcallValueTransferGas: 6700, // Paid for CALL when the value transfer is non-zero }, }, /** @@ -168,8 +443,9 @@ export const EIPs: EIPsDict = { 3198: { minimumHardfork: Hardfork.London, requiredEIPs: [], - gasPrices: { - basefee: 2, // Gas cost of the BASEFEE opcode + params: { + // gasPrices + basefeeGas: 2, // Gas cost of the BASEFEE opcode }, }, /** @@ -180,12 +456,12 @@ export const EIPs: EIPsDict = { 3529: { minimumHardfork: Hardfork.Berlin, requiredEIPs: [2929], - gasConfig: { + params: { + // gasConfig maxRefundQuotient: 5, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) - }, - gasPrices: { - selfdestructRefund: 0, // Refunded following a selfdestruct operation - sstoreClearRefundEIP2200: 4800, // Once per SSTORE operation for clearing an originally existing storage slot + // gasPrices + selfdestructRefundGas: 0, // Refunded following a selfdestruct operation + sstoreClearRefundEIP2200Gas: 4800, // Once per SSTORE operation for clearing an originally existing storage slot }, }, /** @@ -214,7 +490,8 @@ export const EIPs: EIPsDict = { 3554: { minimumHardfork: Hardfork.MuirGlacier, requiredEIPs: [], - pow: { + params: { + // pow difficultyBombDelay: 9500000, // the amount of blocks to delay the difficulty bomb with }, }, @@ -262,8 +539,9 @@ export const EIPs: EIPsDict = { 3855: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [], - gasPrices: { - push0: 2, // Base fee of the PUSH0 opcode + params: { + // gasPrices + push0Gas: 2, // Base fee of the PUSH0 opcode }, }, /** @@ -274,10 +552,10 @@ export const EIPs: EIPsDict = { 3860: { minimumHardfork: Hardfork.SpuriousDragon, requiredEIPs: [], - gasPrices: { - initCodeWordCost: 2, // Gas to pay for each word (32 bytes) of initcode when creating a contract - }, - vm: { + params: { + // gasPrices + initCodeWordGas: 2, // Gas to pay for each word (32 bytes) of initcode when creating a contract + // vm maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract }, }, @@ -289,10 +567,11 @@ export const EIPs: EIPsDict = { 4200: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670], - gasPrices: { - rjump: 2, // Base fee of the RJUMP opcode - rjumpi: 4, // Base fee of the RJUMPI opcode - rjumpv: 4, // Base fee of the RJUMPV opcode + params: { + // gasPrices + rjumpGas: 2, // Base fee of the RJUMP opcode + rjumpiGas: 4, // Base fee of the RJUMPI opcode + rjumpvGas: 4, // Base fee of the RJUMPV opcode }, }, /** @@ -303,7 +582,8 @@ export const EIPs: EIPsDict = { 4345: { minimumHardfork: Hardfork.London, requiredEIPs: [], - pow: { + params: { + // pow difficultyBombDelay: 10700000, // the amount of blocks to delay the difficulty bomb with }, }, @@ -315,8 +595,9 @@ export const EIPs: EIPsDict = { 4399: { minimumHardfork: Hardfork.London, requiredEIPs: [], - gasPrices: { - prevrandao: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) + params: { + // gasPrices + prevrandaoGas: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) }, }, /** @@ -327,9 +608,10 @@ export const EIPs: EIPsDict = { 4750: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670, 5450], - gasPrices: { - callf: 5, // Base fee of the CALLF opcode - retf: 3, // Base fee of the RETF opcode + params: { + // gasPrices + callfGas: 5, // Base fee of the CALLF opcode + retfGas: 3, // Base fee of the RETF opcode }, }, /** @@ -340,8 +622,8 @@ export const EIPs: EIPsDict = { 4788: { minimumHardfork: Hardfork.Cancun, requiredEIPs: [], - gasPrices: {}, - vm: { + params: { + // vm historicalRootsLength: 8191, // The modulo parameter of the beaconroot ring buffer in the beaconroot statefull precompile }, }, @@ -353,19 +635,18 @@ export const EIPs: EIPsDict = { 4844: { minimumHardfork: Hardfork.Paris, requiredEIPs: [1559, 2718, 2930, 4895], - gasConfig: { + params: { + // gasConfig blobGasPerBlob: 131072, // The base fee for blob gas per blob targetBlobGasPerBlock: 393216, // The target blob gas consumed per block maxblobGasPerBlock: 786432, // The max blob gas allowable per block blobGasPriceUpdateFraction: 3338477, // The denominator used in the exponential when calculating a blob gas price - }, - gasPrices: { - simpleGasPerBlob: 12000, // The basic gas fee for each blob - minBlobGasPrice: 1, // The minimum fee per blob gas - kzgPointEvaluationGasPrecompilePrice: 50000, // The fee associated with the point evaluation precompile - blobhash: 3, // Base fee of the BLOBHASH opcode - }, - sharding: { + // gasPrices + simplePerBlobGas: 12000, // The basic gas fee for each blob + minBlobGas: 1, // The minimum fee per blob gas + kzgPointEvaluationPrecompileGas: 50000, // The fee associated with the point evaluation precompile + blobhashGas: 3, // Base fee of the BLOBHASH opcode + // sharding blobCommitmentVersionKzg: 1, // The number indicated a versioned hash is a KZG commitment fieldElementsPerBlob: 4096, // The number of field elements allowed per blob }, @@ -387,7 +668,8 @@ export const EIPs: EIPsDict = { 5133: { minimumHardfork: Hardfork.GrayGlacier, requiredEIPs: [], - pow: { + params: { + // pow difficultyBombDelay: 11400000, // the amount of blocks to delay the difficulty bomb with }, }, @@ -408,8 +690,9 @@ export const EIPs: EIPsDict = { 5656: { minimumHardfork: Hardfork.Shanghai, requiredEIPs: [], - gasPrices: { - mcopy: 3, // Base fee of the MCOPY opcode + params: { + // gasPrices + mcopyGas: 3, // Base fee of the MCOPY opcode }, }, /** @@ -429,8 +712,9 @@ export const EIPs: EIPsDict = { 6206: { minimumHardfork: Hardfork.London, requiredEIPs: [4750, 5450], - gasPrices: { - jumpf: 5, // Base fee of the JUMPF opcode + params: { + // gasPrices + jumpfGas: 5, // Base fee of the JUMPF opcode }, }, /** @@ -450,11 +734,11 @@ export const EIPs: EIPsDict = { 6800: { minimumHardfork: Hardfork.London, requiredEIPs: [], - gasPrices: { - create: 1000, // Base fee of the CREATE opcode - coldsload: 0, // Gas cost of the first read of storage from a given location (per transaction) - }, - vm: { + params: { + // gasPrices + createGas: 1000, // Base fee of the CREATE opcode + coldsloadGas: 0, // Gas cost of the first read of storage from a given location (per transaction) + // vm // kaustinen 6 current uses this address, however this will be updated to correct address // in next iteration historyStorageAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The address where the historical blockhashes are stored @@ -468,7 +752,8 @@ export const EIPs: EIPsDict = { 7002: { minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], - vm: { + params: { + // vm withdrawalRequestType: BigInt(0x01), // The withdrawal request type for EIP-7685 excessWithdrawalsRequestStorageSlot: BigInt(0), // The storage slot of the excess withdrawals withdrawalsRequestCountStorage: BigInt(1), // The storage slot of the withdrawal request count @@ -496,11 +781,12 @@ export const EIPs: EIPsDict = { EIP 214 - (STATICCALL) - Included in Byzantium */ requiredEIPs: [2929], - gasPrices: { - extcall: 0, // Base fee of the EXTCALL opcode - extdelegatecall: 0, // Base fee of the EXTDELEGATECALL opcode - extstaticcall: 0, // Base fee of the EXTSTATICCALL opcode - returndataload: 3, // Base fee of the RETURNDATALOAD opcode + params: { + // gasPrices + extcallGas: 0, // Base fee of the EXTCALL opcode + extdelegatecallGas: 0, // Base fee of the EXTDELEGATECALL opcode + extstaticcallGas: 0, // Base fee of the EXTSTATICCALL opcode + returndataloadGas: 3, // Base fee of the RETURNDATALOAD opcode minRetainedGas: 5000, // Minimum gas retained prior to executing an EXT*CALL opcode (this is the minimum gas available after performing the EXT*CALL) minCalleeGas: 2300, //Minimum gas available to the the address called by an EXT*CALL opcode }, @@ -513,7 +799,8 @@ export const EIPs: EIPsDict = { 7251: { minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], - vm: { + params: { + // vm consolidationRequestType: BigInt(0x02), // The withdrawal request type for EIP-7685 systemAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The system address to perform operations on the consolidation requests predeploy address consolidationRequestPredeployAddress: BigInt('0x00b42dbF2194e931E80326D950320f7d9Dbeac02'), // Address of the consolidations contract @@ -527,11 +814,12 @@ export const EIPs: EIPsDict = { 7480: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670], - gasPrices: { - dataload: 4, // Base fee of the DATALOAD opcode - dataloadn: 3, // Base fee of the DATALOADN opcode - datasize: 2, // Base fee of the DATASIZE opcode - datacopy: 3, // Base fee of the DATACOPY opcode + params: { + // gasPrices + dataloadGas: 4, // Base fee of the DATALOAD opcode + dataloadnGas: 3, // Base fee of the DATALOADN opcode + datasizeGas: 2, // Base fee of the DATASIZE opcode + datacopyGas: 3, // Base fee of the DATACOPY opcode }, }, /** @@ -542,8 +830,9 @@ export const EIPs: EIPsDict = { 7516: { minimumHardfork: Hardfork.Paris, requiredEIPs: [4844], - gasPrices: { - blobbasefee: 2, // Gas cost of the BLOBBASEFEE opcode + params: { + // gasPrices + blobbasefeeGas: 2, // Gas cost of the BLOBBASEFEE opcode }, }, /** @@ -557,9 +846,10 @@ export const EIPs: EIPsDict = { EIP 170 - (Max contract size) - Included in Spurious Dragon */ requiredEIPs: [3540, 3541, 3670], - gasPrices: { - eofcreate: 32000, // Base fee of the EOFCREATE opcode (Same as CREATE/CREATE2) - returncontract: 0, // Base fee of the RETURNCONTRACT opcode + params: { + // gasPrices + eofcreateGas: 32000, // Base fee of the EOFCREATE opcode (Same as CREATE/CREATE2) + returncontractGas: 0, // Base fee of the RETURNCONTRACT opcode }, }, /** @@ -571,7 +861,6 @@ export const EIPs: EIPsDict = { // TODO: Set correct minimum hardfork minimumHardfork: Hardfork.Cancun, requiredEIPs: [3675], - gasPrices: {}, }, /** * Description : EVM Object Format (EOFv1) Meta @@ -581,7 +870,6 @@ export const EIPs: EIPsDict = { 7692: { minimumHardfork: Hardfork.Cancun, requiredEIPs: [663, 3540, 3670, 4200, 4750, 5450, 6206, 7069, 7480, 7620, 7698], - gasPrices: {}, }, /** * Description : EOF - Creation transaction @@ -601,8 +889,9 @@ export const EIPs: EIPsDict = { // TODO: Set correct minimum hardfork minimumHardfork: Hardfork.Cancun, requiredEIPs: [2718, 2929, 2930], - gasPrices: { - perAuthBaseCost: 2500, // Gas cost of each authority item + params: { + // gasPrices + perAuthBaseGas: 2500, // Gas cost of each authority item }, }, /** diff --git a/packages/common/src/hardforks.ts b/packages/common/src/hardforks.ts index b95a4183b2..527ae642a1 100644 --- a/packages/common/src/hardforks.ts +++ b/packages/common/src/hardforks.ts @@ -1,125 +1,13 @@ import type { HardforksDict } from './types.js' -export const hardforks: HardforksDict = { +export const hardforksDict: HardforksDict = { /** * Description: Start of the Ethereum main chain * URL : - * Status : Final */ chainstart: { - gasConfig: { - minGasLimit: 5000, // Minimum the gas limit may ever be - gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations - maxRefundQuotient: 2, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) - }, - gasPrices: { - base: 2, // Gas base cost, used e.g. for ChainID opcode (Istanbul) - exp: 10, // Base fee of the EXP opcode - expByte: 10, // Times ceil(log256(exponent)) for the EXP instruction - keccak256: 30, // Base fee of the SHA3 opcode - keccak256Word: 6, // Once per word of the SHA3 operation's data - sload: 50, // Base fee of the SLOAD opcode - sstoreSet: 20000, // Once per SSTORE operation if the zeroness changes from zero - sstoreReset: 5000, // Once per SSTORE operation if the zeroness does not change from zero - sstoreRefund: 15000, // Once per SSTORE operation if the zeroness changes to zero - jumpdest: 1, // Base fee of the JUMPDEST opcode - log: 375, // Base fee of the LOG opcode - logData: 8, // Per byte in a LOG* operation's data - logTopic: 375, // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas - create: 32000, // Base fee of the CREATE opcode - call: 40, // Base fee of the CALL opcode - callStipend: 2300, // Free gas given at beginning of call - callValueTransfer: 9000, // Paid for CALL when the value transfor is non-zero - callNewAccount: 25000, // Paid for CALL when the destination address didn't exist prior - selfdestructRefund: 24000, // Refunded following a selfdestruct operation - memory: 3, // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL - quadCoeffDiv: 512, // Divisor for the quadratic particle of the memory cost equation - createData: 200, // - tx: 21000, // Per transaction. NOTE: Not payable on data of calls between transactions - txCreation: 32000, // The cost of creating a contract via tx - txDataZero: 4, // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions - txDataNonZero: 68, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions - copy: 3, // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added - ecRecover: 3000, - sha256: 60, - sha256Word: 12, - ripemd160: 600, - ripemd160Word: 120, - identity: 15, - identityWord: 3, - stop: 0, // Base fee of the STOP opcode - add: 3, // Base fee of the ADD opcode - mul: 5, // Base fee of the MUL opcode - sub: 3, // Base fee of the SUB opcode - div: 5, // Base fee of the DIV opcode - sdiv: 5, // Base fee of the SDIV opcode - mod: 5, // Base fee of the MOD opcode - smod: 5, // Base fee of the SMOD opcode - addmod: 8, // Base fee of the ADDMOD opcode - mulmod: 8, // Base fee of the MULMOD opcode - signextend: 5, // Base fee of the SIGNEXTEND opcode - lt: 3, // Base fee of the LT opcode - gt: 3, // Base fee of the GT opcode - slt: 3, // Base fee of the SLT opcode - sgt: 3, // Base fee of the SGT opcode - eq: 3, // Base fee of the EQ opcode - iszero: 3, // Base fee of the ISZERO opcode - and: 3, // Base fee of the AND opcode - or: 3, // Base fee of the OR opcode - xor: 3, // Base fee of the XOR opcode - not: 3, // Base fee of the NOT opcode - byte: 3, // Base fee of the BYTE opcode - address: 2, // Base fee of the ADDRESS opcode - balance: 20, // Base fee of the BALANCE opcode - origin: 2, // Base fee of the ORIGIN opcode - caller: 2, // Base fee of the CALLER opcode - callvalue: 2, // Base fee of the CALLVALUE opcode - calldataload: 3, // Base fee of the CALLDATALOAD opcode - calldatasize: 2, // Base fee of the CALLDATASIZE opcode - calldatacopy: 3, // Base fee of the CALLDATACOPY opcode - codesize: 2, // Base fee of the CODESIZE opcode - codecopy: 3, // Base fee of the CODECOPY opcode - gasprice: 2, // Base fee of the GASPRICE opcode - extcodesize: 20, // Base fee of the EXTCODESIZE opcode - extcodecopy: 20, // Base fee of the EXTCODECOPY opcode - blockhash: 20, // Base fee of the BLOCKHASH opcode - coinbase: 2, // Base fee of the COINBASE opcode - timestamp: 2, // Base fee of the TIMESTAMP opcode - number: 2, // Base fee of the NUMBER opcode - difficulty: 2, // Base fee of the DIFFICULTY opcode - gaslimit: 2, // Base fee of the GASLIMIT opcode - pop: 2, // Base fee of the POP opcode - mload: 3, // Base fee of the MLOAD opcode - mstore: 3, // Base fee of the MSTORE opcode - mstore8: 3, // Base fee of the MSTORE8 opcode - sstore: 0, // Base fee of the SSTORE opcode - jump: 8, // Base fee of the JUMP opcode - jumpi: 10, // Base fee of the JUMPI opcode - pc: 2, // Base fee of the PC opcode - msize: 2, // Base fee of the MSIZE opcode - gas: 2, // Base fee of the GAS opcode - push: 3, // Base fee of the PUSH opcode - dup: 3, // Base fee of the DUP opcode - swap: 3, // Base fee of the SWAP opcode - callcode: 40, // Base fee of the CALLCODE opcode - return: 0, // Base fee of the RETURN opcode - invalid: 0, // Base fee of the INVALID opcode - selfdestruct: 0, // Base fee of the SELFDESTRUCT opcode - }, - vm: { - stackLimit: 1024, // Maximum size of VM stack allowed - callCreateDepth: 1024, // Maximum depth of call/create stack - maxExtraDataSize: 32, // Maximum size extra data may be after Genesis - }, - pow: { - minimumDifficulty: 131072, // The minimum that the difficulty may ever be - difficultyBoundDivisor: 2048, // The bound divisor of the difficulty, used in the update calculations - durationLimit: 13, // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not - epochDuration: 30000, // Duration between proof-of-work epochs - timebombPeriod: 100000, // Exponential difficulty timebomb period - minerReward: BigInt('5000000000000000000'), // the amount a miner get rewarded for mining a block - difficultyBombDelay: 0, // the amount of blocks to delay the difficulty bomb with - }, + eips: [1], }, /** * Description: Homestead hardfork with protocol and network changes @@ -127,32 +15,23 @@ export const hardforks: HardforksDict = { * Status : Final */ homestead: { - gasPrices: { - delegatecall: 40, // Base fee of the DELEGATECALL opcode - }, + eips: [606], }, /** * Description: DAO rescue hardfork * URL : https://eips.ethereum.org/EIPS/eip-779 * Status : Final */ - dao: {}, + dao: { + eips: [], + }, /** * Description: Hardfork with gas cost changes for IO-heavy operations * URL : https://eips.ethereum.org/EIPS/eip-608 * Status : Final */ tangerineWhistle: { - gasPrices: { - sload: 200, // Once per SLOAD operation - call: 700, // Once per CALL operation & message call transaction - extcodesize: 700, // Base fee of the EXTCODESIZE opcode - extcodecopy: 700, // Base fee of the EXTCODECOPY opcode - balance: 400, // Base fee of the BALANCE opcode - delegatecall: 700, // Base fee of the DELEGATECALL opcode - callcode: 700, // Base fee of the CALLCODE opcode - selfdestruct: 5000, // Base fee of the SELFDESTRUCT opcode - }, + eips: [608], }, /** * Description: HF with EIPs for simple replay attack protection, EXP cost increase, state trie clearing, contract code size limit @@ -160,12 +39,7 @@ export const hardforks: HardforksDict = { * Status : Final */ spuriousDragon: { - gasPrices: { - expByte: 50, // Times ceil(log256(exponent)) for the EXP instruction - }, - vm: { - maxCodeSize: 24576, // Maximum length of contract code - }, + eips: [607], }, /** * Description: Hardfork with new precompiles, instructions and other protocol changes @@ -173,21 +47,7 @@ export const hardforks: HardforksDict = { * Status : Final */ byzantium: { - gasPrices: { - modexpGquaddivisor: 20, // Gquaddivisor from modexp precompile for gas calculation - ecAdd: 500, // Gas costs for curve addition precompile - ecMul: 40000, // Gas costs for curve multiplication precompile - ecPairing: 100000, // Base gas costs for curve pairing precompile - ecPairingWord: 80000, // Gas costs regarding curve pairing precompile input length - revert: 0, // Base fee of the REVERT opcode - staticcall: 700, // Base fee of the STATICCALL opcode - returndatasize: 2, // Base fee of the RETURNDATASIZE opcode - returndatacopy: 3, // Base fee of the RETURNDATACOPY opcode - }, - pow: { - minerReward: BigInt('3000000000000000000'), // the amount a miner get rewarded for mining a block - difficultyBombDelay: 3000000, // the amount of blocks to delay the difficulty bomb with - }, + eips: [609], }, /** * Description: Postponed hardfork including EIP-1283 (SSTORE gas metering changes) @@ -195,24 +55,7 @@ export const hardforks: HardforksDict = { * Status : Final */ constantinople: { - gasPrices: { - netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change - netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero - netSstoreCleanGas: 5000, // Once per SSTORE operation from clean non-zero - netSstoreDirtyGas: 200, // Once per SSTORE operation from dirty - netSstoreClearRefund: 15000, // Once per SSTORE operation for clearing an originally existing storage slot - netSstoreResetRefund: 4800, // Once per SSTORE operation for resetting to the original non-zero value - netSstoreResetClearRefund: 19800, // Once per SSTORE operation for resetting to the original zero value - shl: 3, // Base fee of the SHL opcode - shr: 3, // Base fee of the SHR opcode - sar: 3, // Base fee of the SAR opcode - extcodehash: 400, // Base fee of the EXTCODEHASH opcode - create2: 32000, // Base fee of the CREATE2 opcode - }, - pow: { - minerReward: BigInt('2000000000000000000'), // The amount a miner gets rewarded for mining a block - difficultyBombDelay: 5000000, // the amount of blocks to delay the difficulty bomb with - }, + eips: [1013], }, /** * Description: Aka constantinopleFix, removes EIP-1283, activate together with or after constantinople @@ -220,15 +63,7 @@ export const hardforks: HardforksDict = { * Status : Final */ petersburg: { - gasPrices: { - netSstoreNoopGas: null, // Removed along EIP-1283 - netSstoreInitGas: null, // Removed along EIP-1283 - netSstoreCleanGas: null, // Removed along EIP-1283 - netSstoreDirtyGas: null, // Removed along EIP-1283 - netSstoreClearRefund: null, // Removed along EIP-1283 - netSstoreResetRefund: null, // Removed along EIP-1283 - netSstoreResetClearRefund: null, // Removed along EIP-1283 - }, + eips: [1716], }, /** * Description: HF targeted for December 2019 following the Constantinople/Petersburg HF @@ -236,28 +71,7 @@ export const hardforks: HardforksDict = { * Status : Final */ istanbul: { - gasConfig: {}, - gasPrices: { - blake2Round: 1, // Gas cost per round for the Blake2 F precompile - ecAdd: 150, // Gas costs for curve addition precompile - ecMul: 6000, // Gas costs for curve multiplication precompile - ecPairing: 45000, // Base gas costs for curve pairing precompile - ecPairingWord: 34000, // Gas costs regarding curve pairing precompile input length - txDataNonZero: 16, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions - sstoreSentryGasEIP2200: 2300, // Minimum gas required to be present for an SSTORE call, not consumed - sstoreNoopGasEIP2200: 800, // Once per SSTORE operation if the value doesn't change - sstoreDirtyGasEIP2200: 800, // Once per SSTORE operation if a dirty value is changed - sstoreInitGasEIP2200: 20000, // Once per SSTORE operation from clean zero to non-zero - sstoreInitRefundEIP2200: 19200, // Once per SSTORE operation for resetting to the original zero value - sstoreCleanGasEIP2200: 5000, // Once per SSTORE operation from clean non-zero to something else - sstoreCleanRefundEIP2200: 4200, // Once per SSTORE operation for resetting to the original non-zero value - sstoreClearRefundEIP2200: 15000, // Once per SSTORE operation for clearing an originally existing storage slot - balance: 700, // Base fee of the BALANCE opcode - extcodehash: 700, // Base fee of the EXTCODEHASH opcode - chainid: 2, // Base fee of the CHAINID opcode - selfbalance: 5, // Base fee of the SELFBALANCE opcode - sload: 800, // Base fee of the SLOAD opcode - }, + eips: [1679], }, /** * Description: HF to delay the difficulty bomb @@ -265,9 +79,7 @@ export const hardforks: HardforksDict = { * Status : Final */ muirGlacier: { - pow: { - difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with - }, + eips: [2384], }, /** * Description: HF targeted for July 2020 following the Muir Glacier HF diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 3c6082db90..edd6eb1b7f 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -163,33 +163,25 @@ export interface HardforkByOpts { td?: BigIntLike } -export type EIPOrHFConfig = { - gasConfig?: { - [key: string]: number | bigint | null - } - gasPrices?: { - [key: string]: number | bigint | null - } - pow?: { - [key: string]: number | bigint | null - } - sharding?: { - [key: string]: number | bigint | null - } - vm?: { - [key: string]: number | bigint | null - } -} - export type EIPConfig = { minimumHardfork: Hardfork requiredEIPs: number[] -} & EIPOrHFConfig + params?: { + [key: string]: number | bigint | null + } +} export type HardforkConfig = { eips?: number[] consensus?: ConsensusConfig -} & EIPOrHFConfig + params?: { + [key: string]: number | bigint | null + } +} + +export type EIPsDict = { + [key: string]: EIPConfig +} export type HardforksDict = { [key: string]: HardforkConfig diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index 975a256c02..caa1274edf 100644 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -1,6 +1,6 @@ import { intToHex, isHexString, stripHexPrefix } from '@ethereumjs/util' -import { chains as CHAIN_SPECS } from './chains.js' +import { chainsDict } from './chains.js' import { Chain, Hardfork } from './enums.js' import type { ChainConfig, ChainName, ChainsConfig } from './index.js' @@ -243,7 +243,7 @@ export function getInitializedChains(customChains?: ChainConfig[]): ChainsConfig for (const [name, id] of Object.entries(Chain)) { names[id] = name.toLowerCase() } - const chains = { ...CHAIN_SPECS } as ChainsConfig + const chains = { ...chainsDict } as ChainsConfig if (customChains) { for (const chain of customChains) { const { name } = chain diff --git a/packages/common/test/customChains.spec.ts b/packages/common/test/customChains.spec.ts index 71bdd0d9ae..14eb3a4688 100644 --- a/packages/common/test/customChains.spec.ts +++ b/packages/common/test/customChains.spec.ts @@ -1,4 +1,3 @@ -import { BIGINT_0 } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { @@ -230,9 +229,8 @@ describe('[Common]: Custom chains', () => { customHardforks: { // Hardfork which changes the gas of STOP from 0 to 10 stop10Gas: { - name: 'stop10Gas', eips: [2935], - vm: { + params: { stop: BigInt(10), }, }, @@ -250,13 +248,15 @@ describe('[Common]: Custom chains', () => { ], }) c.setHardfork(Hardfork.Chainstart) - assert.equal(c.param('vm', 'stop'), BIGINT_0) + assert.throws(() => { + c.param('stop') + }) c.setHardforkBy({ blockNumber: 1, timestamp: 1000, }) assert.equal(c.hardfork(), 'stop10Gas') - assert.equal(c.param('vm', 'stop'), BigInt(10)) + assert.equal(c.param('stop'), BigInt(10)) }) }) diff --git a/packages/common/test/params.spec.ts b/packages/common/test/params.spec.ts index c6420e2847..4969aaf6c2 100644 --- a/packages/common/test/params.spec.ts +++ b/packages/common/test/params.spec.ts @@ -6,19 +6,19 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { it('Basic usage', () => { const c = new Common({ chain: Chain.Mainnet, eips: [2537] }) let msg = 'Should return correct value when HF directly provided' - assert.equal(c.paramByHardfork('gasPrices', 'ecAdd', 'byzantium'), BigInt(500), msg) + assert.equal(c.paramByHardfork('ecAddGas', 'byzantium'), BigInt(500), msg) msg = 'Should return correct value for HF set in class' c.setHardfork(Hardfork.Byzantium) - assert.equal(c.param('gasPrices', 'ecAdd'), BigInt(500), msg) + assert.equal(c.param('ecAddGas'), BigInt(500), msg) c.setHardfork(Hardfork.Istanbul) - assert.equal(c.param('gasPrices', 'ecAdd'), BigInt(150), msg) + assert.equal(c.param('ecAddGas'), BigInt(150), msg) c.setHardfork(Hardfork.MuirGlacier) - assert.equal(c.param('gasPrices', 'ecAdd'), BigInt(150), msg) + assert.equal(c.param('ecAddGas'), BigInt(150), msg) - msg = 'Should return 0n for non-existing value' - assert.equal(c.param('gasPrices', 'notexistingvalue'), BigInt(0), msg) - assert.equal(c.paramByHardfork('gasPrices', 'notexistingvalue', 'byzantium'), BigInt(0), msg) + assert.throws(() => { + c.paramByHardfork('notexistingvalue', 'byzantium') + }) /* // Manual test since no test triggering EIP config available @@ -26,19 +26,16 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { // To run please manually add an "ecAdd" entry with value 12345 to EIP2537 config // and uncomment the test msg = 'EIP config should take precedence over HF config' - assert.equal(c.param('gasPrices', 'ecAdd'), 12345, msg) + assert.equal(c.param('ecAddGas'), 12345, msg) */ }) it('Error cases for param(), paramByHardfork()', () => { const c = new Common({ chain: Chain.Mainnet }) - const msg = 'Should return 0n when called with non-existing topic' - assert.equal(c.paramByHardfork('gasPrizes', 'ecAdd', 'byzantium'), 0n, msg) - c.setHardfork(Hardfork.Byzantium) assert.equal( - c.param('gasPrices', 'ecAdd'), + c.param('ecAddGas'), BigInt(500), 'Should return correct value for HF set in class' ) @@ -48,96 +45,75 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { const c = new Common({ chain: Chain.Mainnet }) let msg = 'Should return correct value for chain start' - assert.equal( - c.paramByHardfork('pow', 'minerReward', 'chainstart'), - BigInt(5000000000000000000), - msg - ) + assert.equal(c.paramByHardfork('minerReward', 'chainstart'), BigInt(5000000000000000000), msg) msg = 'Should reflect HF update changes' - assert.equal( - c.paramByHardfork('pow', 'minerReward', 'byzantium'), - BigInt(3000000000000000000), - msg - ) + assert.equal(c.paramByHardfork('minerReward', 'byzantium'), BigInt(3000000000000000000), msg) msg = 'Should return updated sstore gas prices for constantinople' - assert.equal( - c.paramByHardfork('gasPrices', 'netSstoreNoopGas', 'constantinople'), - BigInt(200), - msg - ) + assert.equal(c.paramByHardfork('netSstoreNoopGas', 'constantinople'), BigInt(200), msg) msg = 'Should nullify SSTORE related values for petersburg' - assert.equal(c.paramByHardfork('gasPrices', 'netSstoreNoopGas', 'petersburg'), BigInt(0), msg) + assert.equal(c.paramByHardfork('netSstoreNoopGas', 'petersburg'), BigInt(0), msg) }) it('Access by block number, paramByBlock()', () => { const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) let msg = 'Should correctly translate block numbers into HF states (updated value)' - assert.equal(c.paramByBlock('pow', 'minerReward', 4370000), BigInt(3000000000000000000), msg) + assert.equal(c.paramByBlock('minerReward', 4370000), BigInt(3000000000000000000), msg) msg = 'Should correctly translate block numbers into HF states (original value)' - assert.equal(c.paramByBlock('pow', 'minerReward', 4369999), BigInt(5000000000000000000), msg) + assert.equal(c.paramByBlock('minerReward', 4369999), BigInt(5000000000000000000), msg) msg = 'Should correctly translate total difficulty into HF states' const td = BigInt('1196768507891266117779') - assert.equal( - c.paramByBlock('pow', 'minerReward', 4370000, td), - BigInt(3000000000000000000), - msg - ) + assert.equal(c.paramByBlock('minerReward', 4370000, td), BigInt(3000000000000000000), msg) }) it('Access on copied Common instances', () => { const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) let msg = 'Should correctly access param with param() on original Common' - assert.equal(c.param('pow', 'minerReward'), BigInt(2000000000000000000), msg) + assert.equal(c.param('minerReward'), BigInt(2000000000000000000), msg) const cCopy = c.copy() cCopy.setHardfork(Hardfork.Chainstart) msg = 'Should correctly access param with param() on copied Common with hardfork changed' - assert.equal(cCopy.param('pow', 'minerReward'), BigInt(5000000000000000000), msg) + assert.equal(cCopy.param('minerReward'), BigInt(5000000000000000000), msg) msg = 'Should correctly access param with param() on original Common after copy and HF change on copied Common' - assert.equal(c.param('pow', 'minerReward'), BigInt(2000000000000000000), msg) + assert.equal(c.param('minerReward'), BigInt(2000000000000000000), msg) }) it('EIP param access, paramByEIP()', () => { const c = new Common({ chain: Chain.Mainnet }) - let msg = 'Should return undefined for non-existing value' - assert.equal(c.paramByEIP('gasConfig', 'notexistingvalue', 1559), undefined, msg) - assert.equal(c.paramByEIP('gasPrices', 'notexistingvalue', 2537), undefined, msg) + assert.throws(() => { + c.paramByEIP('notexistingvalue', 1559) + }) + assert.throws(() => { + c.paramByEIP('notexistingvalue', 2537) + }) const UNSUPPORTED_EIP = 1000000 - let f = function () { - c.paramByEIP('gasPrices', 'Bls12381G1AddGas', UNSUPPORTED_EIP) + const f = function () { + c.paramByEIP('Bls12381G1AddGas', UNSUPPORTED_EIP) } - msg = 'Should throw for using paramByEIP() with an unsupported EIP' + let msg = 'Should throw for using paramByEIP() with an unsupported EIP' assert.throws(f, /not supported$/, undefined, msg) - msg = 'Should return undefined for paramByEIP() with a not existing topic' - assert.equal(c.paramByEIP('notExistingTopic', 'Bls12381G1AddGas', 1559), undefined, msg) - f = function () { - c.paramByEIP('notExistingTopic', 'Bls12381G1AddGas', 2537) - } - msg = 'Should return undefined for paramByEIP() with a not existing topic' - assert.equal(f(), undefined, msg) - msg = 'Should return Bls12381G1AddGas gas price for EIP2537' - assert.equal(c.paramByEIP('gasPrices', 'Bls12381G1AddGas', 2537), BigInt(500), msg) + assert.equal(c.paramByEIP('Bls12381G1AddGas', 2537), BigInt(500), msg) }) it('returns the right block delay for EIP3554', () => { for (const fork of [Hardfork.MuirGlacier, Hardfork.Berlin]) { const c = new Common({ chain: Chain.Mainnet, hardfork: fork }) - let delay = c.param('pow', 'difficultyBombDelay') + let delay = c.param('difficultyBombDelay') assert.equal(delay, BigInt(9000000)) c.setEIPs([3554]) - delay = c.param('pow', 'difficultyBombDelay') + delay = c.param('difficultyBombDelay') assert.equal(delay, BigInt(9500000)) } }) diff --git a/packages/devp2p/package.json b/packages/devp2p/package.json index a20a1e5591..2665112bf0 100644 --- a/packages/devp2p/package.json +++ b/packages/devp2p/package.json @@ -55,6 +55,7 @@ "lint:fix": "../../config/cli/lint-fix.sh", "prepublishOnly": "../../config/cli/prepublish.sh", "test": "vitest run", + "test:node": "npm run test", "tsc": "../../config/cli/ts-compile.sh" }, "dependencies": { diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index a166f503a6..1d1ac85bac 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -396,7 +396,7 @@ export class EVM implements EVMInterface { if (this.common.isActivatedEIP(3860)) { if ( - message.data.length > Number(this.common.param('vm', 'maxInitCodeSize')) && + message.data.length > Number(this.common.param('maxInitCodeSize')) && !this.allowUnlimitedInitCodeSize ) { return { @@ -552,8 +552,7 @@ export class EVM implements EVMInterface { let totalGas = result.executionGasUsed let returnFee = BIGINT_0 if (!result.exceptionError && !this.common.isActivatedEIP(6800)) { - returnFee = - BigInt(result.returnValue.length) * BigInt(this.common.param('gasPrices', 'createData')) + returnFee = BigInt(result.returnValue.length) * BigInt(this.common.param('createDataGas')) totalGas = totalGas + returnFee if (this.DEBUG) { debugGas(`Add return value size fee (${returnFee} to gas used (-> ${totalGas}))`) @@ -565,7 +564,7 @@ export class EVM implements EVMInterface { if ( !result.exceptionError && this.common.gteHardfork(Hardfork.SpuriousDragon) && - result.returnValue.length > Number(this.common.param('vm', 'maxCodeSize')) + result.returnValue.length > Number(this.common.param('maxCodeSize')) ) { allowedCodeSize = false } diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 4ce1cc582f..2c9715f9f5 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -32,8 +32,6 @@ import type { Address, PrefixedHexString } from '@ethereumjs/util' const debugGas = debugDefault('evm:gas') -let counter = 0 - export interface InterpreterOpts { pc?: number } @@ -339,11 +337,6 @@ export class Interpreter { * reducing its base gas cost, and increments the program counter. */ async runStep(opcodeObj?: OpcodeMapEntry): Promise { - counter += 1 - if (counter % 1000 === 0) { - console.log(counter) - } - const opEntry = opcodeObj ?? this.lookupOpInfo(this._runState.opCode) const opInfo = opEntry.opcodeInfo @@ -995,7 +988,7 @@ export class Interpreter { // Check if account has enough ether and max depth not exceeded if ( - this._env.depth >= Number(this.common.param('vm', 'stackLimit')) || + this._env.depth >= Number(this.common.param('stackLimit')) || (msg.delegatecall !== true && this._env.contract.balance < msg.value) ) { return BIGINT_0 @@ -1060,7 +1053,7 @@ export class Interpreter { // Check if account has enough ether and max depth not exceeded if ( - this._env.depth >= Number(this.common.param('vm', 'stackLimit')) || + this._env.depth >= Number(this.common.param('stackLimit')) || this._env.contract.balance < value ) { return BIGINT_0 @@ -1076,7 +1069,7 @@ export class Interpreter { if (this.common.isActivatedEIP(3860)) { if ( - codeToRun.length > Number(this.common.param('vm', 'maxInitCodeSize')) && + codeToRun.length > Number(this.common.param('maxInitCodeSize')) && this._evm.allowUnlimitedInitCodeSize === false ) { return BIGINT_0 @@ -1189,7 +1182,7 @@ export class Interpreter { async _selfDestruct(toAddress: Address): Promise { // only add to refund if this is the first selfdestruct for the address if (!this._result.selfdestruct.has(bytesToHex(this._env.address.bytes))) { - this.refundGas(this.common.param('gasPrices', 'selfdestructRefund')) + this.refundGas(this.common.param('selfdestructRefundGas')) } this._result.selfdestruct.add(bytesToHex(this._env.address.bytes)) diff --git a/packages/evm/src/opcodes/EIP1283.ts b/packages/evm/src/opcodes/EIP1283.ts index 63e6eae0da..49a67a48c8 100644 --- a/packages/evm/src/opcodes/EIP1283.ts +++ b/packages/evm/src/opcodes/EIP1283.ts @@ -21,24 +21,24 @@ export function updateSstoreGasEIP1283( ) { if (equalsBytes(currentStorage, value)) { // If current value equals new value (this is a no-op), 200 gas is deducted. - return common.param('gasPrices', 'netSstoreNoopGas') + return common.param('netSstoreNoopGas') } // If current value does not equal new value if (equalsBytes(originalStorage, currentStorage)) { // If original value equals current value (this storage slot has not been changed by the current execution context) if (originalStorage.length === 0) { // If original value is 0, 20000 gas is deducted. - return common.param('gasPrices', 'netSstoreInitGas') + return common.param('netSstoreInitGas') } if (value.length === 0) { // If new value is 0, add 15000 gas to refund counter. runState.interpreter.refundGas( - common.param('gasPrices', 'netSstoreClearRefund'), + common.param('netSstoreClearRefundGas'), 'EIP-1283 -> netSstoreClearRefund' ) } // Otherwise, 5000 gas is deducted. - return common.param('gasPrices', 'netSstoreCleanGas') + return common.param('netSstoreCleanGas') } // If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. if (originalStorage.length !== 0) { @@ -46,13 +46,13 @@ export function updateSstoreGasEIP1283( if (currentStorage.length === 0) { // If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. runState.interpreter.subRefund( - common.param('gasPrices', 'netSstoreClearRefund'), + common.param('netSstoreClearRefundGas'), 'EIP-1283 -> netSstoreClearRefund' ) } else if (value.length === 0) { // If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. runState.interpreter.refundGas( - common.param('gasPrices', 'netSstoreClearRefund'), + common.param('netSstoreClearRefundGas'), 'EIP-1283 -> netSstoreClearRefund' ) } @@ -62,16 +62,16 @@ export function updateSstoreGasEIP1283( if (originalStorage.length === 0) { // If original value is 0, add 19800 gas to refund counter. runState.interpreter.refundGas( - common.param('gasPrices', 'netSstoreResetClearRefund'), + common.param('netSstoreResetClearRefundGas'), 'EIP-1283 -> netSstoreResetClearRefund' ) } else { // Otherwise, add 4800 gas to refund counter. runState.interpreter.refundGas( - common.param('gasPrices', 'netSstoreResetRefund'), + common.param('netSstoreResetRefundGas'), 'EIP-1283 -> netSstoreResetRefund' ) } } - return common.param('gasPrices', 'netSstoreDirtyGas') + return common.param('netSstoreDirtyGas') } diff --git a/packages/evm/src/opcodes/EIP2200.ts b/packages/evm/src/opcodes/EIP2200.ts index f1c4656740..50ee69ddd1 100644 --- a/packages/evm/src/opcodes/EIP2200.ts +++ b/packages/evm/src/opcodes/EIP2200.ts @@ -26,41 +26,41 @@ export function updateSstoreGasEIP2200( common: Common ) { // Fail if not enough gas is left - if (runState.interpreter.getGasLeft() <= common.param('gasPrices', 'sstoreSentryGasEIP2200')) { + if (runState.interpreter.getGasLeft() <= common.param('sstoreSentryEIP2200Gas')) { trap(ERROR.OUT_OF_GAS) } // Noop if (equalsBytes(currentStorage, value)) { - const sstoreNoopCost = common.param('gasPrices', 'sstoreNoopGasEIP2200') + const sstoreNoopCost = common.param('sstoreNoopEIP2200Gas') return adjustSstoreGasEIP2929(runState, key, sstoreNoopCost, 'noop', common) } if (equalsBytes(originalStorage, currentStorage)) { // Create slot if (originalStorage.length === 0) { - return common.param('gasPrices', 'sstoreInitGasEIP2200') + return common.param('sstoreInitEIP2200Gas') } // Delete slot if (value.length === 0) { runState.interpreter.refundGas( - common.param('gasPrices', 'sstoreClearRefundEIP2200'), + common.param('sstoreClearRefundEIP2200Gas'), 'EIP-2200 -> sstoreClearRefundEIP2200' ) } // Write existing slot - return common.param('gasPrices', 'sstoreCleanGasEIP2200') + return common.param('sstoreCleanEIP2200Gas') } if (originalStorage.length > 0) { if (currentStorage.length === 0) { // Recreate slot runState.interpreter.subRefund( - common.param('gasPrices', 'sstoreClearRefundEIP2200'), + common.param('sstoreClearRefundEIP2200Gas'), 'EIP-2200 -> sstoreClearRefundEIP2200' ) } else if (value.length === 0) { // Delete slot runState.interpreter.refundGas( - common.param('gasPrices', 'sstoreClearRefundEIP2200'), + common.param('sstoreClearRefundEIP2200Gas'), 'EIP-2200 -> sstoreClearRefundEIP2200' ) } @@ -68,14 +68,14 @@ export function updateSstoreGasEIP2200( if (equalsBytes(originalStorage, value)) { if (originalStorage.length === 0) { // Reset to original non-existent slot - const sstoreInitRefund = common.param('gasPrices', 'sstoreInitRefundEIP2200') + const sstoreInitRefund = common.param('sstoreInitRefundEIP2200Gas') runState.interpreter.refundGas( adjustSstoreGasEIP2929(runState, key, sstoreInitRefund, 'initRefund', common), 'EIP-2200 -> initRefund' ) } else { // Reset to original existing slot - const sstoreCleanRefund = common.param('gasPrices', 'sstoreCleanRefundEIP2200') + const sstoreCleanRefund = common.param('sstoreCleanRefundEIP2200Gas') runState.interpreter.refundGas( BigInt(adjustSstoreGasEIP2929(runState, key, sstoreCleanRefund, 'cleanRefund', common)), 'EIP-2200 -> cleanRefund' @@ -83,5 +83,5 @@ export function updateSstoreGasEIP2200( } } // Dirty update - return common.param('gasPrices', 'sstoreDirtyGasEIP2200') + return common.param('sstoreDirtyEIP2200Gas') } diff --git a/packages/evm/src/opcodes/EIP2929.ts b/packages/evm/src/opcodes/EIP2929.ts index f249c1e7dd..9812f45467 100644 --- a/packages/evm/src/opcodes/EIP2929.ts +++ b/packages/evm/src/opcodes/EIP2929.ts @@ -30,11 +30,11 @@ export function accessAddressEIP2929( // selfdestruct beneficiary address reads are charged an *additional* cold access // if verkle not activated if (chargeGas && !common.isActivatedEIP(6800)) { - return common.param('gasPrices', 'coldaccountaccess') + return common.param('coldaccountaccessGas') } // Warm: (selfdestruct beneficiary address reads are not charged when warm) } else if (chargeGas && !isSelfdestructOrAuthcall) { - return common.param('gasPrices', 'warmstorageread') + return common.param('warmstoragereadGas') } return BIGINT_0 } @@ -63,10 +63,10 @@ export function accessStorageEIP2929( if (slotIsCold) { runState.interpreter.journal.addWarmedStorage(address, key) if (chargeGas && !common.isActivatedEIP(6800)) { - return common.param('gasPrices', 'coldsload') + return common.param('coldsloadGas') } } else if (chargeGas && (!isSstore || common.isActivatedEIP(6800))) { - return common.param('gasPrices', 'warmstorageread') + return common.param('warmstoragereadGas') } return BIGINT_0 } @@ -91,17 +91,17 @@ export function adjustSstoreGasEIP2929( if (!common.isActivatedEIP(2929)) return defaultCost const address = runState.interpreter.getAddress().bytes - const warmRead = common.param('gasPrices', 'warmstorageread') - const coldSload = common.param('gasPrices', 'coldsload') + const warmRead = common.param('warmstoragereadGas') + const coldSload = common.param('coldsloadGas') if (runState.interpreter.journal.isWarmedStorage(address, key)) { switch (costName) { case 'noop': return warmRead case 'initRefund': - return common.param('gasPrices', 'sstoreInitGasEIP2200') - warmRead + return common.param('sstoreInitEIP2200Gas') - warmRead case 'cleanRefund': - return common.param('gasPrices', 'sstoreReset') - coldSload - warmRead + return common.param('sstoreResetGas') - coldSload - warmRead } } diff --git a/packages/evm/src/opcodes/codes.ts b/packages/evm/src/opcodes/codes.ts index 2c374af45a..dd3e2250d2 100644 --- a/packages/evm/src/opcodes/codes.ts +++ b/packages/evm/src/opcodes/codes.ts @@ -429,7 +429,7 @@ export function getOpcodesForHF(common: Common, customOpcodes?: CustomOpcode[]): } for (const key in opcodeBuilder) { - const baseFee = Number(common.param('gasPrices', opcodeBuilder[key].name.toLowerCase())) + const baseFee = Number(common.param(`${opcodeBuilder[key].name.toLowerCase()}Gas`)) // explicitly verify that we have defined a base fee if (baseFee === undefined) { throw new Error(`base fee not defined for: ${opcodeBuilder[key].name}`) diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 69e5faf9bd..7011f92273 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -650,9 +650,9 @@ export const handlers: Map = new Map([ } const historyAddress = new Address( - bigIntToAddressBytes(common.param('vm', 'historyStorageAddress')) + bigIntToAddressBytes(common.param('historyStorageAddress')) ) - const historyServeWindow = common.param('vm', 'historyServeWindow') + const historyServeWindow = common.param('historyServeWindow') const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32) if (common.isActivatedEIP(6800)) { @@ -1360,7 +1360,7 @@ export const handlers: Map = new Map([ if ( common.isActivatedEIP(3860) && - length > Number(common.param('vm', 'maxInitCodeSize')) && + length > Number(common.param('maxInitCodeSize')) && !runState.interpreter._evm.allowUnlimitedInitCodeSize ) { trap(ERROR.INITCODE_SIZE_VIOLATION) @@ -1396,7 +1396,7 @@ export const handlers: Map = new Map([ if ( common.isActivatedEIP(3860) && - length > Number(common.param('vm', 'maxInitCodeSize')) && + length > Number(common.param('maxInitCodeSize')) && !runState.interpreter._evm.allowUnlimitedInitCodeSize ) { trap(ERROR.INITCODE_SIZE_VIOLATION) @@ -1440,7 +1440,7 @@ export const handlers: Map = new Map([ let gasLimit = runState.messageGasLimit! if (value !== BIGINT_0) { - const callStipend = common.param('gasPrices', 'callStipend') + const callStipend = common.param('callStipendGas') runState.interpreter.addStipend(callStipend) gasLimit += callStipend } @@ -1463,7 +1463,7 @@ export const handlers: Map = new Map([ let gasLimit = runState.messageGasLimit! if (value !== BIGINT_0) { - const callStipend = common.param('gasPrices', 'callStipend') + const callStipend = common.param('callStipendGas') runState.interpreter.addStipend(callStipend) gasLimit += callStipend } diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index a706698cf9..7d2bfe179e 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -72,7 +72,7 @@ export const dynamicGasHandlers: Map 32) { trap(ERROR.OUT_OF_RANGE) } - const expPricePerByte = common.param('gasPrices', 'expByte') + const expPricePerByte = common.param('expByteGas') gas += BigInt(byteLength) * expPricePerByte return gas }, @@ -83,7 +83,7 @@ export const dynamicGasHandlers: Map { const [offset, length] = runState.stack.peek(2) gas += subMemUsage(runState, offset, length, common) - gas += common.param('gasPrices', 'keccak256Word') * divCeil(length, BIGINT_32) + gas += common.param('keccak256WordGas') * divCeil(length, BIGINT_32) return gas }, ], @@ -120,7 +120,7 @@ export const dynamicGasHandlers: Map BIGINT_0) { - gas += common.param('gasPrices', 'authcallValueTransfer') + gas += common.param('authcallValueTransferGas') const account = await runState.stateManager.getAccount(toAddress) if (!account) { - gas += common.param('gasPrices', 'callNewAccount') + gas += common.param('callNewAccountGas') } } @@ -855,7 +853,7 @@ export const dynamicGasHandlers: Map 0, charge CALL_VALUE_COST if (value > BIGINT_0) { - gas += common.param('gasPrices', 'callValueTransfer') + gas += common.param('callValueTransferGas') } // Check if the target address > 20 bytes @@ -877,12 +875,12 @@ export const dynamicGasHandlers: Map= Number(common.param('vm', 'stackLimit')) || + runState.env.depth >= Number(common.param('stackLimit')) || runState.env.contract.balance < value || gasLimit < minCalleeGas ) { @@ -934,8 +932,8 @@ export const dynamicGasHandlers: Map= Number(common.param('vm', 'stackLimit')) || - gasLimit < minCalleeGas - ) { + if (runState.env.depth >= Number(common.param('stackLimit')) || gasLimit < minCalleeGas) { // Note: this is a hack, TODO: get around this hack and clean this up // This special case will ensure that the actual EXT*CALL is being ran, // But, the code in `function.ts` will note that `runState.messageGasLimit` is set to a negative number @@ -1021,8 +1016,8 @@ export const dynamicGasHandlers: Map= Number(common.param('vm', 'stackLimit')) || - gasLimit < minCalleeGas - ) { + if (runState.env.depth >= Number(common.param('stackLimit')) || gasLimit < minCalleeGas) { // Note: this is a hack, TODO: get around this hack and clean this up // This special case will ensure that the actual EXT*CALL is being ran, // But, the code in `function.ts` will note that `runState.messageGasLimit` is set to a negative number @@ -1093,7 +1085,7 @@ export const dynamicGasHandlers: Map 0 && currentStorage.length > 0) ) { - const gas = common.param('gasPrices', 'sstoreReset') + const gas = common.param('sstoreResetGas') return gas } else if (value.length === 0 && currentStorage.length > 0) { - const gas = common.param('gasPrices', 'sstoreReset') - runState.interpreter.refundGas(common.param('gasPrices', 'sstoreRefund'), 'updateSstoreGas') + const gas = common.param('sstoreResetGas') + runState.interpreter.refundGas(common.param('sstoreRefundGas'), 'updateSstoreGas') return gas } else { /* @@ -229,7 +229,7 @@ export function updateSstoreGas( -> Value is zero, but slot is nonzero Thus, the remaining case is where value is nonzero, but slot is zero, which is this clause */ - return common.param('gasPrices', 'sstoreSet') + return common.param('sstoreSetGas') } } diff --git a/packages/evm/src/precompiles/01-ecrecover.ts b/packages/evm/src/precompiles/01-ecrecover.ts index a6a7d609d5..7c1df7b476 100644 --- a/packages/evm/src/precompiles/01-ecrecover.ts +++ b/packages/evm/src/precompiles/01-ecrecover.ts @@ -17,7 +17,7 @@ import type { PrecompileInput } from './types.js' export function precompile01(opts: PrecompileInput): ExecResult { const ecrecoverFunction = opts.common.customCrypto.ecrecover ?? ecrecover - const gasUsed = opts.common.param('gasPrices', 'ecRecover') + const gasUsed = opts.common.param('ecRecoverGas') if (opts._debug !== undefined) { opts._debug( `Run ECRECOVER (0x01) precompile data=${short(opts.data)} length=${ diff --git a/packages/evm/src/precompiles/02-sha256.ts b/packages/evm/src/precompiles/02-sha256.ts index e6ee57fe48..19fc94e649 100644 --- a/packages/evm/src/precompiles/02-sha256.ts +++ b/packages/evm/src/precompiles/02-sha256.ts @@ -9,8 +9,8 @@ import type { PrecompileInput } from './types.js' export function precompile02(opts: PrecompileInput): ExecResult { const data = opts.data const sha256Function = opts.common.customCrypto.sha256 ?? sha256 - let gasUsed = opts.common.param('gasPrices', 'sha256') - gasUsed += opts.common.param('gasPrices', 'sha256Word') * BigInt(Math.ceil(data.length / 32)) + let gasUsed = opts.common.param('sha256Gas') + gasUsed += opts.common.param('sha256WordGas') * BigInt(Math.ceil(data.length / 32)) if (opts._debug !== undefined) { opts._debug( diff --git a/packages/evm/src/precompiles/03-ripemd160.ts b/packages/evm/src/precompiles/03-ripemd160.ts index d244563509..e4cdded33e 100644 --- a/packages/evm/src/precompiles/03-ripemd160.ts +++ b/packages/evm/src/precompiles/03-ripemd160.ts @@ -9,8 +9,8 @@ import type { PrecompileInput } from './types.js' export function precompile03(opts: PrecompileInput): ExecResult { const data = opts.data - let gasUsed = opts.common.param('gasPrices', 'ripemd160') - gasUsed += opts.common.param('gasPrices', 'ripemd160Word') * BigInt(Math.ceil(data.length / 32)) + let gasUsed = opts.common.param('ripemd160Gas') + gasUsed += opts.common.param('ripemd160WordGas') * BigInt(Math.ceil(data.length / 32)) if (opts._debug !== undefined) { opts._debug( diff --git a/packages/evm/src/precompiles/04-identity.ts b/packages/evm/src/precompiles/04-identity.ts index e5a73f1771..52602abcf4 100644 --- a/packages/evm/src/precompiles/04-identity.ts +++ b/packages/evm/src/precompiles/04-identity.ts @@ -8,8 +8,8 @@ import type { PrecompileInput } from './types.js' export function precompile04(opts: PrecompileInput): ExecResult { const data = opts.data - let gasUsed = opts.common.param('gasPrices', 'identity') - gasUsed += opts.common.param('gasPrices', 'identityWord') * BigInt(Math.ceil(data.length / 32)) + let gasUsed = opts.common.param('identityGas') + gasUsed += opts.common.param('identityWordGas') * BigInt(Math.ceil(data.length / 32)) if (opts._debug !== undefined) { opts._debug( `Run IDENTITY (0x04) precompile data=${short(opts.data)} length=${ diff --git a/packages/evm/src/precompiles/05-modexp.ts b/packages/evm/src/precompiles/05-modexp.ts index 29f5970157..791ceefb53 100644 --- a/packages/evm/src/precompiles/05-modexp.ts +++ b/packages/evm/src/precompiles/05-modexp.ts @@ -118,7 +118,7 @@ export function precompile05(opts: PrecompileInput): ExecResult { if (maxLen < mLen) { maxLen = mLen } - const Gquaddivisor = opts.common.param('gasPrices', 'modexpGquaddivisor') + const Gquaddivisor = opts.common.param('modexpGquaddivisorGas') let gasUsed const bStart = BIGINT_96 diff --git a/packages/evm/src/precompiles/06-ecadd.ts b/packages/evm/src/precompiles/06-ecadd.ts index 08a8a49fac..e978d96663 100644 --- a/packages/evm/src/precompiles/06-ecadd.ts +++ b/packages/evm/src/precompiles/06-ecadd.ts @@ -9,7 +9,7 @@ import type { PrecompileInput } from './types.js' export function precompile06(opts: PrecompileInput): ExecResult { const inputData = bytesToUnprefixedHex(opts.data.subarray(0, 128)) - const gasUsed = opts.common.param('gasPrices', 'ecAdd') + const gasUsed = opts.common.param('ecAddGas') if (opts._debug !== undefined) { opts._debug( `Run ECADD (0x06) precompile data=${short(opts.data)} length=${opts.data.length} gasLimit=${ diff --git a/packages/evm/src/precompiles/07-ecmul.ts b/packages/evm/src/precompiles/07-ecmul.ts index 12a2da11fc..611e1ce20b 100644 --- a/packages/evm/src/precompiles/07-ecmul.ts +++ b/packages/evm/src/precompiles/07-ecmul.ts @@ -8,7 +8,7 @@ import type { PrecompileInput } from './types.js' export function precompile07(opts: PrecompileInput): ExecResult { const inputData = bytesToUnprefixedHex(opts.data.subarray(0, 128)) - const gasUsed = opts.common.param('gasPrices', 'ecMul') + const gasUsed = opts.common.param('ecMulGas') if (opts._debug !== undefined) { opts._debug( `Run ECMUL (0x07) precompile data=${short(opts.data)} length=${opts.data.length} gasLimit=${ diff --git a/packages/evm/src/precompiles/08-ecpairing.ts b/packages/evm/src/precompiles/08-ecpairing.ts index cf398be205..2fc5be6cbc 100644 --- a/packages/evm/src/precompiles/08-ecpairing.ts +++ b/packages/evm/src/precompiles/08-ecpairing.ts @@ -11,8 +11,7 @@ export function precompile08(opts: PrecompileInput): ExecResult { // no need to care about non-divisible-by-192, because bn128.pairing will properly fail in that case const inputDataSize = BigInt(Math.floor(inputData.length / 192)) const gasUsed = - opts.common.param('gasPrices', 'ecPairing') + - inputDataSize * opts.common.param('gasPrices', 'ecPairingWord') + opts.common.param('ecPairingGas') + inputDataSize * opts.common.param('ecPairingWordGas') if (opts._debug !== undefined) { opts._debug( `Run ECPAIRING (0x08) precompile data=${short(opts.data)} length=${ diff --git a/packages/evm/src/precompiles/09-blake2f.ts b/packages/evm/src/precompiles/09-blake2f.ts index 9ac57f0a58..7fb536f1c6 100644 --- a/packages/evm/src/precompiles/09-blake2f.ts +++ b/packages/evm/src/precompiles/09-blake2f.ts @@ -188,7 +188,7 @@ export function precompile09(opts: PrecompileInput): ExecResult { // final const f = lastByte === 1 - let gasUsed = opts.common.param('gasPrices', 'blake2Round') + let gasUsed = opts.common.param('blake2RoundGas') gasUsed *= BigInt(rounds) if (opts._debug !== undefined) { opts._debug( diff --git a/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts b/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts index c9fb679678..6b3dea6ced 100644 --- a/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts +++ b/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts @@ -23,7 +23,7 @@ export async function precompile0a(opts: PrecompileInput): Promise { if (opts.common.customCrypto?.kzg === undefined) { throw new Error('kzg not initialized') } - const gasUsed = opts.common.param('gasPrices', 'kzgPointEvaluationGasPrecompilePrice') + const gasUsed = opts.common.param('kzgPointEvaluationPrecompileGas') if (opts._debug !== undefined) { opts._debug( `Run KZG_POINT_EVALUATION (0x14) precompile data=${short(opts.data)} length=${ @@ -43,8 +43,8 @@ export async function precompile0a(opts: PrecompileInput): Promise { return EvmErrorResult(new EvmError(ERROR.INVALID_INPUT_LENGTH), opts.gasLimit) } - const version = Number(opts.common.param('sharding', 'blobCommitmentVersionKzg')) - const fieldElementsPerBlob = opts.common.param('sharding', 'fieldElementsPerBlob') + const version = Number(opts.common.param('blobCommitmentVersionKzg')) + const fieldElementsPerBlob = opts.common.param('fieldElementsPerBlob') const versionedHash = opts.data.subarray(0, 32) const z = opts.data.subarray(32, 64) const y = opts.data.subarray(64, 96) diff --git a/packages/evm/src/precompiles/0b-bls12-g1add.ts b/packages/evm/src/precompiles/0b-bls12-g1add.ts index b6357ff4e1..cad13c876e 100644 --- a/packages/evm/src/precompiles/0b-bls12-g1add.ts +++ b/packages/evm/src/precompiles/0b-bls12-g1add.ts @@ -12,7 +12,7 @@ export async function precompile0b(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381G1AddGas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381G1AddGas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12G1ADD (0x0b)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/src/precompiles/0c-bls12-g1mul.ts b/packages/evm/src/precompiles/0c-bls12-g1mul.ts index 0fdc07cd14..3302c77295 100644 --- a/packages/evm/src/precompiles/0c-bls12-g1mul.ts +++ b/packages/evm/src/precompiles/0c-bls12-g1mul.ts @@ -12,7 +12,7 @@ export async function precompile0c(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381G1MulGas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381G1MulGas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12G1MUL (0x0c)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/src/precompiles/0d-bls12-g1msm.ts b/packages/evm/src/precompiles/0d-bls12-g1msm.ts index 229b46bbeb..e1b00709c0 100644 --- a/packages/evm/src/precompiles/0d-bls12-g1msm.ts +++ b/packages/evm/src/precompiles/0d-bls12-g1msm.ts @@ -29,7 +29,7 @@ export async function precompile0d(opts: PrecompileInput): Promise { // on this eventually to be "floored" pair number should happen before the input length modulo // validation (same for g2msm) const numPairs = Math.floor(inputData.length / 160) - const gasUsedPerPair = opts.common.paramByEIP('gasPrices', 'Bls12381G1MulGas', 2537) ?? BigInt(0) + const gasUsedPerPair = opts.common.paramByEIP('Bls12381G1MulGas', 2537) ?? BigInt(0) const gasUsed = msmGasUsed(numPairs, gasUsedPerPair) if (!gasCheck(opts, gasUsed, 'BLS12G1MSM (0x0d)')) { diff --git a/packages/evm/src/precompiles/0e-bls12-g2add.ts b/packages/evm/src/precompiles/0e-bls12-g2add.ts index ce1a25cf3a..12bc94804f 100644 --- a/packages/evm/src/precompiles/0e-bls12-g2add.ts +++ b/packages/evm/src/precompiles/0e-bls12-g2add.ts @@ -12,7 +12,7 @@ export async function precompile0e(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381G2AddGas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381G2AddGas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12G2ADD (0x0e)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/src/precompiles/0f-bls12-g2mul.ts b/packages/evm/src/precompiles/0f-bls12-g2mul.ts index 7e83542b94..ed4c8553ff 100644 --- a/packages/evm/src/precompiles/0f-bls12-g2mul.ts +++ b/packages/evm/src/precompiles/0f-bls12-g2mul.ts @@ -12,7 +12,7 @@ export async function precompile0f(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381G2MulGas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381G2MulGas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12G2MUL (0x0f)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/src/precompiles/10-bls12-g2msm.ts b/packages/evm/src/precompiles/10-bls12-g2msm.ts index aa3b75fea1..d660b1521d 100644 --- a/packages/evm/src/precompiles/10-bls12-g2msm.ts +++ b/packages/evm/src/precompiles/10-bls12-g2msm.ts @@ -24,7 +24,7 @@ export async function precompile10(opts: PrecompileInput): Promise { } const numPairs = Math.floor(opts.data.length / 288) - const gasUsedPerPair = opts.common.paramByEIP('gasPrices', 'Bls12381G2MulGas', 2537) ?? BigInt(0) + const gasUsedPerPair = opts.common.paramByEIP('Bls12381G2MulGas', 2537) ?? BigInt(0) const gasUsed = msmGasUsed(numPairs, gasUsedPerPair) if (!gasCheck(opts, gasUsed, 'BLS12G2MSM (0x10)')) { diff --git a/packages/evm/src/precompiles/11-bls12-pairing.ts b/packages/evm/src/precompiles/11-bls12-pairing.ts index d24fdc95ed..b36cf33049 100644 --- a/packages/evm/src/precompiles/11-bls12-pairing.ts +++ b/packages/evm/src/precompiles/11-bls12-pairing.ts @@ -11,7 +11,7 @@ import type { PrecompileInput } from './types.js' export async function precompile11(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface - const baseGas = opts.common.paramByEIP('gasPrices', 'Bls12381PairingBaseGas', 2537) ?? BigInt(0) + const baseGas = opts.common.paramByEIP('Bls12381PairingBaseGas', 2537) ?? BigInt(0) // TODO: confirm that this is not a thing for the other precompiles if (opts.data.length === 0) { @@ -21,8 +21,7 @@ export async function precompile11(opts: PrecompileInput): Promise { return EvmErrorResult(new EvmError(ERROR.BLS_12_381_INPUT_EMPTY), opts.gasLimit) } - const gasUsedPerPair = - opts.common.paramByEIP('gasPrices', 'Bls12381PairingPerPairGas', 2537) ?? BigInt(0) + const gasUsedPerPair = opts.common.paramByEIP('Bls12381PairingPerPairGas', 2537) ?? BigInt(0) // TODO: For this precompile it is the only exception that the length check is placed before the // gas check. I will keep it there to not side-change the existing implementation, but we should diff --git a/packages/evm/src/precompiles/12-bls12-map-fp-to-g1.ts b/packages/evm/src/precompiles/12-bls12-map-fp-to-g1.ts index fc07d753a7..28eb2b9168 100644 --- a/packages/evm/src/precompiles/12-bls12-map-fp-to-g1.ts +++ b/packages/evm/src/precompiles/12-bls12-map-fp-to-g1.ts @@ -12,7 +12,7 @@ export async function precompile12(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381MapG1Gas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381MapG1Gas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12MAPFPTOG1 (0x12)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/src/precompiles/13-bls12-map-fp2-to-g2.ts b/packages/evm/src/precompiles/13-bls12-map-fp2-to-g2.ts index b1a39f5f8a..b774cb098f 100644 --- a/packages/evm/src/precompiles/13-bls12-map-fp2-to-g2.ts +++ b/packages/evm/src/precompiles/13-bls12-map-fp2-to-g2.ts @@ -12,7 +12,7 @@ export async function precompile13(opts: PrecompileInput): Promise { const bls = (opts._EVM)._bls! as EVMBLSInterface // note: the gas used is constant; even if the input is incorrect. - const gasUsed = opts.common.paramByEIP('gasPrices', 'Bls12381MapG2Gas', 2537) ?? BigInt(0) + const gasUsed = opts.common.paramByEIP('Bls12381MapG2Gas', 2537) ?? BigInt(0) if (!gasCheck(opts, gasUsed, 'BLS12MAPFP2TOG2 (0x13)')) { return OOGResult(opts.gasLimit) } diff --git a/packages/evm/test/eips/eip-3860.spec.ts b/packages/evm/test/eips/eip-3860.spec.ts index bb3b82f5da..e9f08e022b 100644 --- a/packages/evm/test/eips/eip-3860.spec.ts +++ b/packages/evm/test/eips/eip-3860.spec.ts @@ -150,7 +150,7 @@ describe('EIP 3860 tests', () => { // It tries to deploy a contract too large, where the code is all zeros // (since memory which is not allocated/resized to yet is always defaulted to 0) data: concatBytes( - hexToBytes(`0x${'00'.repeat(Number(common.param('vm', 'maxInitCodeSize')) + 1)}`), + hexToBytes(`0x${'00'.repeat(Number(common.param('maxInitCodeSize')) + 1)}`), bytes ), } diff --git a/packages/tx/src/baseTransaction.ts b/packages/tx/src/baseTransaction.ts index 2597dfa885..d006773276 100644 --- a/packages/tx/src/baseTransaction.ts +++ b/packages/tx/src/baseTransaction.ts @@ -174,11 +174,11 @@ export abstract class BaseTransaction * The minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) */ getBaseFee(): bigint { - const txFee = this.common.param('gasPrices', 'tx') + const txFee = this.common.param('txGas') let fee = this.getDataFee() if (txFee) fee += txFee if (this.common.gteHardfork('homestead') && this.toCreationAddress()) { - const txCreationFee = this.common.param('gasPrices', 'txCreation') + const txCreationFee = this.common.param('txCreationGas') if (txCreationFee) fee += txCreationFee } return fee @@ -188,8 +188,8 @@ export abstract class BaseTransaction * The amount of gas paid for the data in this tx */ getDataFee(): bigint { - const txDataZero = this.common.param('gasPrices', 'txDataZero') - const txDataNonZero = this.common.param('gasPrices', 'txDataNonZero') + const txDataZero = this.common.param('txDataZeroGas') + const txDataNonZero = this.common.param('txDataNonZeroGas') let cost = BIGINT_0 for (let i = 0; i < this.data.length; i++) { @@ -198,7 +198,7 @@ export abstract class BaseTransaction if ((this.to === undefined || this.to === null) && this.common.isActivatedEIP(3860)) { const dataLength = BigInt(Math.ceil(this.data.length / 32)) - const initCodeCost = this.common.param('gasPrices', 'initCodeWordCost') * dataLength + const initCodeCost = this.common.param('initCodeWordGas') * dataLength cost += initCodeCost } diff --git a/packages/tx/src/capabilities/eip7702.ts b/packages/tx/src/capabilities/eip7702.ts index 06813dc996..67a3d2f285 100644 --- a/packages/tx/src/capabilities/eip7702.ts +++ b/packages/tx/src/capabilities/eip7702.ts @@ -10,7 +10,7 @@ import type { EIP7702CompatibleTx } from '../types.js' export function getDataFee(tx: EIP7702CompatibleTx): bigint { const eip2930Cost = BigInt(AccessLists.getDataFeeEIP2930(tx.accessList, tx.common)) const eip7702Cost = BigInt( - tx.authorizationList.length * Number(tx.common.param('gasPrices', 'perAuthBaseCost')) + tx.authorizationList.length * Number(tx.common.param('perAuthBaseGas')) ) return Legacy.getDataFee(tx, eip2930Cost + eip7702Cost) } diff --git a/packages/tx/src/eip4844Transaction.ts b/packages/tx/src/eip4844Transaction.ts index 31f0726583..a1e43256d9 100644 --- a/packages/tx/src/eip4844Transaction.ts +++ b/packages/tx/src/eip4844Transaction.ts @@ -160,7 +160,7 @@ export class BlobEIP4844Transaction extends BaseTransaction maxInitCodeSize) { throw new Error( `the initcode size of this transaction is too large: it is ${length} while the max is ${common.param( - 'vm', 'maxInitCodeSize' )}` ) @@ -114,8 +113,8 @@ export class AccessLists { } public static getDataFeeEIP2930(accessList: AccessListBytes, common: Common): number { - const accessListStorageKeyCost = common.param('gasPrices', 'accessListStorageKeyCost') - const accessListAddressCost = common.param('gasPrices', 'accessListAddressCost') + const accessListStorageKeyCost = common.param('accessListStorageKeyGas') + const accessListAddressCost = common.param('accessListAddressGas') let slots = 0 for (let index = 0; index < accessList.length; index++) { @@ -216,7 +215,7 @@ export class AuthorizationLists { } public static getDataFeeEIP7702(authorityList: AuthorizationListBytes, common: Common): number { - const perAuthBaseCost = common.param('gasPrices', 'perAuthBaseCost') + const perAuthBaseCost = common.param('perAuthBaseGas') return authorityList.length * Number(perAuthBaseCost) } } diff --git a/packages/tx/test/eip3860.spec.ts b/packages/tx/test/eip3860.spec.ts index 4125d39807..c8bc64fefe 100644 --- a/packages/tx/test/eip3860.spec.ts +++ b/packages/tx/test/eip3860.spec.ts @@ -10,7 +10,7 @@ const common = new Common({ eips: [3860, 4844, 4895], }) -const maxInitCodeSize = common.param('vm', 'maxInitCodeSize') +const maxInitCodeSize = common.param('maxInitCodeSize') const txTypes = [ TransactionType.Legacy, TransactionType.AccessListEIP2930, diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index 63199482ce..b4c0faad44 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -475,14 +475,12 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) // Cost should be: // Base fee + 2*TxDataNonZero + TxDataZero + AccessListAddressCost + AccessListSlotCost - const txDataZero: number = Number(common.param('gasPrices', 'txDataZero')) - const txDataNonZero: number = Number(common.param('gasPrices', 'txDataNonZero')) - const accessListStorageKeyCost: number = Number( - common.param('gasPrices', 'accessListStorageKeyCost') - ) - const accessListAddressCost: number = Number(common.param('gasPrices', 'accessListAddressCost')) - const baseFee: number = Number(common.param('gasPrices', 'tx')) - const creationFee: number = Number(common.param('gasPrices', 'txCreation')) + const txDataZero: number = Number(common.param('txDataZeroGas')) + const txDataNonZero: number = Number(common.param('txDataNonZeroGas')) + const accessListStorageKeyCost: number = Number(common.param('accessListStorageKeyGas')) + const accessListAddressCost: number = Number(common.param('accessListAddressGas')) + const baseFee: number = Number(common.param('txGas')) + const creationFee: number = Number(common.param('txCreationGas')) assert.ok( tx.getBaseFee() === diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 28b034dc60..06742865dd 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -99,7 +99,7 @@ export class BlockBuilder { typeof this.headerData.baseFeePerGas === 'undefined' ) { if (this.headerData.number === vm.common.hardforkBlock(Hardfork.London)) { - this.headerData.baseFeePerGas = vm.common.param('gasConfig', 'initialBaseFee') + this.headerData.baseFeePerGas = vm.common.param('initialBaseFee') } else { this.headerData.baseFeePerGas = opts.parentBlock.header.calcNextBaseFee() } @@ -176,7 +176,7 @@ export class BlockBuilder { * Adds the block miner reward to the coinbase account. */ private async rewardMiner() { - const minerReward = this.vm.common.param('pow', 'minerReward') + const minerReward = this.vm.common.param('minerReward') const reward = calculateMinerReward(minerReward, 0) const coinbase = this.headerData.coinbase !== undefined @@ -223,8 +223,8 @@ export class BlockBuilder { // cannot be greater than the remaining gas in the block const blockGasLimit = toType(this.headerData.gasLimit, TypeOutput.BigInt) - const blobGasLimit = this.vm.common.param('gasConfig', 'maxblobGasPerBlock') - const blobGasPerBlob = this.vm.common.param('gasConfig', 'blobGasPerBlob') + const blobGasLimit = this.vm.common.param('maxblobGasPerBlock') + const blobGasPerBlob = this.vm.common.param('blobGasPerBlob') const blockGasRemaining = blockGasLimit - this.gasUsed if (tx.gasLimit > blockGasRemaining) { diff --git a/packages/vm/src/requests.ts b/packages/vm/src/requests.ts index b8e095afbe..36c4214262 100644 --- a/packages/vm/src/requests.ts +++ b/packages/vm/src/requests.ts @@ -62,7 +62,7 @@ const accumulateEIP7002Requests = async ( ): Promise => { // Partial withdrawals logic const addressBytes = setLengthLeft( - bigIntToBytes(vm.common.param('vm', 'withdrawalRequestPredeployAddress')), + bigIntToBytes(vm.common.param('withdrawalRequestPredeployAddress')), 20 ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) @@ -75,7 +75,7 @@ const accumulateEIP7002Requests = async ( ) } - const systemAddressBytes = bigIntToAddressBytes(vm.common.param('vm', 'systemAddress')) + const systemAddressBytes = bigIntToAddressBytes(vm.common.param('systemAddress')) const systemAddress = Address.fromString(bytesToHex(systemAddressBytes)) const originalAccount = await vm.stateManager.getAccount(systemAddress) @@ -112,7 +112,7 @@ const accumulateEIP7251Requests = async ( ): Promise => { // Partial withdrawals logic const addressBytes = setLengthLeft( - bigIntToBytes(vm.common.param('vm', 'consolidationRequestPredeployAddress')), + bigIntToBytes(vm.common.param('consolidationRequestPredeployAddress')), 20 ) const consolidationsAddress = Address.fromString(bytesToHex(addressBytes)) @@ -125,7 +125,7 @@ const accumulateEIP7251Requests = async ( ) } - const systemAddressBytes = bigIntToAddressBytes(vm.common.param('vm', 'systemAddress')) + const systemAddressBytes = bigIntToAddressBytes(vm.common.param('systemAddress')) const systemAddress = Address.fromString(bytesToHex(systemAddressBytes)) const originalAccount = await vm.stateManager.getAccount(systemAddress) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 8d43cb381f..5365822f59 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -499,10 +499,8 @@ export async function accumulateParentBlockHash( if (!vm.common.isActivatedEIP(2935)) { throw new Error('Cannot call `accumulateParentBlockHash`: EIP 2935 is not active') } - const historyAddress = new Address( - bigIntToAddressBytes(vm.common.param('vm', 'historyStorageAddress')) - ) - const historyServeWindow = vm.common.param('vm', 'historyServeWindow') + const historyAddress = new Address(bigIntToAddressBytes(vm.common.param('historyStorageAddress'))) + const historyServeWindow = vm.common.param('historyServeWindow') // getAccount with historyAddress will throw error as witnesses are not bundeled // but we need to put account so as to query later for slot @@ -542,7 +540,7 @@ export async function accumulateParentBeaconBlockRoot(vm: VM, root: Uint8Array, throw new Error('Cannot call `accumulateParentBeaconBlockRoot`: EIP 4788 is not active') } // Save the parentBeaconBlockRoot to the beaconroot stateful precompile ring buffers - const historicalRootsLength = BigInt(vm.common.param('vm', 'historicalRootsLength')) + const historicalRootsLength = BigInt(vm.common.param('historicalRootsLength')) const timestampIndex = timestamp % historicalRootsLength const timestampExtended = timestampIndex + historicalRootsLength @@ -614,7 +612,7 @@ async function applyTransactions(vm: VM, block: Block, opts: RunBlockOpts) { let maxGasLimit if (vm.common.isActivatedEIP(1559)) { - maxGasLimit = block.header.gasLimit * vm.common.param('gasConfig', 'elasticityMultiplier') + maxGasLimit = block.header.gasLimit * vm.common.param('elasticityMultiplier') } else { maxGasLimit = block.header.gasLimit } @@ -693,7 +691,7 @@ async function assignBlockRewards(vm: VM, block: Block): Promise { if (vm.DEBUG) { debug(`Assign block rewards`) } - const minerReward = vm.common.param('pow', 'minerReward') + const minerReward = vm.common.param('minerReward') const ommers = block.uncleHeaders // Reward ommers for (const ommer of ommers) { diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 8d7c5b2c32..4ea07f89c4 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -369,7 +369,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { // the signer must be able to afford the transaction // assert signer(tx).balance >= tx.message.gas * tx.message.max_fee_per_gas + get_total_data_gas(tx) * tx.message.max_fee_per_data_gas const castTx = tx as BlobEIP4844Transaction - totalblobGas = castTx.common.param('gasConfig', 'blobGasPerBlob') * BigInt(castTx.numBlobs()) + totalblobGas = castTx.common.param('blobGasPerBlob') * BigInt(castTx.numBlobs()) maxCost += totalblobGas * castTx.maxFeePerBlobGas // 4844 minimum blobGas price check @@ -589,7 +589,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { // Process any gas refund let gasRefund = results.execResult.gasRefund ?? BIGINT_0 results.gasRefund = gasRefund - const maxRefundQuotient = vm.common.param('gasConfig', 'maxRefundQuotient') + const maxRefundQuotient = vm.common.param('maxRefundQuotient') if (gasRefund !== BIGINT_0) { const maxRefund = results.totalGasSpent / maxRefundQuotient gasRefund = gasRefund < maxRefund ? gasRefund : maxRefund 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 34d4bd2824..49a2f317ed 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 @@ -204,7 +204,7 @@ describe('EIP 2935: historical block hashes', () => { const commonGetHistoryServeWindow = eip2935ActiveAtCommon(0, historyAddressBigInt) commonGetHistoryServeWindow.setEIPs([2935]) const common = eip2935ActiveAtCommon(blocksActivation, historyAddressBigInt) - const historyServeWindow = commonGetHistoryServeWindow.param('vm', 'historyServeWindow') + const historyServeWindow = commonGetHistoryServeWindow.param('historyServeWindow') const blockchain = await createBlockchain({ common, diff --git a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts index 90651d883c..2da4678de8 100644 --- a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts @@ -533,9 +533,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const gasBigInt = bytesToBigInt(gasUsed) const preGas = - gas! - - common.param('gasPrices', 'warmstorageread')! - - common.param('gasPrices', 'coldaccountaccess')! + gas! - common.param('warmstoragereadGas')! - common.param('coldaccountaccessGas')! const expected = preGas - preGas / 64n - 2n assert.equal(gasBigInt, expected, 'forwarded max call gas') }) @@ -575,7 +573,7 @@ describe('EIP-3074 AUTHCALL', () => { hexToBytes(`0x${'00'.repeat(31)}01`) ) const gasBigInt = bytesToBigInt(gasUsed) - const preGas = gas! - common.param('gasPrices', 'warmstorageread')! + const preGas = gas! - common.param('warmstoragereadGas')! const expected = preGas - preGas / 64n - 2n assert.equal(gasBigInt, expected, 'forwarded max call gas') }) @@ -617,10 +615,10 @@ describe('EIP-3074 AUTHCALL', () => { const gasBigInt = gas! - gasAfterCall! const expected = - common.param('gasPrices', 'coldaccountaccess')! + - common.param('gasPrices', 'warmstorageread')! + - common.param('gasPrices', 'callNewAccount')! + - common.param('gasPrices', 'authcallValueTransfer')! + common.param('coldaccountaccessGas')! + + common.param('warmstoragereadGas')! + + common.param('callNewAccountGas')! + + common.param('authcallValueTransferGas')! assert.equal(gasBigInt, expected, 'forwarded max call gas') }) @@ -666,9 +664,9 @@ describe('EIP-3074 AUTHCALL', () => { const gasBigInt = bytesToBigInt(gasUsed) const preGas = gas! - - common.param('gasPrices', 'warmstorageread')! - - common.param('gasPrices', 'authcallValueTransfer')! - - common.param('gasPrices', 'coldaccountaccess')! + common.param('warmstoragereadGas')! - + common.param('authcallValueTransferGas')! - + common.param('coldaccountaccessGas')! const expected = preGas - preGas / 64n - 2n assert.equal(gasBigInt, expected, 'forwarded max call gas') diff --git a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts index 6bdba6452c..d6babfbca1 100644 --- a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts @@ -67,9 +67,7 @@ describe('EIP 3651 tests', () => { ) const result2 = await runTx(vm2, { block, tx, skipHardForkValidation: true }) - const expectedDiff = - common.param('gasPrices', 'coldaccountaccess')! - - common.param('gasPrices', 'warmstorageread')! + const expectedDiff = common.param('coldaccountaccessGas')! - common.param('warmstoragereadGas')! assert.equal( result2.totalGasSpent - result.totalGasSpent, expectedDiff, diff --git a/packages/vm/test/api/EIPs/eip-3855.spec.ts b/packages/vm/test/api/EIPs/eip-3855.spec.ts index 13bf664890..477dc6498c 100644 --- a/packages/vm/test/api/EIPs/eip-3855.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3855.spec.ts @@ -29,7 +29,7 @@ describe('EIP 3855 tests', () => { assert.ok(stack!.length === 1) assert.equal(stack![0], BigInt(0)) - assert.equal(result.executionGasUsed, common.param('gasPrices', 'push0')) + assert.equal(result.executionGasUsed, common.param('push0Gas')) }) it('should correctly use push0 to create a stack with stack limit length', async () => { @@ -39,7 +39,7 @@ describe('EIP 3855 tests', () => { stack = e.stack }) - const depth = Number(common.param('vm', 'stackLimit')) + const depth = Number(common.param('stackLimit')) const result = await vm.evm.runCode!({ code: hexToBytes(`0x${'5F'.repeat(depth)}00`), @@ -52,13 +52,13 @@ describe('EIP 3855 tests', () => { assert.fail('stack element is not 0') } } - assert.equal(result.executionGasUsed, common.param('gasPrices', 'push0')! * BigInt(depth)) + assert.equal(result.executionGasUsed, common.param('push0Gas')! * BigInt(depth)) }) it('should correctly use push0 to create a stack with stack limit + 1 length', async () => { const vm = await VM.create({ common }) - const depth = Number(common.param('vm', 'stackLimit')!) + 1 + const depth = Number(common.param('stackLimit')!) + 1 const result = await vm.evm.runCode!({ code: hexToBytes(`0x${'5F'.repeat(depth)}`), diff --git a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts index 7e5ff94266..a6fd6abaf4 100644 --- a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts @@ -90,7 +90,7 @@ describe('EIP4844 tests', () => { 'blob transaction should be same' ) - const blobGasPerBlob = common.param('gasConfig', 'blobGasPerBlob') + const blobGasPerBlob = common.param('blobGasPerBlob') assert.equal(block.header.blobGasUsed, blobGasPerBlob, 'blob gas used for 1 blob should match') // block should successfully execute with VM.runBlock and have same outputs diff --git a/packages/vm/test/api/EIPs/eip-7002.spec.ts b/packages/vm/test/api/EIPs/eip-7002.spec.ts index 6d70872d06..5612e5de29 100644 --- a/packages/vm/test/api/EIPs/eip-7002.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7002.spec.ts @@ -52,7 +52,7 @@ const amountBytes = setLengthLeft(bigIntToBytes(amount), 8) function generateTx(nonce: bigint) { const addressBytes = setLengthLeft( - bigIntToBytes(common.param('vm', 'withdrawalRequestPredeployAddress')), + bigIntToBytes(common.param('withdrawalRequestPredeployAddress')), 20 ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index 7d824395cf..d4b9d7e6a5 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -156,7 +156,7 @@ describe('VM -> common (chain, HFs, EIPs)', () => { let common = createCustomCommon({ chainId: 3 }) common.setHardfork(Hardfork.Byzantium) let vm = await VM.create({ common }) - assert.equal(vm.common.param('gasPrices', 'ecAdd'), BigInt(500)) + assert.equal(vm.common.param('ecAddGas'), BigInt(500)) try { common = new Common({ chain: 'mainchain', hardfork: Hardfork.Homestead }) @@ -313,7 +313,7 @@ describe('VM -> setHardfork, state (deprecated), blockchain', () => { const diff = resultNotActivated.execResult.executionGasUsed - resultActivated.execResult.executionGasUsed - const expected = common.param('gasPrices', 'callNewAccount') + const expected = common.param('callNewAccountGas') assert.equal(diff, expected, 'precompiles are activated') }) From 5d4b2b2f881852a8c1c28392c5c85aa82c69fd09 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Tue, 23 Jul 2024 21:41:33 +0200 Subject: [PATCH 16/58] Tx: move and rename constructors (#3533) * tx: move files into dirs * tx: remove static constructors * tx: export new constructors * monorepo: rename all tx constructors * tx: fix tests * fix examples * fix tx examples * add 4844 docs Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> * tx: update dev docs --------- Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> --- packages/block/examples/4844.ts | 10 +- packages/block/test/block.spec.ts | 6 +- packages/block/test/eip1559block.spec.ts | 4 +- packages/block/test/eip4844block.spec.ts | 6 +- .../client/src/net/protocol/ethprotocol.ts | 3 +- packages/client/src/rpc/modules/eth.ts | 4 +- .../integration/fullethereumservice.spec.ts | 4 +- packages/client/test/miner/miner.spec.ts | 15 +- .../client/test/miner/pendingBlock.spec.ts | 18 +- .../test/net/protocol/ethprotocol.spec.ts | 4 +- .../client/test/rpc/debug/getRawBlock.spec.ts | 8 +- .../test/rpc/debug/getRawHeader.spec.ts | 8 +- .../test/rpc/debug/getRawReceipts.spec.ts | 12 +- .../test/rpc/debug/getRawTransaction.spec.ts | 6 +- .../test/rpc/engine/newPayloadV1.spec.ts | 8 +- .../test/rpc/engine/newPayloadV2.spec.ts | 6 +- packages/client/test/rpc/eth/call.spec.ts | 6 +- .../client/test/rpc/eth/estimateGas.spec.ts | 6 +- packages/client/test/rpc/eth/gasPrice.spec.ts | 22 +- .../client/test/rpc/eth/getBalance.spec.ts | 4 +- .../test/rpc/eth/getBlockByNumber.spec.ts | 8 +- .../test/rpc/eth/getBlockReceipts.spec.ts | 16 +- .../getBlockTransactionCountByNumber.spec.ts | 16 +- packages/client/test/rpc/eth/getCode.spec.ts | 4 +- packages/client/test/rpc/eth/getLogs.spec.ts | 10 +- packages/client/test/rpc/eth/getProof.spec.ts | 6 +- .../client/test/rpc/eth/getStorageAt.spec.ts | 4 +- .../getTransactionByBlockHashAndIndex.spec.ts | 6 +- .../test/rpc/eth/getTransactionByHash.spec.ts | 6 +- .../test/rpc/eth/getTransactionCount.spec.ts | 4 +- .../rpc/eth/getTransactionReceipt.spec.ts | 12 +- .../test/rpc/eth/sendRawTransaction.spec.ts | 18 +- packages/client/test/rpc/mockBlockchain.ts | 8 +- packages/client/test/sim/simutils.ts | 8 +- packages/client/test/sim/txGenerator.ts | 4 +- packages/client/test/sync/txpool.spec.ts | 24 +- packages/client/test/util/wasmCrypto.spec.ts | 6 +- .../statemanager/test/rpcStateManager.spec.ts | 4 +- packages/tx/examples/accessListTx.ts | 4 +- packages/tx/examples/blobTx.ts | 4 +- packages/tx/examples/custom-chain-id-tx.ts | 6 +- packages/tx/examples/custom-chain-tx.ts | 6 +- packages/tx/examples/l2tx.ts | 6 +- packages/tx/examples/legacyTx.ts | 4 +- packages/tx/examples/londonTx.ts | 4 +- packages/tx/examples/transactions.ts | 6 +- packages/tx/src/1559/constructors.ts | 103 ++++++ packages/tx/src/1559/index.ts | 2 + .../src/{eip1559Transaction.ts => 1559/tx.ts} | 121 +------ packages/tx/src/2930/constructors.ts | 88 +++++ packages/tx/src/2930/index.ts | 2 + .../src/{eip2930Transaction.ts => 2930/tx.ts} | 107 +----- packages/tx/src/4844/constructors.ts | 327 +++++++++++++++++ packages/tx/src/4844/index.ts | 2 + .../src/{eip4844Transaction.ts => 4844/tx.ts} | 334 +----------------- packages/tx/src/7702/constructors.ts | 102 ++++++ packages/tx/src/7702/index.ts | 2 + .../src/{eip7702Transaction.ts => 7702/tx.ts} | 122 +------ packages/tx/src/baseTransaction.ts | 25 -- packages/tx/src/index.ts | 15 +- packages/tx/src/legacy/constructors.ts | 69 ++++ packages/tx/src/legacy/index.ts | 2 + .../{legacyTransaction.ts => legacy/tx.ts} | 81 +---- packages/tx/src/transactionFactory.ts | 38 +- packages/tx/src/types.ts | 10 +- packages/tx/src/util.ts | 25 ++ packages/tx/test/base.spec.ts | 72 ++-- packages/tx/test/eip1559.spec.ts | 34 +- packages/tx/test/eip4844.spec.ts | 76 ++-- packages/tx/test/eip7702.spec.ts | 22 +- packages/tx/test/inputValue.spec.ts | 23 +- packages/tx/test/legacy.spec.ts | 116 +++--- packages/tx/test/transactionFactory.spec.ts | 12 +- packages/tx/test/typedTxsAndEIP2930.spec.ts | 95 ++--- packages/vm/examples/buildBlock.ts | 4 +- packages/vm/examples/run-solidity-contract.ts | 26 +- packages/vm/examples/runTx.ts | 6 +- packages/vm/src/buildBlock.ts | 4 +- packages/vm/test/api/EIPs/eip-1153.spec.ts | 10 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 6 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 6 +- .../eip-2935-historical-block-hashes.spec.ts | 6 +- .../test/api/EIPs/eip-3074-authcall.spec.ts | 42 +-- packages/vm/test/api/EIPs/eip-3529.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-3541.spec.ts | 16 +- packages/vm/test/api/EIPs/eip-3607.spec.ts | 6 +- .../api/EIPs/eip-3651-warm-coinbase.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-3860.spec.ts | 4 +- .../vm/test/api/EIPs/eip-4844-blobs.spec.ts | 4 +- .../api/EIPs/eip-4895-withdrawals.spec.ts | 4 +- .../eip-6780-selfdestruct-same-tx.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-7002.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-7702.spec.ts | 8 +- packages/vm/test/api/buildBlock.spec.ts | 22 +- packages/vm/test/api/events.spec.ts | 14 +- packages/vm/test/api/runBlock.spec.ts | 24 +- packages/vm/test/api/runTx.spec.ts | 17 +- packages/vm/test/api/types.spec.ts | 6 +- .../vm/test/retesteth/transition-child.cts | 6 +- packages/vm/test/util.ts | 29 +- 100 files changed, 1388 insertions(+), 1295 deletions(-) create mode 100644 packages/tx/src/1559/constructors.ts create mode 100644 packages/tx/src/1559/index.ts rename packages/tx/src/{eip1559Transaction.ts => 1559/tx.ts} (71%) create mode 100644 packages/tx/src/2930/constructors.ts create mode 100644 packages/tx/src/2930/index.ts rename packages/tx/src/{eip2930Transaction.ts => 2930/tx.ts} (70%) create mode 100644 packages/tx/src/4844/constructors.ts create mode 100644 packages/tx/src/4844/index.ts rename packages/tx/src/{eip4844Transaction.ts => 4844/tx.ts} (51%) create mode 100644 packages/tx/src/7702/constructors.ts create mode 100644 packages/tx/src/7702/index.ts rename packages/tx/src/{eip7702Transaction.ts => 7702/tx.ts} (73%) create mode 100644 packages/tx/src/legacy/constructors.ts create mode 100644 packages/tx/src/legacy/index.ts rename packages/tx/src/{legacyTransaction.ts => legacy/tx.ts} (81%) diff --git a/packages/block/examples/4844.ts b/packages/block/examples/4844.ts index 7039c84189..a73cb682ba 100644 --- a/packages/block/examples/4844.ts +++ b/packages/block/examples/4844.ts @@ -1,9 +1,9 @@ -import { Common, Chain, Hardfork } from '@ethereumjs/common' -import { Block, createBlockFromBlockData } from '@ethereumjs/block' -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { createBlockFromBlockData } from '@ethereumjs/block' +import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { create4844BlobTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' -import { loadKZG } from 'kzg-wasm' import { randomBytes } from 'crypto' +import { loadKZG } from 'kzg-wasm' const main = async () => { const kzg = await loadKZG() @@ -15,7 +15,7 @@ const main = async () => { kzg, }, }) - const blobTx = BlobEIP4844Transaction.fromTxData( + const blobTx = create4844BlobTx( { blobsData: ['myFirstBlob'], to: Address.fromPrivateKey(randomBytes(32)) }, { common } ) diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index 8bccdd1d63..9cf52e6f24 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { KECCAK256_RLP_ARRAY, bytesToHex, @@ -199,7 +199,7 @@ describe('[Block]: block functions', () => { }) it('should test transaction validation - transaction not signed', async () => { - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: 53000, gasPrice: 7, }) @@ -252,7 +252,7 @@ describe('[Block]: block functions', () => { }) it('should test data integrity', async () => { - const unsignedTx = LegacyTransaction.fromTxData({}) + const unsignedTx = createLegacyTx({}) const txRoot = await genTransactionsTrieRoot([unsignedTx]) let block = createBlockFromBlockData({ diff --git a/packages/block/test/eip1559block.spec.ts b/packages/block/test/eip1559block.spec.ts index fcd8355440..878a5907f5 100644 --- a/packages/block/test/eip1559block.spec.ts +++ b/packages/block/test/eip1559block.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -407,7 +407,7 @@ describe('EIP1559 tests', () => { }) it('Header -> validateTransactions() -> tx', async () => { - const transaction = FeeMarketEIP1559Transaction.fromTxData( + const transaction = create1559FeeMarketTx( { maxFeePerGas: BigInt(0), maxPriorityFeePerGas: BigInt(0), diff --git a/packages/block/test/eip4844block.spec.ts b/packages/block/test/eip4844block.spec.ts index d953090041..c3c316218e 100644 --- a/packages/block/test/eip4844block.spec.ts +++ b/packages/block/test/eip4844block.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { create4844BlobTx } from '@ethereumjs/tx' import { blobsToCommitments, commitmentsToVersionedHashes, @@ -171,7 +171,7 @@ describe('transaction validation tests', () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) - const tx1 = BlobEIP4844Transaction.fromTxData( + const tx1 = create4844BlobTx( { blobVersionedHashes, blobs, @@ -182,7 +182,7 @@ describe('transaction validation tests', () => { }, { common } ).sign(randomBytes(32)) - const tx2 = BlobEIP4844Transaction.fromTxData( + const tx2 = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/client/src/net/protocol/ethprotocol.ts b/packages/client/src/net/protocol/ethprotocol.ts index bc94fec3dc..b0cbdebd2e 100644 --- a/packages/client/src/net/protocol/ethprotocol.ts +++ b/packages/client/src/net/protocol/ethprotocol.ts @@ -8,6 +8,7 @@ import { Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { BlobEIP4844Transaction, + create4844BlobTxFromSerializedNetworkWrapper, createTxFromBlockBodyData, createTxFromSerializedData, isAccessListEIP2930Tx, @@ -295,7 +296,7 @@ export class EthProtocol extends Protocol { txs.map((txData) => { // Blob transactions are deserialized with network wrapper if (txData[0] === 3) { - return BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txData, { common }) + return create4844BlobTxFromSerializedNetworkWrapper(txData, { common }) } else { return createTxFromBlockBodyData(txData, { common }) } diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 67d2779a8d..9afdf2c69b 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -1,8 +1,8 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' import { - BlobEIP4844Transaction, Capability, + create4844BlobTxFromSerializedNetworkWrapper, createTxFromSerializedData, createTxFromTxData, } from '@ethereumjs/tx' @@ -1162,7 +1162,7 @@ export class Eth { const txBuf = hexToBytes(serializedTx) if (txBuf[0] === 0x03) { // Blob Transactions sent over RPC are expected to be in Network Wrapper format - tx = BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txBuf, { common }) + tx = create4844BlobTxFromSerializedNetworkWrapper(txBuf, { common }) const blobGasLimit = common.param('maxblobGasPerBlock') const blobGasPerBlob = common.param('blobGasPerBlob') diff --git a/packages/client/test/integration/fullethereumservice.spec.ts b/packages/client/test/integration/fullethereumservice.spec.ts index 8a8f0b1612..15d6427517 100644 --- a/packages/client/test/integration/fullethereumservice.spec.ts +++ b/packages/client/test/integration/fullethereumservice.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTxFromRLP } from '@ethereumjs/tx' import { Account, bytesToHex, equalsBytes, hexToBytes, toBytes } from '@ethereumjs/util' import * as td from 'testdouble' import { assert, describe, it } from 'vitest' @@ -94,7 +94,7 @@ describe( const txData = '0x02f901100180843b9aca00843b9aca008402625a0094cccccccccccccccccccccccccccccccccccccccc830186a0b8441a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0afb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9a0479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64' - const tx = FeeMarketEIP1559Transaction.fromSerializedTx(toBytes(txData)) + const tx = create1559FeeMarketTxFromRLP(toBytes(txData)) await service.execution.vm.stateManager.putAccount( tx.getSenderAddress(), new Account(BigInt(0), BigInt('40000000000100000')) diff --git a/packages/client/test/miner/miner.spec.ts b/packages/client/test/miner/miner.spec.ts index 9373ae032c..e3868c7cb7 100644 --- a/packages/client/test/miner/miner.spec.ts +++ b/packages/client/test/miner/miner.spec.ts @@ -7,7 +7,7 @@ import { createCustomCommon, } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createLegacyTx } from '@ethereumjs/tx' import { Address, equalsBytes, hexToBytes } from '@ethereumjs/util' import { AbstractLevel } from 'abstract-level' // import { keccak256 } from 'ethereum-cryptography/keccak' @@ -177,7 +177,7 @@ const createTx = ( to: to.address, value, } - const tx = LegacyTransaction.fromTxData(txData, { common }) + const tx = createLegacyTx(txData, { common }) const signedTx = tx.sign(from.privateKey) return signedTx } @@ -454,10 +454,9 @@ describe('assembleBlocks() -> should not include tx under the baseFee', async () // the default block baseFee will be 7 // add tx with maxFeePerGas of 6 - const tx = FeeMarketEIP1559Transaction.fromTxData( - { to: B.address, maxFeePerGas: 6 }, - { common } - ).sign(A.privateKey) + const tx = create1559FeeMarketTx({ to: B.address, maxFeePerGas: 6 }, { common }).sign( + A.privateKey + ) try { await txPool.add(tx, true) } catch { @@ -508,11 +507,11 @@ describe("assembleBlocks() -> should stop assembling a block after it's full", a // add txs const data = '0xfe' // INVALID opcode, consumes all gas - const tx1FillsBlockGasLimit = LegacyTransaction.fromTxData( + const tx1FillsBlockGasLimit = createLegacyTx( { gasLimit: gasLimit - 1, data, gasPrice: BigInt('1000000000') }, { common: customCommon } ).sign(A.privateKey) - const tx2ExceedsBlockGasLimit = LegacyTransaction.fromTxData( + const tx2ExceedsBlockGasLimit = createLegacyTx( { gasLimit: 21000, to: B.address, nonce: 1, gasPrice: BigInt('1000000000') }, { common: customCommon } ).sign(A.privateKey) diff --git a/packages/client/test/miner/pendingBlock.spec.ts b/packages/client/test/miner/pendingBlock.spec.ts index f280c8f653..fd4f87ca1b 100644 --- a/packages/client/test/miner/pendingBlock.spec.ts +++ b/packages/client/test/miner/pendingBlock.spec.ts @@ -6,11 +6,7 @@ import { createCommonFromGethGenesis, } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { - BlobEIP4844Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, -} from '@ethereumjs/tx' +import { create1559FeeMarketTx, create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { Account, Address, @@ -120,7 +116,7 @@ describe('[PendingBlock]', async () => { to: to.address, value, } - const tx = LegacyTransaction.fromTxData(txData, { common }) + const tx = createLegacyTx(txData, { common }) const signedTx = tx.sign(from.privateKey) return signedTx } @@ -239,7 +235,7 @@ describe('[PendingBlock]', async () => { await txPool.add(txA022) // This tx will not be added since its too big to fit - const txA03 = LegacyTransaction.fromTxData( + const txA03 = createLegacyTx( { data: '0xFE', // INVALID opcode, uses all gas gasLimit: 10000000, @@ -283,7 +279,7 @@ describe('[PendingBlock]', async () => { await setBalance(vm, A.address, BigInt(5000000000000000)) await txPool.add(txA01) await txPool.add(txA02) - const txA03 = LegacyTransaction.fromTxData( + const txA03 = createLegacyTx( { data: '0xFE', // INVALID opcode, uses all gas gasLimit: 10000000, @@ -378,7 +374,7 @@ describe('[PendingBlock]', async () => { // Create 3 txs with 2 blobs each so that only 2 of them can be included in a build for (let x = 0; x <= 2; x++) { - const txA01 = BlobEIP4844Transaction.fromTxData( + const txA01 = create4844BlobTx( { blobVersionedHashes: [ ...blobVersionedHashes, @@ -401,7 +397,7 @@ describe('[PendingBlock]', async () => { } // Add one other normal tx for nonce 3 which should also be not included in the build - const txNorm = FeeMarketEIP1559Transaction.fromTxData( + const txNorm = create1559FeeMarketTx( { gasLimit: 0xffffffn, maxFeePerGas: 1000000000n, @@ -456,7 +452,7 @@ describe('[PendingBlock]', async () => { const proofs = blobsToProofs(kzg, blobs, commitments) // create a tx with missing blob data which should be excluded from the build - const missingBlobTx = BlobEIP4844Transaction.fromTxData( + const missingBlobTx = create4844BlobTx( { blobVersionedHashes, kzgCommitments: commitments, diff --git a/packages/client/test/net/protocol/ethprotocol.spec.ts b/packages/client/test/net/protocol/ethprotocol.spec.ts index 82c423e52e..01dd00fe1e 100644 --- a/packages/client/test/net/protocol/ethprotocol.spec.ts +++ b/packages/client/test/net/protocol/ethprotocol.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' -import { FeeMarketEIP1559Transaction, TransactionType, createTxFromTxData } from '@ethereumjs/tx' +import { TransactionType, create1559FeeMarketTx, createTxFromTxData } from '@ethereumjs/tx' import { Address, bigIntToBytes, bytesToBigInt, hexToBytes, randomBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -122,7 +122,7 @@ describe('[EthProtocol]', () => { const p = new EthProtocol({ config, chain }) chain.config.chainCommon.setHardfork(Hardfork.London) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 8, diff --git a/packages/client/test/rpc/debug/getRawBlock.spec.ts b/packages/client/test/rpc/debug/getRawBlock.spec.ts index b4d32790e1..86102288a2 100644 --- a/packages/client/test/rpc/debug/getRawBlock.spec.ts +++ b/packages/client/test/rpc/debug/getRawBlock.spec.ts @@ -1,6 +1,6 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' -import { BlobEIP4844Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -13,9 +13,9 @@ const kzg = await loadKZG() const common = createCustomCommon({ chainId: 1 }, { customCrypto: { kzg } }) common.setHardfork('cancun') -const mockedTx1 = LegacyTransaction.fromTxData({}).sign(dummy.privKey) -const mockedTx2 = LegacyTransaction.fromTxData({ nonce: 1 }).sign(dummy.privKey) -const mockedBlobTx3 = BlobEIP4844Transaction.fromTxData( +const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) +const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) +const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, { common } ).sign(dummy.privKey) diff --git a/packages/client/test/rpc/debug/getRawHeader.spec.ts b/packages/client/test/rpc/debug/getRawHeader.spec.ts index 409423edad..27a2a7e67e 100644 --- a/packages/client/test/rpc/debug/getRawHeader.spec.ts +++ b/packages/client/test/rpc/debug/getRawHeader.spec.ts @@ -1,6 +1,6 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' -import { BlobEIP4844Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -13,9 +13,9 @@ const kzg = await loadKZG() const common = createCustomCommon({ chainId: 1 }, { customCrypto: { kzg } }) common.setHardfork('cancun') -const mockedTx1 = LegacyTransaction.fromTxData({}).sign(dummy.privKey) -const mockedTx2 = LegacyTransaction.fromTxData({ nonce: 1 }).sign(dummy.privKey) -const mockedBlobTx3 = BlobEIP4844Transaction.fromTxData( +const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) +const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) +const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, { common } ).sign(dummy.privKey) diff --git a/packages/client/test/rpc/debug/getRawReceipts.spec.ts b/packages/client/test/rpc/debug/getRawReceipts.spec.ts index 87159a06cc..7d23ce7775 100644 --- a/packages/client/test/rpc/debug/getRawReceipts.spec.ts +++ b/packages/client/test/rpc/debug/getRawReceipts.spec.ts @@ -1,9 +1,5 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { - BlobEIP4844Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, -} from '@ethereumjs/tx' +import { create1559FeeMarketTx, create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { bigIntToHex, blobsToCommitments, @@ -36,7 +32,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain(pow, 'pow') const rpc = getRpcClient(server) // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, @@ -64,7 +60,7 @@ describe(method, () => { ) const rpc = getRpcClient(server) // construct tx - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, @@ -125,7 +121,7 @@ describe(method, () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobs.map((blob, ctx) => kzg.computeBlobKzgProof(blob, commitments[ctx])) - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/client/test/rpc/debug/getRawTransaction.spec.ts b/packages/client/test/rpc/debug/getRawTransaction.spec.ts index 8811fec759..19b65e6aac 100644 --- a/packages/client/test/rpc/debug/getRawTransaction.spec.ts +++ b/packages/client/test/rpc/debug/getRawTransaction.spec.ts @@ -1,4 +1,4 @@ -import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createLegacyTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -18,7 +18,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain(pow, 'pow', { txLookupLimit: 1 }) const rpc = getRpcClient(server) // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) @@ -42,7 +42,7 @@ describe(method, () => { ) const rpc = getRpcClient(server) // construct tx - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, diff --git a/packages/client/test/rpc/engine/newPayloadV1.spec.ts b/packages/client/test/rpc/engine/newPayloadV1.spec.ts index de3a725a33..d2b6754909 100644 --- a/packages/client/test/rpc/engine/newPayloadV1.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV1.spec.ts @@ -1,5 +1,5 @@ import { BlockHeader } from '@ethereumjs/block' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes, zeros } from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' @@ -155,7 +155,7 @@ describe(method, () => { chain.config.logger.silent = true // Let's mock a non-signed transaction so execution fails - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 21_000, maxFeePerGas: 10, @@ -195,7 +195,7 @@ describe(method, () => { const { server, common } = await setupChain(newGenesisJSON, 'post-merge', { engine: true }) const rpc = getRpcClient(server) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: '0x7', value: 6, @@ -238,7 +238,7 @@ describe(method, () => { }) const rpc = getRpcClient(server) const transactions = Array.from({ length: 101 }, (_v, i) => { - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { nonce: i, maxFeePerGas: '0x7', diff --git a/packages/client/test/rpc/engine/newPayloadV2.spec.ts b/packages/client/test/rpc/engine/newPayloadV2.spec.ts index 40c0152e41..16ccb21d08 100644 --- a/packages/client/test/rpc/engine/newPayloadV2.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV2.spec.ts @@ -1,5 +1,5 @@ import { BlockHeader } from '@ethereumjs/block' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes, zeros } from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' @@ -153,7 +153,7 @@ describe(`${method}: call with executionPayloadV1`, () => { chain.config.logger.silent = true // Let's mock a non-signed transaction so execution fails - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 21_000, maxFeePerGas: 10, @@ -192,7 +192,7 @@ describe(`${method}: call with executionPayloadV1`, () => { const { server, common } = await setupChain(newGenesisJSON, 'post-merge', { engine: true }) const rpc = getRpcClient(server) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: '0x7', value: 6, diff --git a/packages/client/test/rpc/eth/call.spec.ts b/packages/client/test/rpc/eth/call.spec.ts index 802ed0639b..e516875ad1 100644 --- a/packages/client/test/rpc/eth/call.spec.ts +++ b/packages/client/test/rpc/eth/call.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bigIntToHex, bytesToHex } from '@ethereumjs/util' import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -51,7 +51,7 @@ describe(method, () => { // construct block with tx const gasLimit = 2000000 - const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit, data }, { common, freeze: false }) tx.getSenderAddress = () => { return address } @@ -83,7 +83,7 @@ describe(method, () => { data: `0x${funcHash}` as PrefixedHexString, gasLimit: bigIntToHex(BigInt(53000)), } - const estimateTx = LegacyTransaction.fromTxData(estimateTxData, { freeze: false }) + const estimateTx = createLegacyTx(estimateTxData, { freeze: false }) estimateTx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index f009406c71..a584855504 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -2,7 +2,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { createCommonFromGethGenesis } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -60,7 +60,7 @@ describe( // construct block with tx const gasLimit = 2000000 - const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit, data }, { common, freeze: false }) tx.getSenderAddress = () => { return address } @@ -93,7 +93,7 @@ describe( gasLimit: bigIntToHex(BigInt(53000)), gasPrice: bigIntToHex(BigInt(1000000000)), } - const estimateTx = LegacyTransaction.fromTxData(estimateTxData, { freeze: false }) + const estimateTx = createLegacyTx(estimateTxData, { freeze: false }) estimateTx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/gasPrice.spec.ts b/packages/client/test/rpc/eth/gasPrice.spec.ts index 9ff204ed90..4516d91d79 100644 --- a/packages/client/test/rpc/eth/gasPrice.spec.ts +++ b/packages/client/test/rpc/eth/gasPrice.spec.ts @@ -1,4 +1,4 @@ -import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createLegacyTx } from '@ethereumjs/tx' import { bigIntToHex, intToHex } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -11,6 +11,8 @@ import { setupChain, } from '../helpers.js' +import type { LegacyTransaction } from '@ethereumjs/tx' + const method = 'eth_gasPrice' describe(method, () => { @@ -19,7 +21,7 @@ describe(method, () => { const rpc = getRpcClient(server) const GAS_PRICE = 100 // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 21000, gasPrice: GAS_PRICE, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) @@ -42,7 +44,7 @@ describe(method, () => { for (let i = 0; i < iterations; i++) { const gasPrice = i * 100 averageGasPrice += BigInt(gasPrice) - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { nonce: i, gasLimit: 21000, gasPrice, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) @@ -64,11 +66,11 @@ describe(method, () => { const G1 = 100 const G2 = 1231231 - const tx1 = LegacyTransaction.fromTxData( + const tx1 = createLegacyTx( { gasLimit: 21000, gasPrice: G1, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) - const tx2 = LegacyTransaction.fromTxData( + const tx2 = createLegacyTx( { nonce: 1, gasLimit: 21000, gasPrice: G2, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) @@ -90,7 +92,7 @@ describe(method, () => { 'powLondon' ) const rpc = getRpcClient(server) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 21000, maxPriorityFeePerGas: 10, @@ -120,7 +122,7 @@ describe(method, () => { const rpc = getRpcClient(server) const maxPriority1 = 10 const maxPriority2 = 1231231 - const tx1 = FeeMarketEIP1559Transaction.fromTxData( + const tx1 = create1559FeeMarketTx( { gasLimit: 21000, maxPriorityFeePerGas: maxPriority1, @@ -129,7 +131,7 @@ describe(method, () => { }, { common } ).sign(dummy.privKey) - const tx2 = FeeMarketEIP1559Transaction.fromTxData( + const tx2 = create1559FeeMarketTx( { nonce: 1, gasLimit: 21000, @@ -162,7 +164,7 @@ describe(method, () => { let tx: LegacyTransaction for (let i = 0; i < iterations; i++) { if (i === 0) { - tx = LegacyTransaction.fromTxData( + tx = createLegacyTx( { nonce: i, gasLimit: 21000, @@ -172,7 +174,7 @@ describe(method, () => { { common } ).sign(dummy.privKey) } else { - tx = LegacyTransaction.fromTxData( + tx = createLegacyTx( { nonce: i, gasLimit: 21000, diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index e2f6a69dc0..9afbc079c8 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -48,7 +48,7 @@ describe( ) // construct block with tx - const tx = LegacyTransaction.fromTxData({ gasLimit: 53000 }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) tx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts index 7916783d26..8b631dd738 100644 --- a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' -import { BlobEIP4844Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { Address, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -13,9 +13,9 @@ const kzg = await loadKZG() const common = createCustomCommon({ chainId: 1 }, { customCrypto: { kzg } }) common.setHardfork('cancun') -const mockedTx1 = LegacyTransaction.fromTxData({}).sign(dummy.privKey) -const mockedTx2 = LegacyTransaction.fromTxData({ nonce: 1 }).sign(dummy.privKey) -const mockedBlobTx3 = BlobEIP4844Transaction.fromTxData( +const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) +const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) +const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, { common } ).sign(dummy.privKey) diff --git a/packages/client/test/rpc/eth/getBlockReceipts.spec.ts b/packages/client/test/rpc/eth/getBlockReceipts.spec.ts index 62ce82605c..7234049067 100644 --- a/packages/client/test/rpc/eth/getBlockReceipts.spec.ts +++ b/packages/client/test/rpc/eth/getBlockReceipts.spec.ts @@ -1,9 +1,5 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { - BlobEIP4844Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, -} from '@ethereumjs/tx' +import { create1559FeeMarketTx, create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { bigIntToHex, blobsToCommitments, @@ -32,7 +28,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain(pow, 'pow') const rpc = getRpcClient(server) // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, @@ -40,7 +36,7 @@ describe(method, () => { }, { common } ).sign(dummy.privKey) - const tx2 = LegacyTransaction.fromTxData( + const tx2 = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, @@ -63,7 +59,7 @@ describe(method, () => { ) const rpc = getRpcClient(server) // construct tx - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, @@ -72,7 +68,7 @@ describe(method, () => { }, { common } ).sign(dummy.privKey) - const tx1 = FeeMarketEIP1559Transaction.fromTxData( + const tx1 = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, @@ -128,7 +124,7 @@ describe(method, () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobs.map((blob, ctx) => kzg.computeBlobKzgProof(blob, commitments[ctx])) - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index 5a12f43f82..1e06d6157f 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -38,7 +38,7 @@ describe(method, () => { const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // construct block with tx - const tx = LegacyTransaction.fromTxData({ gasLimit: 53000 }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) tx.getSenderAddress = () => { return address } @@ -85,21 +85,15 @@ describe(method, () => { const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // construct block with tx - const tx = LegacyTransaction.fromTxData({ gasLimit: 53000 }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) tx.getSenderAddress = () => { return address } - const tx2 = LegacyTransaction.fromTxData( - { gasLimit: 53000, nonce: 1 }, - { common, freeze: false } - ) + const tx2 = createLegacyTx({ gasLimit: 53000, nonce: 1 }, { common, freeze: false }) tx2.getSenderAddress = () => { return address } - const tx3 = LegacyTransaction.fromTxData( - { gasLimit: 53000, nonce: 2 }, - { common, freeze: false } - ) + const tx3 = createLegacyTx({ gasLimit: 53000, nonce: 2 }, { common, freeze: false }) tx3.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index 6d61d0f64f..cc6e678865 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -64,7 +64,7 @@ describe(method, () => { // construct block with tx const gasLimit = 2000000 - const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit, data }, { common, freeze: false }) tx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/getLogs.spec.ts b/packages/client/test/rpc/eth/getLogs.spec.ts index 8267907200..2cdd054f59 100644 --- a/packages/client/test/rpc/eth/getLogs.spec.ts +++ b/packages/client/test/rpc/eth/getLogs.spec.ts @@ -1,4 +1,4 @@ -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -32,7 +32,7 @@ describe(method, async () => { const rpc = getRpcClient(server) // deploy contracts at two different addresses const txData = { gasLimit: 2000000, gasPrice: 100 } - const tx1 = LegacyTransaction.fromTxData( + const tx1 = createLegacyTx( { ...txData, data: logExampleBytecode, @@ -40,7 +40,7 @@ describe(method, async () => { }, { common } ).sign(dummy.privKey) - const tx2 = LegacyTransaction.fromTxData( + const tx2 = createLegacyTx( { ...txData, data: logExampleBytecode, @@ -56,7 +56,7 @@ describe(method, async () => { const data = hexToBytes( '0xaefb4f0a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004' ) - const tx3 = LegacyTransaction.fromTxData( + const tx3 = createLegacyTx( { ...txData, data, @@ -65,7 +65,7 @@ describe(method, async () => { }, { common } ).sign(dummy.privKey) - const tx4 = LegacyTransaction.fromTxData( + const tx4 = createLegacyTx( { ...txData, data, diff --git a/packages/client/test/rpc/eth/getProof.spec.ts b/packages/client/test/rpc/eth/getProof.spec.ts index 644061fca3..b9e2f41d1d 100644 --- a/packages/client/test/rpc/eth/getProof.spec.ts +++ b/packages/client/test/rpc/eth/getProof.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Common } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -127,7 +127,7 @@ describe(method, async () => { // construct block with tx const gasLimit = 2000000 - const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit, data }, { common, freeze: false }) tx.getSenderAddress = () => { return address } @@ -160,7 +160,7 @@ describe(method, async () => { gasLimit: bigIntToHex(BigInt(530000)), nonce: 1, } - const storeTx = LegacyTransaction.fromTxData(storeTxData, { common, freeze: false }) + const storeTx = createLegacyTx(storeTxData, { common, freeze: false }) storeTx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/getStorageAt.spec.ts b/packages/client/test/rpc/eth/getStorageAt.spec.ts index 2163a276c6..fe30e8ba1a 100644 --- a/packages/client/test/rpc/eth/getStorageAt.spec.ts +++ b/packages/client/test/rpc/eth/getStorageAt.spec.ts @@ -1,5 +1,5 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -29,7 +29,7 @@ describe(method, async () => { // construct block with tx const gasLimit = 2000000 - const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit, data }, { common, freeze: false }) const signedTx = tx.sign(tx.getHashedMessageToSign()) const parent = await chain.blockchain.getCanonicalHeadHeader() diff --git a/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts b/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts index 47a4c00884..5a97a2950e 100644 --- a/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts @@ -1,4 +1,4 @@ -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -11,7 +11,7 @@ const method = 'eth_getTransactionByBlockHashAndIndex' async function setUp() { const { common, execution, server, chain } = await setupChain(pow, 'pow') const txs = [ - LegacyTransaction.fromTxData( + createLegacyTx( { gasLimit: 21000, gasPrice: 100, @@ -20,7 +20,7 @@ async function setUp() { }, { common } ).sign(dummy.privKey), - LegacyTransaction.fromTxData( + createLegacyTx( { gasLimit: 21000, gasPrice: 50, nonce: 1, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey), diff --git a/packages/client/test/rpc/eth/getTransactionByHash.spec.ts b/packages/client/test/rpc/eth/getTransactionByHash.spec.ts index 6297d4cc38..9a5fa3981a 100644 --- a/packages/client/test/rpc/eth/getTransactionByHash.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionByHash.spec.ts @@ -1,4 +1,4 @@ -import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createLegacyTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -18,7 +18,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain(pow, 'pow', { txLookupLimit: 1 }) const rpc = getRpcClient(server) // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, to: '0x0000000000000000000000000000000000000000' }, { common } ).sign(dummy.privKey) @@ -43,7 +43,7 @@ describe(method, () => { ) const rpc = getRpcClient(server) // construct tx - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 6cbd479db9..b58383b877 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' -import { LegacyTransaction, createTxFromTxData } from '@ethereumjs/tx' +import { createLegacyTx, createTxFromTxData } from '@ethereumjs/tx' import { Account, Address, hexToBytes, randomBytes } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -44,7 +44,7 @@ describe(method, () => { assert.equal(res.result, '0x0', 'should return the correct nonce (0)') // construct block with tx - const tx = LegacyTransaction.fromTxData({ gasLimit: 53000 }, { common, freeze: false }) + const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) tx.getSenderAddress = () => { return address } diff --git a/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts b/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts index 8ce2c8cf2e..8f4ff58727 100644 --- a/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts @@ -1,9 +1,5 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { - BlobEIP4844Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, -} from '@ethereumjs/tx' +import { create1559FeeMarketTx, create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { blobsToCommitments, bytesToHex, @@ -30,7 +26,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain(pow, 'pow') const rpc = getRpcClient(server) // construct tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, @@ -53,7 +49,7 @@ describe(method, () => { ) const rpc = getRpcClient(server) // construct tx - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { gasLimit: 2000000, maxFeePerGas: 975000000, @@ -108,7 +104,7 @@ describe(method, () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobs.map((blob, ctx) => kzg.computeBlobKzgProof(blob, commitments[ctx])) - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/client/test/rpc/eth/sendRawTransaction.spec.ts b/packages/client/test/rpc/eth/sendRawTransaction.spec.ts index 3fd39270a5..0d2de1b69e 100644 --- a/packages/client/test/rpc/eth/sendRawTransaction.spec.ts +++ b/packages/client/test/rpc/eth/sendRawTransaction.spec.ts @@ -1,11 +1,7 @@ import { BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { - BlobEIP4844Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, -} from '@ethereumjs/tx' +import { create1559FeeMarketTxFromRLP, create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' import { Account, blobsToCommitments, @@ -47,7 +43,7 @@ describe(method, () => { // Mainnet EIP-1559 tx const txData = '0x02f90108018001018402625a0094cccccccccccccccccccccccccccccccccccccccc830186a0b8441a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0afb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9a0479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64' - const transaction = FeeMarketEIP1559Transaction.fromSerializedTx(hexToBytes(txData)) + const transaction = create1559FeeMarketTxFromRLP(hexToBytes(txData)) const address = transaction.getSenderAddress() const vm = (client.services.find((s) => s.name === 'eth') as FullEthereumService).execution.vm @@ -75,7 +71,7 @@ describe(method, () => { const syncTargetHeight = new Common({ chain: Chain.Mainnet }).hardforkBlock(Hardfork.London) const { rpc } = await baseSetup({ syncTargetHeight, includeVM: true }) - const transaction = LegacyTransaction.fromTxData({ + const transaction = createLegacyTx({ gasLimit: 21000, gasPrice: 0, nonce: 0, @@ -152,7 +148,7 @@ describe(method, () => { const txData = '0x02f90108018001018402625a0094cccccccccccccccccccccccccccccccccccccccc830186a0b8441a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0afb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9a0479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - const tx = FeeMarketEIP1559Transaction.fromSerializedTx(hexToBytes(txData), { + const tx = create1559FeeMarketTxFromRLP(hexToBytes(txData), { common, freeze: false, }) @@ -187,7 +183,7 @@ describe(method, () => { // Mainnet EIP-1559 tx const txData = '0x02f90108018001018402625a0094cccccccccccccccccccccccccccccccccccccccc830186a0b8441a8451e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85bf859940000000000000000000000000000000000000101f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000060a701a0afb6e247b1c490e284053c87ab5f6b59e219d51f743f7a4d83e400782bc7e4b9a0479a268e0e0acd4de3f1e28e4fac2a6b32a4195e8dfa9d19147abe8807aa6f64' - const transaction = FeeMarketEIP1559Transaction.fromSerializedTx(hexToBytes(txData)) + const transaction = create1559FeeMarketTxFromRLP(hexToBytes(txData)) const address = transaction.getSenderAddress() const vm = (client.services.find((s) => s.name === 'eth') as FullEthereumService).execution.vm @@ -237,7 +233,7 @@ describe(method, () => { const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobs.map((blob, ctx) => kzg.computeBlobKzgProof(blob, commitments[ctx])) const pk = randomBytes(32) - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { blobVersionedHashes, blobs, @@ -252,7 +248,7 @@ describe(method, () => { { common } ).sign(pk) - const replacementTx = BlobEIP4844Transaction.fromTxData( + const replacementTx = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/client/test/rpc/mockBlockchain.ts b/packages/client/test/rpc/mockBlockchain.ts index 79d12643b2..2a00b29418 100644 --- a/packages/client/test/rpc/mockBlockchain.ts +++ b/packages/client/test/rpc/mockBlockchain.ts @@ -1,16 +1,16 @@ import { createBlockFromBlockData } from '@ethereumjs/block' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { equalsBytes, toBytes } from '@ethereumjs/util' import { dummy } from './helpers.js' +import type { LegacyTransaction } from '@ethereumjs/tx' + export function mockBlockchain(options: any = {}) { const number = options.number ?? '0x444444' const blockHash = options.hash ?? '0x910abca1728c53e8d6df870dd7af5352e974357dc58205dea1676be17ba6becf' - const transactions = options.transactions ?? [ - LegacyTransaction.fromTxData({}).sign(dummy.privKey), - ] + const transactions = options.transactions ?? [createLegacyTx({}).sign(dummy.privKey)] const block = { hash: () => toBytes(blockHash), serialize: () => createBlockFromBlockData({ header: { number }, transactions }).serialize(), diff --git a/packages/client/test/sim/simutils.ts b/packages/client/test/sim/simutils.ts index a65e4e3de4..252ea2decc 100644 --- a/packages/client/test/sim/simutils.ts +++ b/packages/client/test/sim/simutils.ts @@ -1,6 +1,6 @@ import { executionPayloadFromBeaconPayload } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' -import { BlobEIP4844Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, create4844BlobTx } from '@ethereumjs/tx' import { Address, BIGINT_1, @@ -279,7 +279,7 @@ export async function runTxHelper( const block = await client.request('eth_getBlockByNumber', ['latest', false]) const baseFeePerGas = BigInt(block.result.baseFeePerGas) * 100n const maxPriorityFeePerGas = 100000000n - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { data, gasLimit: 1000000, @@ -346,7 +346,7 @@ export const runBlobTx = async ( txData.gasLimit = BigInt(1000000) const nonce = await client.request('eth_getTransactionCount', [sender.toString(), 'latest'], 2.0) txData.nonce = BigInt(nonce.result) - const blobTx = BlobEIP4844Transaction.fromTxData(txData, opts).sign(pkey) + const blobTx = create4844BlobTx(txData, opts).sign(pkey) const serializedWrapper = blobTx.serializeNetworkWrapper() @@ -407,7 +407,7 @@ export const createBlobTxs = async ( gas: undefined, } - const blobTx = BlobEIP4844Transaction.fromTxData(txData, opts).sign(pkey) + const blobTx = create4844BlobTx(txData, opts).sign(pkey) const serializedWrapper = blobTx.serializeNetworkWrapper() await fs.appendFile('./blobs.txt', bytesToHex(serializedWrapper) + '\n') diff --git a/packages/client/test/sim/txGenerator.ts b/packages/client/test/sim/txGenerator.ts index a3122f095c..bb1225d710 100644 --- a/packages/client/test/sim/txGenerator.ts +++ b/packages/client/test/sim/txGenerator.ts @@ -1,5 +1,5 @@ // Adapted from - https://github.com/Inphi/eip4844-interop/blob/master/blob_tx_generator/blob.js -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { create4844BlobTx } from '@ethereumjs/tx' import { Address, blobsToCommitments, @@ -121,7 +121,7 @@ async function run(data: any) { txData.gasLimit = BigInt(28000000) const nonce = await getNonce(client, sender.toString()) txData.nonce = BigInt(nonce) - const blobTx = BlobEIP4844Transaction.fromTxData(txData).sign(pkey) + const blobTx = create4844BlobTx(txData).sign(pkey) const serializedWrapper = blobTx.serializeNetworkWrapper() diff --git a/packages/client/test/sync/txpool.spec.ts b/packages/client/test/sync/txpool.spec.ts index f2c31222cf..21240417e9 100644 --- a/packages/client/test/sync/txpool.spec.ts +++ b/packages/client/test/sync/txpool.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, create2930AccessListTx } from '@ethereumjs/tx' import { Account, bytesToHex, @@ -176,7 +176,7 @@ describe('[TxPool]', async () => { } txData.maxFeePerGas += (txData.maxFeePerGas * feeBump) / 100 txData.maxPriorityFeePerGas += (txData.maxPriorityFeePerGas * feeBump) / 100 - const tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }) + const tx = create1559FeeMarketTx(txData, { common }) const signedTx = tx.sign(from.privateKey) return signedTx } @@ -531,7 +531,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, }) @@ -547,7 +547,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, nonce: 0, @@ -567,7 +567,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData( + create1559FeeMarketTx( { maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, @@ -590,7 +590,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, gasLimit: 21000, @@ -610,7 +610,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, nonce: 0, @@ -633,7 +633,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, nonce: 0, @@ -657,7 +657,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, }).sign(A.privateKey) @@ -677,7 +677,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - FeeMarketEIP1559Transaction.fromTxData({ + create1559FeeMarketTx({ maxFeePerGas: 10000000, maxPriorityFeePerGas: 10000000, nonce: 0, @@ -694,7 +694,7 @@ describe('[TxPool]', async () => { const txs = [] txs.push( - AccessListEIP2930Transaction.fromTxData({ + create2930AccessListTx({ gasPrice: 10000000, nonce: 0, }).sign(A.privateKey) @@ -709,7 +709,7 @@ describe('[TxPool]', async () => { it('announcedTxHashes() -> reject txs with too low gas price (invalid tx type)', async () => { const txs = [] - const tx = AccessListEIP2930Transaction.fromTxData( + const tx = create2930AccessListTx( { gasPrice: 1000000000 - 1, nonce: 0, diff --git a/packages/client/test/util/wasmCrypto.spec.ts b/packages/client/test/util/wasmCrypto.spec.ts index 4fad467ef3..59b0502a2a 100644 --- a/packages/client/test/util/wasmCrypto.spec.ts +++ b/packages/client/test/util/wasmCrypto.spec.ts @@ -1,5 +1,5 @@ import { Common } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { BIGINT_2, bytesToHex, @@ -50,8 +50,8 @@ describe('WASM crypto tests', () => { const common = new Common({ chain: 'mainnet' }) const pk = randomBytes(32) - const tx = LegacyTransaction.fromTxData({}, { common }).sign(pk) - const tx2 = LegacyTransaction.fromTxData({}, { common: commonWithCustomCrypto }).sign(pk) + const tx = createLegacyTx({}, { common }).sign(pk) + const tx2 = createLegacyTx({}, { common: commonWithCustomCrypto }).sign(pk) assert.deepEqual(tx.getSenderPublicKey(), tx2.getSenderPublicKey()) assert.deepEqual(tx.hash(), tx2.hash()) diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index c8b50311a5..e563feacc6 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromJsonRpcProvider, createBlockFromRPC } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { type EVMRunCallOpts, createEVM } from '@ethereumjs/evm' -import { FeeMarketEIP1559Transaction, createTxFromRPC } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createTxFromRPC } from '@ethereumjs/tx' import { Address, bigIntToBytes, @@ -242,7 +242,7 @@ describe('runTx custom transaction test', () => { const privateKey = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' ) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { to: vitalikDotEth, value: '0x100', gasLimit: 500000n, maxFeePerGas: 7 }, { common } ).sign(privateKey) diff --git a/packages/tx/examples/accessListTx.ts b/packages/tx/examples/accessListTx.ts index 1c7346b3c2..7e5b5e1db3 100644 --- a/packages/tx/examples/accessListTx.ts +++ b/packages/tx/examples/accessListTx.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { AccessListEIP2930Transaction } from '@ethereumjs/tx' +import { create2930AccessListTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }) @@ -27,5 +27,5 @@ const txData = { type: '0x01', } -const tx = AccessListEIP2930Transaction.fromTxData(txData, { common }) +const tx = create2930AccessListTx(txData, { common }) console.log(bytesToHex(tx.hash())) // 0x9150cdebad74e88b038e6c6b964d99af705f9c0883d7f0bbc0f3e072358f5b1d diff --git a/packages/tx/examples/blobTx.ts b/packages/tx/examples/blobTx.ts index 9600e22186..03f38924fe 100644 --- a/packages/tx/examples/blobTx.ts +++ b/packages/tx/examples/blobTx.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { create4844BlobTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' @@ -31,7 +31,7 @@ const main = async () => { blobsData: ['abcd'], } - const tx = BlobEIP4844Transaction.fromTxData(txData, { common }) + const tx = create4844BlobTx(txData, { common }) console.log(bytesToHex(tx.hash())) //0x3c3e7c5e09c250d2200bcc3530f4a9088d7e3fb4ea3f4fccfd09f535a3539e84 } diff --git a/packages/tx/examples/custom-chain-id-tx.ts b/packages/tx/examples/custom-chain-id-tx.ts index 4d9b911a89..30d5baf394 100644 --- a/packages/tx/examples/custom-chain-id-tx.ts +++ b/packages/tx/examples/custom-chain-id-tx.ts @@ -1,6 +1,6 @@ -import { LegacyTransaction } from '../dist/cjs' +import { createLegacyTxFromRLP } from '@ethereumjs/tx' import { toBytes } from '@ethereumjs/util' -import { Common, createCustomCommon, Hardfork } from '@ethereumjs/common' +import { createCustomCommon, Hardfork } from '@ethereumjs/common' const txData = toBytes( '0xf9010b82930284d09dc30083419ce0942d18de92e0f9aee1a29770c3b15c6cf8ac5498e580b8a42f43f4fb0000000000000000000000000000000000000000000000000000016b78998da900000000000000000000000000000000000000000000000000000000000cb1b70000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000001363e4f00000000000000000000000000000000000000000000000000000000000186a029a0fac36e66d329af0e831b2e61179b3ec8d7c7a8a2179e303cfed3364aff2bc3e4a07cb73d56e561ccbd838818dd3dea5fa0b5158577ffc61c0e6ec1f0ed55716891' @@ -8,7 +8,7 @@ const txData = toBytes( const common = createCustomCommon({ chainId: 3 }) common.setHardfork(Hardfork.Petersburg) -const tx = LegacyTransaction.fromSerializedTx(txData, { common }) +const tx = createLegacyTxFromRLP(txData, { common }) if ( tx.isValid() && diff --git a/packages/tx/examples/custom-chain-tx.ts b/packages/tx/examples/custom-chain-tx.ts index 8378dccf3a..8ac85170fd 100644 --- a/packages/tx/examples/custom-chain-tx.ts +++ b/packages/tx/examples/custom-chain-tx.ts @@ -1,6 +1,6 @@ import { Address } from '@ethereumjs/util' -import { Common, createCustomCommon } from '@ethereumjs/common' -import { LegacyTransaction } from '../dist/cjs/index' +import { createCustomCommon } from '@ethereumjs/common' +import { createLegacyTx } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' // In this example we create a transaction for a custom network. @@ -20,7 +20,7 @@ const customCommon = createCustomCommon( // We pass our custom Common object whenever we create a transaction const opts = { common: customCommon } -const tx = LegacyTransaction.fromTxData( +const tx = createLegacyTx( { nonce: 0, gasPrice: 100, diff --git a/packages/tx/examples/l2tx.ts b/packages/tx/examples/l2tx.ts index 427f2dc425..5b9dd1ad55 100644 --- a/packages/tx/examples/l2tx.ts +++ b/packages/tx/examples/l2tx.ts @@ -1,5 +1,5 @@ -import { Common, createCustomCommon, CustomChain } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createCustomCommon, CustomChain } from '@ethereumjs/common' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' const pk = hexToBytes('0x076247989df60a82f6e86e58104368676096f84e60972282ee00d4673a2bc9b9') @@ -14,6 +14,6 @@ const txData = { value: 1, } -const tx = LegacyTransaction.fromTxData(txData, { common }) +const tx = createLegacyTx(txData, { common }) const signedTx = tx.sign(pk) console.log(bytesToHex(signedTx.hash())) // 0xbf98f6f8700812ed6f2314275070256e11945fa48afd80fb301265f6a41a2dc2 diff --git a/packages/tx/examples/legacyTx.ts b/packages/tx/examples/legacyTx.ts index 1755327c9d..69dd8220c1 100644 --- a/packages/tx/examples/legacyTx.ts +++ b/packages/tx/examples/legacyTx.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' const txParams = { @@ -12,7 +12,7 @@ const txParams = { } const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) -const tx = LegacyTransaction.fromTxData(txParams, { common }) +const tx = createLegacyTx(txParams, { common }) const privateKey = Buffer.from( 'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', diff --git a/packages/tx/examples/londonTx.ts b/packages/tx/examples/londonTx.ts index 50877045a8..00bb618fe7 100644 --- a/packages/tx/examples/londonTx.ts +++ b/packages/tx/examples/londonTx.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) @@ -20,5 +20,5 @@ const txData = { type: '0x02', } -const tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }) +const tx = create1559FeeMarketTx(txData, { common }) console.log(bytesToHex(tx.hash())) // 0x6f9ef69ccb1de1aea64e511efd6542541008ced321887937c95b03779358ec8a diff --git a/packages/tx/examples/transactions.ts b/packages/tx/examples/transactions.ts index df864181d3..4104b91435 100644 --- a/packages/tx/examples/transactions.ts +++ b/packages/tx/examples/transactions.ts @@ -2,13 +2,13 @@ // You can run them with tsx, as this project is developed in TypeScript. // Install the dependencies and run `npx tsx examples/transactions.ts` -import { LegacyTransaction } from '../dist/cjs' import { bytesToHex, toBytes, hexToBytes } from '@ethereumjs/util' +import { createLegacyTx, createLegacyTxFromBytesArray } from '@ethereumjs/tx' // We create an unsigned transaction. // Notice we don't set the `to` field because we are creating a new contract. // This transaction's chain is set to mainnet. -const tx = LegacyTransaction.fromTxData({ +const tx = createLegacyTx({ nonce: 0, gasPrice: 100, gasLimit: 1000000000, @@ -50,7 +50,7 @@ const rawTx = [ '0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13', ] -const tx2 = LegacyTransaction.fromValuesArray(rawTx.map(toBytes)) // This is also a mainnet transaction +const tx2 = createLegacyTxFromBytesArray(rawTx.map(toBytes)) // This is also a mainnet transaction // So assuming that you were able to parse the transaction, we will now get the sender's address. diff --git a/packages/tx/src/1559/constructors.ts b/packages/tx/src/1559/constructors.ts new file mode 100644 index 0000000000..6972a8bdfd --- /dev/null +++ b/packages/tx/src/1559/constructors.ts @@ -0,0 +1,103 @@ +import { RLP } from '@ethereumjs/rlp' +import { bytesToBigInt, bytesToHex, equalsBytes, validateNoLeadingZeroes } from '@ethereumjs/util' + +import { TransactionType } from '../types.js' +import { txTypeBytes, validateNotArray } from '../util.js' + +import { FeeMarketEIP1559Transaction } from './tx.js' + +import type { TxOptions } from '../types.js' +import type { TxData, TxValuesArray } from './tx.js' + +/** + * Instantiate a transaction from a data dictionary. + * + * Format: { chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, + * accessList, v, r, s } + * + * Notes: + * - `chainId` will be set automatically if not provided + * - All parameters are optional and have some basic default values + */ +export function create1559FeeMarketTx(txData: TxData, opts: TxOptions = {}) { + return new FeeMarketEIP1559Transaction(txData, opts) +} + +/** + * Create a transaction from an array of byte encoded values ordered according to the devp2p network encoding - format noted below. + * + * Format: `[chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, + * accessList, signatureYParity, signatureR, signatureS]` + */ +export function createEIP1559FeeMarketTxFromBytesArray( + values: TxValuesArray, + opts: TxOptions = {} +) { + if (values.length !== 9 && values.length !== 12) { + throw new Error( + 'Invalid EIP-1559 transaction. Only expecting 9 values (for unsigned tx) or 12 values (for signed tx).' + ) + } + + const [ + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + data, + accessList, + v, + r, + s, + ] = values + + validateNotArray({ chainId, v }) + validateNoLeadingZeroes({ nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, value, v, r, s }) + + return new FeeMarketEIP1559Transaction( + { + chainId: bytesToBigInt(chainId), + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + data, + accessList: accessList ?? [], + v: v !== undefined ? bytesToBigInt(v) : undefined, // EIP2930 supports v's with value 0 (empty Uint8Array) + r, + s, + }, + opts + ) +} + +/** + * Instantiate a transaction from an RLP serialized tx. + * + * Format: `0x02 || rlp([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, + * accessList, signatureYParity, signatureR, signatureS])` + */ +export function create1559FeeMarketTxFromRLP(serialized: Uint8Array, opts: TxOptions = {}) { + if ( + equalsBytes(serialized.subarray(0, 1), txTypeBytes(TransactionType.FeeMarketEIP1559)) === false + ) { + throw new Error( + `Invalid serialized tx input: not an EIP-1559 transaction (wrong tx type, expected: ${ + TransactionType.FeeMarketEIP1559 + }, received: ${bytesToHex(serialized.subarray(0, 1))}` + ) + } + + const values = RLP.decode(serialized.subarray(1)) + + if (!Array.isArray(values)) { + throw new Error('Invalid serialized tx input: must be array') + } + + return createEIP1559FeeMarketTxFromBytesArray(values as TxValuesArray, opts) +} diff --git a/packages/tx/src/1559/index.ts b/packages/tx/src/1559/index.ts new file mode 100644 index 0000000000..6eb1e863e8 --- /dev/null +++ b/packages/tx/src/1559/index.ts @@ -0,0 +1,2 @@ +export * from './constructors.js' +export { FeeMarketEIP1559Transaction } from './tx.js' diff --git a/packages/tx/src/eip1559Transaction.ts b/packages/tx/src/1559/tx.ts similarity index 71% rename from packages/tx/src/eip1559Transaction.ts rename to packages/tx/src/1559/tx.ts index b33d12e1c5..67db0d1cf9 100644 --- a/packages/tx/src/eip1559Transaction.ts +++ b/packages/tx/src/1559/tx.ts @@ -1,4 +1,3 @@ -import { RLP } from '@ethereumjs/rlp' import { BIGINT_0, BIGINT_27, @@ -6,19 +5,18 @@ import { bigIntToHex, bigIntToUnpaddedBytes, bytesToBigInt, - bytesToHex, - equalsBytes, toBytes, - validateNoLeadingZeroes, } from '@ethereumjs/util' -import { BaseTransaction } from './baseTransaction.js' -import * as EIP1559 from './capabilities/eip1559.js' -import * as EIP2718 from './capabilities/eip2718.js' -import * as EIP2930 from './capabilities/eip2930.js' -import * as Legacy from './capabilities/legacy.js' -import { TransactionType } from './types.js' -import { AccessLists, txTypeBytes } from './util.js' +import { BaseTransaction } from '../baseTransaction.js' +import * as EIP1559 from '../capabilities/eip1559.js' +import * as EIP2718 from '../capabilities/eip2718.js' +import * as EIP2930 from '../capabilities/eip2930.js' +import * as Legacy from '../capabilities/legacy.js' +import { TransactionType } from '../types.js' +import { AccessLists, validateNotArray } from '../util.js' + +import { create1559FeeMarketTx } from './constructors.js' import type { AccessList, @@ -27,11 +25,11 @@ import type { TxValuesArray as AllTypesTxValuesArray, JsonTx, TxOptions, -} from './types.js' +} from '../types.js' import type { Common } from '@ethereumjs/common' -type TxData = AllTypesTxData[TransactionType.FeeMarketEIP1559] -type TxValuesArray = AllTypesTxValuesArray[TransactionType.FeeMarketEIP1559] +export type TxData = AllTypesTxData[TransactionType.FeeMarketEIP1559] +export type TxValuesArray = AllTypesTxValuesArray[TransactionType.FeeMarketEIP1559] /** * Typed transaction with a new gas fee market mechanism @@ -49,97 +47,6 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction MAX_INTEGER) { const msg = this._errorMsg('gasLimit * maxFeePerGas cannot exceed MAX_INTEGER (2^256-1)') @@ -324,7 +231,7 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction MAX_INTEGER) { const msg = this._errorMsg('gasLimit * gasPrice cannot exceed MAX_INTEGER') @@ -294,7 +213,7 @@ export class AccessListEIP2930Transaction extends BaseTransaction { + if (!(blobVersionedHashes.length === blobs.length && blobs.length === commitments.length)) { + throw new Error('Number of blobVersionedHashes, blobs, and commitments not all equal') + } + if (blobVersionedHashes.length === 0) { + throw new Error('Invalid transaction with empty blobs') + } + + let isValid + try { + isValid = kzg.verifyBlobKzgProofBatch(blobs, commitments, kzgProofs) + } catch (error) { + throw new Error(`KZG verification of blobs fail with error=${error}`) + } + if (!isValid) { + throw new Error('KZG proof cannot be verified from blobs/commitments') + } + + for (let x = 0; x < blobVersionedHashes.length; x++) { + const computedVersionedHash = computeVersionedHash(commitments[x], version) + if (!equalsBytes(computedVersionedHash, blobVersionedHashes[x])) { + throw new Error(`commitment for blob at index ${x} does not match versionedHash`) + } + } +} + +/** + * Instantiate a transaction from a data dictionary. + * + * Format: { chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, + * v, r, s, blobs, kzgCommitments, blobVersionedHashes, kzgProofs } + * + * Notes: + * - `chainId` will be set automatically if not provided + * - All parameters are optional and have some basic default values + * - `blobs` cannot be supplied as well as `kzgCommittments`, `blobVersionedHashes`, `kzgProofs` + * - If `blobs` is passed in, `kzgCommittments`, `blobVersionedHashes`, `kzgProofs` will be derived by the constructor + */ +export function create4844BlobTx(txData: TxData, opts?: TxOptions) { + if (opts?.common?.customCrypto?.kzg === undefined) { + throw new Error( + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + ) + } + const kzg = opts!.common!.customCrypto!.kzg! + if (txData.blobsData !== undefined) { + if (txData.blobs !== undefined) { + throw new Error('cannot have both raw blobs data and encoded blobs in constructor') + } + if (txData.kzgCommitments !== undefined) { + throw new Error('cannot have both raw blobs data and KZG commitments in constructor') + } + if (txData.blobVersionedHashes !== undefined) { + throw new Error('cannot have both raw blobs data and versioned hashes in constructor') + } + if (txData.kzgProofs !== undefined) { + throw new Error('cannot have both raw blobs data and KZG proofs in constructor') + } + txData.blobs = getBlobs(txData.blobsData.reduce((acc, cur) => acc + cur)) + txData.kzgCommitments = blobsToCommitments(kzg, txData.blobs as Uint8Array[]) + txData.blobVersionedHashes = commitmentsToVersionedHashes(txData.kzgCommitments as Uint8Array[]) + txData.kzgProofs = blobsToProofs( + kzg, + txData.blobs as Uint8Array[], + txData.kzgCommitments as Uint8Array[] + ) + } + + return new BlobEIP4844Transaction(txData, opts) +} + +/** + * Create a transaction from an array of byte encoded values ordered according to the devp2p network encoding - format noted below. + * + * Format: `[chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, + * accessList, signatureYParity, signatureR, signatureS]` + */ +export function create4844BlobTxFromBytesArray(values: TxValuesArray, opts: TxOptions = {}) { + if (opts.common?.customCrypto?.kzg === undefined) { + throw new Error( + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + ) + } + + if (values.length !== 11 && values.length !== 14) { + throw new Error( + 'Invalid EIP-4844 transaction. Only expecting 11 values (for unsigned tx) or 14 values (for signed tx).' + ) + } + + const [ + chainId, + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + data, + accessList, + maxFeePerBlobGas, + blobVersionedHashes, + v, + r, + s, + ] = values + + validateNotArray({ chainId, v }) + validateNoLeadingZeroes({ + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + value, + maxFeePerBlobGas, + v, + r, + s, + }) + + return new BlobEIP4844Transaction( + { + chainId: bytesToBigInt(chainId), + nonce, + maxPriorityFeePerGas, + maxFeePerGas, + gasLimit, + to, + value, + data, + accessList: accessList ?? [], + maxFeePerBlobGas, + blobVersionedHashes, + v: v !== undefined ? bytesToBigInt(v) : undefined, // EIP2930 supports v's with value 0 (empty Uint8Array) + r, + s, + }, + opts + ) +} + +/** + * Instantiate a transaction from a RLP serialized tx. + * + * Format: `0x03 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, + * access_list, max_fee_per_data_gas, blob_versioned_hashes, y_parity, r, s])` + */ +export function create4844BlobTxFromRLP(serialized: Uint8Array, opts: TxOptions = {}) { + if (opts.common?.customCrypto?.kzg === undefined) { + throw new Error( + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + ) + } + + if (equalsBytes(serialized.subarray(0, 1), txTypeBytes(TransactionType.BlobEIP4844)) === false) { + throw new Error( + `Invalid serialized tx input: not an EIP-4844 transaction (wrong tx type, expected: ${ + TransactionType.BlobEIP4844 + }, received: ${bytesToHex(serialized.subarray(0, 1))}` + ) + } + + const values = RLP.decode(serialized.subarray(1)) + + if (!Array.isArray(values)) { + throw new Error('Invalid serialized tx input: must be array') + } + + return create4844BlobTxFromBytesArray(values as TxValuesArray, opts) +} + +/** + * Creates a transaction from the network encoding of a blob transaction (with blobs/commitments/proof) + * @param serialized a buffer representing a serialized BlobTransactionNetworkWrapper + * @param opts any TxOptions defined + * @returns a BlobEIP4844Transaction + */ +export function create4844BlobTxFromSerializedNetworkWrapper( + serialized: Uint8Array, + opts?: TxOptions +): BlobEIP4844Transaction { + if (!opts || !opts.common) { + throw new Error('common instance required to validate versioned hashes') + } + + if (opts.common?.customCrypto?.kzg === undefined) { + throw new Error( + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + ) + } + + if (equalsBytes(serialized.subarray(0, 1), txTypeBytes(TransactionType.BlobEIP4844)) === false) { + throw new Error( + `Invalid serialized tx input: not an EIP-4844 transaction (wrong tx type, expected: ${ + TransactionType.BlobEIP4844 + }, received: ${bytesToHex(serialized.subarray(0, 1))}` + ) + } + + // Validate network wrapper + const networkTxValues = RLP.decode(serialized.subarray(1)) + if (networkTxValues.length !== 4) { + throw Error(`Expected 4 values in the deserialized network transaction`) + } + const [txValues, blobs, kzgCommitments, kzgProofs] = + networkTxValues as BlobEIP4844NetworkValuesArray + + // Construct the tx but don't freeze yet, we will assign blobs etc once validated + const decodedTx = create4844BlobTxFromBytesArray(txValues, { ...opts, freeze: false }) + if (decodedTx.to === undefined) { + throw Error('BlobEIP4844Transaction can not be send without a valid `to`') + } + + const version = Number(opts.common.param('blobCommitmentVersionKzg')) + validateBlobTransactionNetworkWrapper( + decodedTx.blobVersionedHashes, + blobs, + kzgCommitments, + kzgProofs, + version, + opts.common.customCrypto.kzg + ) + + // set the network blob data on the tx + decodedTx.blobs = blobs + decodedTx.kzgCommitments = kzgCommitments + decodedTx.kzgProofs = kzgProofs + + // freeze the tx + const freeze = opts?.freeze ?? true + if (freeze) { + Object.freeze(decodedTx) + } + + return decodedTx +} + +/** + * Creates the minimal representation of a blob transaction from the network wrapper version. + * The minimal representation is used when adding transactions to an execution payload/block + * @param txData a {@link BlobEIP4844Transaction} containing optional blobs/kzg commitments + * @param opts - dictionary of {@link TxOptions} + * @returns the "minimal" representation of a BlobEIP4844Transaction (i.e. transaction object minus blobs and kzg commitments) + */ +export function createMinimal4844TxFromNetworkWrapper( + txData: BlobEIP4844Transaction, + opts?: TxOptions +): BlobEIP4844Transaction { + if (opts?.common?.customCrypto?.kzg === undefined) { + throw new Error( + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + ) + } + + const tx = create4844BlobTx( + { + ...txData, + ...{ blobs: undefined, kzgCommitments: undefined, kzgProofs: undefined }, + }, + opts + ) + return tx +} + +/** + * Returns the EIP 4844 transaction network wrapper in JSON format similar to toJSON, including + * blobs, commitments, and proofs fields + * @param serialized a buffer representing a serialized BlobTransactionNetworkWrapper + * @param opts any TxOptions defined + * @returns JsonBlobTxNetworkWrapper with blobs, KZG commitments, and KZG proofs fields + */ +export function blobTxNetworkWrapperToJSON( + serialized: Uint8Array, + opts?: TxOptions +): JsonBlobTxNetworkWrapper { + const tx = create4844BlobTxFromSerializedNetworkWrapper(serialized, opts) + + const accessListJSON = AccessLists.getAccessListJSON(tx.accessList) + const baseJson = tx.toJSON() + + return { + ...baseJson, + chainId: bigIntToHex(tx.chainId), + maxPriorityFeePerGas: bigIntToHex(tx.maxPriorityFeePerGas), + maxFeePerGas: bigIntToHex(tx.maxFeePerGas), + accessList: accessListJSON, + maxFeePerBlobGas: bigIntToHex(tx.maxFeePerBlobGas), + blobVersionedHashes: tx.blobVersionedHashes.map((hash) => bytesToHex(hash)), + blobs: tx.blobs!.map((bytes) => bytesToHex(bytes)), + kzgCommitments: tx.kzgCommitments!.map((bytes) => bytesToHex(bytes)), + kzgProofs: tx.kzgProofs!.map((bytes) => bytesToHex(bytes)), + } +} diff --git a/packages/tx/src/4844/index.ts b/packages/tx/src/4844/index.ts new file mode 100644 index 0000000000..4647d094d5 --- /dev/null +++ b/packages/tx/src/4844/index.ts @@ -0,0 +1,2 @@ +export * from './constructors.js' +export { BlobEIP4844Transaction } from './tx.js' diff --git a/packages/tx/src/eip4844Transaction.ts b/packages/tx/src/4844/tx.ts similarity index 51% rename from packages/tx/src/eip4844Transaction.ts rename to packages/tx/src/4844/tx.ts index a1e43256d9..24960f6189 100644 --- a/packages/tx/src/eip4844Transaction.ts +++ b/packages/tx/src/4844/tx.ts @@ -1,79 +1,37 @@ -import { RLP } from '@ethereumjs/rlp' import { BIGINT_0, BIGINT_27, MAX_INTEGER, bigIntToHex, bigIntToUnpaddedBytes, - blobsToCommitments, - blobsToProofs, bytesToBigInt, bytesToHex, - commitmentsToVersionedHashes, - computeVersionedHash, - equalsBytes, - getBlobs, toBytes, - validateNoLeadingZeroes, } from '@ethereumjs/util' -import { BaseTransaction } from './baseTransaction.js' -import * as EIP1559 from './capabilities/eip1559.js' -import * as EIP2718 from './capabilities/eip2718.js' -import * as EIP2930 from './capabilities/eip2930.js' -import * as Legacy from './capabilities/legacy.js' -import { LIMIT_BLOBS_PER_TX } from './constants.js' -import { TransactionType } from './types.js' -import { AccessLists, txTypeBytes } from './util.js' +import { BaseTransaction } from '../baseTransaction.js' +import * as EIP1559 from '../capabilities/eip1559.js' +import * as EIP2718 from '../capabilities/eip2718.js' +import * as EIP2930 from '../capabilities/eip2930.js' +import * as Legacy from '../capabilities/legacy.js' +import { LIMIT_BLOBS_PER_TX } from '../constants.js' +import { TransactionType } from '../types.js' +import { AccessLists, validateNotArray } from '../util.js' + +import { create4844BlobTx } from './constructors.js' import type { AccessList, AccessListBytes, TxData as AllTypesTxData, TxValuesArray as AllTypesTxValuesArray, - BlobEIP4844NetworkValuesArray, - JsonBlobTxNetworkWrapper, JsonTx, TxOptions, -} from './types.js' +} from '../types.js' import type { Common } from '@ethereumjs/common' -import type { Kzg } from '@ethereumjs/util' - -type TxData = AllTypesTxData[TransactionType.BlobEIP4844] -type TxValuesArray = AllTypesTxValuesArray[TransactionType.BlobEIP4844] - -const validateBlobTransactionNetworkWrapper = ( - blobVersionedHashes: Uint8Array[], - blobs: Uint8Array[], - commitments: Uint8Array[], - kzgProofs: Uint8Array[], - version: number, - kzg: Kzg -) => { - if (!(blobVersionedHashes.length === blobs.length && blobs.length === commitments.length)) { - throw new Error('Number of blobVersionedHashes, blobs, and commitments not all equal') - } - if (blobVersionedHashes.length === 0) { - throw new Error('Invalid transaction with empty blobs') - } - let isValid - try { - isValid = kzg.verifyBlobKzgProofBatch(blobs, commitments, kzgProofs) - } catch (error) { - throw new Error(`KZG verification of blobs fail with error=${error}`) - } - if (!isValid) { - throw new Error('KZG proof cannot be verified from blobs/commitments') - } - - for (let x = 0; x < blobVersionedHashes.length; x++) { - const computedVersionedHash = computeVersionedHash(commitments[x], version) - if (!equalsBytes(computedVersionedHash, blobVersionedHashes[x])) { - throw new Error(`commitment for blob at index ${x} does not match versionedHash`) - } - } -} +export type TxData = AllTypesTxData[TransactionType.BlobEIP4844] +export type TxValuesArray = AllTypesTxValuesArray[TransactionType.BlobEIP4844] /** * Typed transaction with a new gas fee market mechanism for transactions that include "blobs" of data @@ -133,7 +91,7 @@ export class BlobEIP4844Transaction extends BaseTransaction MAX_INTEGER) { const msg = this._errorMsg('gasLimit * maxFeePerGas cannot exceed MAX_INTEGER (2^256-1)') @@ -188,41 +146,6 @@ export class BlobEIP4844Transaction extends BaseTransaction acc + cur)) - txData.kzgCommitments = blobsToCommitments(kzg, txData.blobs as Uint8Array[]) - txData.blobVersionedHashes = commitmentsToVersionedHashes( - txData.kzgCommitments as Uint8Array[] - ) - txData.kzgProofs = blobsToProofs( - kzg, - txData.blobs as Uint8Array[], - txData.kzgCommitments as Uint8Array[] - ) - } - - return new BlobEIP4844Transaction(txData, opts) - } - /** * Returns the minimum of calculated priority fee (from maxFeePerGas and baseFee) and maxPriorityFeePerGas * @param baseFee Base fee retrieved from block @@ -231,203 +154,6 @@ export class BlobEIP4844Transaction extends BaseTransaction bytesToHex(hash)), - blobs: tx.blobs!.map((bytes) => bytesToHex(bytes)), - kzgCommitments: tx.kzgCommitments!.map((bytes) => bytesToHex(bytes)), - kzgProofs: tx.kzgProofs!.map((bytes) => bytesToHex(bytes)), - } - } - toJSON(): JsonTx { const accessListJSON = AccessLists.getAccessListJSON(this.accessList) const baseJson = super.toJSON() @@ -608,7 +304,7 @@ export class BlobEIP4844Transaction extends BaseTransaction MAX_INTEGER) { const msg = this._errorMsg('gasLimit * maxFeePerGas cannot exceed MAX_INTEGER (2^256-1)') @@ -338,7 +244,7 @@ export class EOACodeEIP7702Transaction extends BaseTransaction } } - protected static _validateNotArray(values: { [key: string]: any }) { - const txDataKeys = [ - 'nonce', - 'gasPrice', - 'gasLimit', - 'to', - 'value', - 'data', - 'v', - 'r', - 's', - 'type', - 'baseFee', - 'maxFeePerGas', - 'chainId', - ] - for (const [key, value] of Object.entries(values)) { - if (txDataKeys.includes(key)) { - if (Array.isArray(value)) { - throw new Error(`${key} cannot be an array`) - } - } - } - } - /** * Return a compact error string representation of the object */ diff --git a/packages/tx/src/index.ts b/packages/tx/src/index.ts index 7e3e2e4e97..7c89125bf5 100644 --- a/packages/tx/src/index.ts +++ b/packages/tx/src/index.ts @@ -1,8 +1,11 @@ -export { FeeMarketEIP1559Transaction } from './eip1559Transaction.js' -export { AccessListEIP2930Transaction } from './eip2930Transaction.js' -export { BlobEIP4844Transaction } from './eip4844Transaction.js' -export { EOACodeEIP7702Transaction } from './eip7702Transaction.js' -export { LegacyTransaction } from './legacyTransaction.js' +// Tx constructors +export * from './1559/index.js' +export * from './2930/index.js' +export * from './4844/index.js' +export * from './7702/index.js' +export * from './legacy/index.js' + +// Transaction factory export { createTxFromBlockBodyData, createTxFromJsonRpcProvider, @@ -10,4 +13,6 @@ export { createTxFromSerializedData, createTxFromTxData, } from './transactionFactory.js' + +// Types export * from './types.js' diff --git a/packages/tx/src/legacy/constructors.ts b/packages/tx/src/legacy/constructors.ts new file mode 100644 index 0000000000..002d32bd55 --- /dev/null +++ b/packages/tx/src/legacy/constructors.ts @@ -0,0 +1,69 @@ +import { RLP } from '@ethereumjs/rlp' +import { validateNoLeadingZeroes } from '@ethereumjs/util' + +import { LegacyTransaction } from './tx.js' + +import type { TxOptions } from '../types.js' +import type { TxData, TxValuesArray } from './tx.js' + +/** + * Instantiate a transaction from a data dictionary. + * + * Format: { nonce, gasPrice, gasLimit, to, value, data, v, r, s } + * + * Notes: + * - All parameters are optional and have some basic default values + */ +export function createLegacyTx(txData: TxData, opts: TxOptions = {}) { + return new LegacyTransaction(txData, opts) +} + +/** + * Create a transaction from an array of byte encoded values ordered according to the devp2p network encoding - format noted below. + * + * Format: `[nonce, gasPrice, gasLimit, to, value, data, v, r, s]` + */ +export function createLegacyTxFromBytesArray(values: TxValuesArray, opts: TxOptions = {}) { + // If length is not 6, it has length 9. If v/r/s are empty Uint8Arrays, it is still an unsigned transaction + // This happens if you get the RLP data from `raw()` + if (values.length !== 6 && values.length !== 9) { + throw new Error( + 'Invalid transaction. Only expecting 6 values (for unsigned tx) or 9 values (for signed tx).' + ) + } + + const [nonce, gasPrice, gasLimit, to, value, data, v, r, s] = values + + validateNoLeadingZeroes({ nonce, gasPrice, gasLimit, value, v, r, s }) + + return new LegacyTransaction( + { + nonce, + gasPrice, + gasLimit, + to, + value, + data, + v, + r, + s, + }, + opts + ) +} + +/** + * Instantiate a transaction from a RLP serialized tx. + * + * Format: `rlp([nonce, gasPrice, gasLimit, to, value, data, + * signatureV, signatureR, signatureS])` + */ +export function createLegacyTxFromRLP(serialized: Uint8Array, opts: TxOptions = {}) { + const values = RLP.decode(serialized) + + if (!Array.isArray(values)) { + throw new Error('Invalid serialized tx input. Must be array') + } + + return createLegacyTxFromBytesArray(values as TxValuesArray, opts) +} diff --git a/packages/tx/src/legacy/index.ts b/packages/tx/src/legacy/index.ts new file mode 100644 index 0000000000..8e919af7cc --- /dev/null +++ b/packages/tx/src/legacy/index.ts @@ -0,0 +1,2 @@ +export * from './constructors.js' +export { LegacyTransaction } from './tx.js' diff --git a/packages/tx/src/legacyTransaction.ts b/packages/tx/src/legacy/tx.ts similarity index 81% rename from packages/tx/src/legacyTransaction.ts rename to packages/tx/src/legacy/tx.ts index 74b9c7bdea..f0e59036a0 100644 --- a/packages/tx/src/legacyTransaction.ts +++ b/packages/tx/src/legacy/tx.ts @@ -8,24 +8,26 @@ import { bytesToBigInt, toBytes, unpadBytes, - validateNoLeadingZeroes, } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' -import { BaseTransaction } from './baseTransaction.js' -import * as Legacy from './capabilities/legacy.js' -import { Capability, TransactionType } from './types.js' +import { BaseTransaction } from '../baseTransaction.js' +import * as Legacy from '../capabilities/legacy.js' +import { Capability, TransactionType } from '../types.js' +import { validateNotArray } from '../util.js' + +import { createLegacyTx } from './constructors.js' import type { TxData as AllTypesTxData, TxValuesArray as AllTypesTxValuesArray, JsonTx, TxOptions, -} from './types.js' +} from '../types.js' import type { Common } from '@ethereumjs/common' -type TxData = AllTypesTxData[TransactionType.Legacy] -type TxValuesArray = AllTypesTxValuesArray[TransactionType.Legacy] +export type TxData = AllTypesTxData[TransactionType.Legacy] +export type TxValuesArray = AllTypesTxValuesArray[TransactionType.Legacy] function meetsEIP155(_v: bigint, chainId: bigint) { const v = Number(_v) @@ -42,67 +44,6 @@ export class LegacyTransaction extends BaseTransaction { public readonly common: Common private keccakFunction: (msg: Uint8Array) => Uint8Array - /** - * Instantiate a transaction from a data dictionary. - * - * Format: { nonce, gasPrice, gasLimit, to, value, data, v, r, s } - * - * Notes: - * - All parameters are optional and have some basic default values - */ - public static fromTxData(txData: TxData, opts: TxOptions = {}) { - return new LegacyTransaction(txData, opts) - } - - /** - * Instantiate a transaction from the serialized tx. - * - * Format: `rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])` - */ - public static fromSerializedTx(serialized: Uint8Array, opts: TxOptions = {}) { - const values = RLP.decode(serialized) - - if (!Array.isArray(values)) { - throw new Error('Invalid serialized tx input. Must be array') - } - - return this.fromValuesArray(values as TxValuesArray, opts) - } - - /** - * Create a transaction from a values array. - * - * Format: `[nonce, gasPrice, gasLimit, to, value, data, v, r, s]` - */ - public static fromValuesArray(values: TxValuesArray, opts: TxOptions = {}) { - // If length is not 6, it has length 9. If v/r/s are empty Uint8Arrays, it is still an unsigned transaction - // This happens if you get the RLP data from `raw()` - if (values.length !== 6 && values.length !== 9) { - throw new Error( - 'Invalid transaction. Only expecting 6 values (for unsigned tx) or 9 values (for signed tx).' - ) - } - - const [nonce, gasPrice, gasLimit, to, value, data, v, r, s] = values - - validateNoLeadingZeroes({ nonce, gasPrice, gasLimit, value, v, r, s }) - - return new LegacyTransaction( - { - nonce, - gasPrice, - gasLimit, - to, - value, - data, - v, - r, - s, - }, - opts - ) - } - /** * This constructor takes the values, validates them, assigns them and freezes the object. * @@ -123,7 +64,7 @@ export class LegacyTransaction extends BaseTransaction { } this._validateCannotExceedMaxInteger({ gasPrice: this.gasPrice }) - BaseTransaction._validateNotArray(txData) + validateNotArray(txData) if (this.common.gteHardfork('spuriousDragon')) { if (!this.isSigned()) { @@ -288,7 +229,7 @@ export class LegacyTransaction extends BaseTransaction { const opts = { ...this.txOptions, common: this.common } - return LegacyTransaction.fromTxData( + return createLegacyTx( { nonce: this.nonce, gasPrice: this.gasPrice, diff --git a/packages/tx/src/transactionFactory.ts b/packages/tx/src/transactionFactory.ts index 31344eb8c2..22ca0a7021 100644 --- a/packages/tx/src/transactionFactory.ts +++ b/packages/tx/src/transactionFactory.ts @@ -1,11 +1,15 @@ import { fetchFromProvider, getProvider } from '@ethereumjs/util' -import { FeeMarketEIP1559Transaction } from './eip1559Transaction.js' -import { AccessListEIP2930Transaction } from './eip2930Transaction.js' -import { BlobEIP4844Transaction } from './eip4844Transaction.js' -import { EOACodeEIP7702Transaction } from './eip7702Transaction.js' +import { create1559FeeMarketTx, create1559FeeMarketTxFromRLP } from './1559/constructors.js' +import { create2930AccessListTx, create2930AccessListTxFromRLP } from './2930/constructors.js' +import { create4844BlobTx, create4844BlobTxFromRLP } from './4844/constructors.js' +import { create7702EOACodeTx, create7702EOACodeTxFromRLP } from './7702/constructors.js' import { normalizeTxParams } from './fromRpc.js' -import { LegacyTransaction } from './legacyTransaction.js' +import { + createLegacyTx, + createLegacyTxFromBytesArray, + createLegacyTxFromRLP, +} from './legacy/constructors.js' import { TransactionType, isAccessListEIP2930TxData, @@ -29,18 +33,18 @@ export function createTxFromTxData( ): Transaction[T] { if (!('type' in txData) || txData.type === undefined) { // Assume legacy transaction - return LegacyTransaction.fromTxData(txData, txOptions) as Transaction[T] + return createLegacyTx(txData, txOptions) as Transaction[T] } else { if (isLegacyTxData(txData)) { - return LegacyTransaction.fromTxData(txData, txOptions) as Transaction[T] + return createLegacyTx(txData, txOptions) as Transaction[T] } else if (isAccessListEIP2930TxData(txData)) { - return AccessListEIP2930Transaction.fromTxData(txData, txOptions) as Transaction[T] + return create2930AccessListTx(txData, txOptions) as Transaction[T] } else if (isFeeMarketEIP1559TxData(txData)) { - return FeeMarketEIP1559Transaction.fromTxData(txData, txOptions) as Transaction[T] + return create1559FeeMarketTx(txData, txOptions) as Transaction[T] } else if (isBlobEIP4844TxData(txData)) { - return BlobEIP4844Transaction.fromTxData(txData, txOptions) as Transaction[T] + return create4844BlobTx(txData, txOptions) as Transaction[T] } else if (isEOACodeEIP7702TxData(txData)) { - return EOACodeEIP7702Transaction.fromTxData(txData, txOptions) as Transaction[T] + return create7702EOACodeTx(txData, txOptions) as Transaction[T] } else { throw new Error(`Tx instantiation with type ${(txData as TypedTxData)?.type} not supported`) } @@ -61,18 +65,18 @@ export function createTxFromSerializedData( // Determine the type. switch (data[0]) { case TransactionType.AccessListEIP2930: - return AccessListEIP2930Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + return create2930AccessListTxFromRLP(data, txOptions) as Transaction[T] case TransactionType.FeeMarketEIP1559: - return FeeMarketEIP1559Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + return create1559FeeMarketTxFromRLP(data, txOptions) as Transaction[T] case TransactionType.BlobEIP4844: - return BlobEIP4844Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + return create4844BlobTxFromRLP(data, txOptions) as Transaction[T] case TransactionType.EOACodeEIP7702: - return EOACodeEIP7702Transaction.fromSerializedTx(data, txOptions) as Transaction[T] + return create7702EOACodeTxFromRLP(data, txOptions) as Transaction[T] default: throw new Error(`TypedTransaction with ID ${data[0]} unknown`) } } else { - return LegacyTransaction.fromSerializedTx(data, txOptions) as Transaction[T] + return createLegacyTxFromRLP(data, txOptions) as Transaction[T] } } @@ -93,7 +97,7 @@ export function createTxFromBlockBodyData( return createTxFromSerializedData(data, txOptions) } else if (Array.isArray(data)) { // It is a legacy transaction - return LegacyTransaction.fromValuesArray(data, txOptions) + return createLegacyTxFromBytesArray(data, txOptions) } else { throw new Error('Cannot decode transaction: unknown type input') } diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index f37ee76b9a..e59367ab40 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -1,10 +1,10 @@ import { bytesToBigInt, toBytes } from '@ethereumjs/util' -import type { FeeMarketEIP1559Transaction } from './eip1559Transaction.js' -import type { AccessListEIP2930Transaction } from './eip2930Transaction.js' -import type { BlobEIP4844Transaction } from './eip4844Transaction.js' -import type { EOACodeEIP7702Transaction } from './eip7702Transaction.js' -import type { LegacyTransaction } from './legacyTransaction.js' +import type { FeeMarketEIP1559Transaction } from './1559/tx.js' +import type { AccessListEIP2930Transaction } from './2930/tx.js' +import type { BlobEIP4844Transaction } from './4844/tx.js' +import type { EOACodeEIP7702Transaction } from './7702/tx.js' +import type { LegacyTransaction } from './legacy/tx.js' import type { AccessList, AccessListBytes, diff --git a/packages/tx/src/util.ts b/packages/tx/src/util.ts index 4cc3428dea..afd2c185c6 100644 --- a/packages/tx/src/util.ts +++ b/packages/tx/src/util.ts @@ -223,3 +223,28 @@ export class AuthorizationLists { export function txTypeBytes(txType: TransactionType): Uint8Array { return hexToBytes(`0x${txType.toString(16).padStart(2, '0')}`) } + +export function validateNotArray(values: { [key: string]: any }) { + const txDataKeys = [ + 'nonce', + 'gasPrice', + 'gasLimit', + 'to', + 'value', + 'data', + 'v', + 'r', + 's', + 'type', + 'baseFee', + 'maxFeePerGas', + 'chainId', + ] + for (const [key, value] of Object.entries(values)) { + if (txDataKeys.includes(key)) { + if (Array.isArray(value)) { + throw new Error(`${key} cannot be an array`) + } + } + } +} diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index a3bceeb764..6c93a58b3c 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -18,6 +18,15 @@ import { FeeMarketEIP1559Transaction, LegacyTransaction, TransactionType, + create1559FeeMarketTx, + create1559FeeMarketTxFromRLP, + create2930AccessListTx, + create2930AccessListTxFromBytesArray, + create2930AccessListTxFromRLP, + createEIP1559FeeMarketTxFromBytesArray, + createLegacyTx, + createLegacyTxFromBytesArray, + createLegacyTxFromRLP, } from '../src/index.js' import eip1559Fixtures from './json/eip1559txs.json' @@ -33,21 +42,17 @@ describe('[BaseTransaction]', () => { const legacyTxs: BaseTransaction[] = [] for (const tx of legacyFixtures.slice(0, 4)) { - legacyTxs.push(LegacyTransaction.fromTxData(tx.data as LegacyTxData, { common })) + legacyTxs.push(createLegacyTx(tx.data as LegacyTxData, { common })) } const eip2930Txs: BaseTransaction[] = [] for (const tx of eip2930Fixtures) { - eip2930Txs.push( - AccessListEIP2930Transaction.fromTxData(tx.data as AccessListEIP2930TxData, { common }) - ) + eip2930Txs.push(create2930AccessListTx(tx.data as AccessListEIP2930TxData, { common })) } const eip1559Txs: BaseTransaction[] = [] for (const tx of eip1559Fixtures) { - eip1559Txs.push( - FeeMarketEIP1559Transaction.fromTxData(tx.data as FeeMarketEIP1559TxData, { common }) - ) + eip1559Txs.push(create1559FeeMarketTx(tx.data as FeeMarketEIP1559TxData, { common })) } const zero = new Uint8Array(0) @@ -60,6 +65,11 @@ describe('[BaseTransaction]', () => { txs: legacyTxs, fixtures: legacyFixtures, activeCapabilities: [], + create: { + txData: createLegacyTx, + rlp: createLegacyTxFromRLP, + bytesArray: createLegacyTxFromBytesArray, + }, notActiveCapabilities: [ Capability.EIP1559FeeMarket, Capability.EIP2718TypedTransaction, @@ -75,6 +85,11 @@ describe('[BaseTransaction]', () => { txs: eip2930Txs, fixtures: eip2930Fixtures, activeCapabilities: [Capability.EIP2718TypedTransaction, Capability.EIP2930AccessLists], + create: { + txData: create2930AccessListTx, + rlp: create2930AccessListTxFromRLP, + bytesArray: create2930AccessListTxFromBytesArray, + }, notActiveCapabilities: [Capability.EIP1559FeeMarket, 9999], }, { @@ -89,13 +104,18 @@ describe('[BaseTransaction]', () => { Capability.EIP2718TypedTransaction, Capability.EIP2930AccessLists, ], + create: { + txData: create1559FeeMarketTx, + rlp: create1559FeeMarketTxFromRLP, + bytesArray: createEIP1559FeeMarketTxFromBytesArray, + }, notActiveCapabilities: [9999], }, ] it('Initialization', () => { for (const txType of txTypes) { - let tx = txType.class.fromTxData({}, { common }) + let tx = txType.create.txData({}, { common }) assert.equal( tx.common.hardfork(), 'london', @@ -107,7 +127,7 @@ describe('[BaseTransaction]', () => { chain: Chain.Mainnet, hardfork: Hardfork.London, }) - tx = txType.class.fromTxData({}, { common: initCommon }) + tx = txType.create.txData({}, { common: initCommon }) assert.equal( tx.common.hardfork(), 'london', @@ -121,7 +141,7 @@ describe('[BaseTransaction]', () => { `${txType.name}: should stay on correct HF if outer common HF changes` ) - tx = txType.class.fromTxData({}, { common, freeze: false }) + tx = txType.create.txData({}, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), `${txType.name}: tx should not be frozen when freeze deactivated in options` @@ -129,10 +149,10 @@ describe('[BaseTransaction]', () => { // Perform the same test as above, but now using a different construction method. This also implies that passing on the // options object works as expected. - tx = txType.class.fromTxData({}, { common, freeze: false }) + tx = txType.create.txData({}, { common, freeze: false }) const rlpData = tx.serialize() - tx = txType.class.fromSerializedTx(rlpData, { common }) + tx = txType.create.rlp(rlpData, { common }) assert.equal( tx.type, txType.type, @@ -141,16 +161,16 @@ describe('[BaseTransaction]', () => { assert.ok(Object.isFrozen(tx), `${txType.name}: tx should be frozen by default`) - tx = txType.class.fromSerializedTx(rlpData, { common, freeze: false }) + tx = txType.create.rlp(rlpData, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), `${txType.name}: tx should not be frozen when freeze deactivated in options` ) - tx = txType.class.fromValuesArray(txType.values as any, { common }) + tx = txType.create.bytesArray(txType.values as any, { common }) assert.ok(Object.isFrozen(tx), `${txType.name}: tx should be frozen by default`) - tx = txType.class.fromValuesArray(txType.values as any, { common, freeze: false }) + tx = txType.create.bytesArray(txType.values as any, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), `${txType.name}: tx should not be frozen when freeze deactivated in options` @@ -162,7 +182,7 @@ describe('[BaseTransaction]', () => { let rlpData: any = legacyTxs[0].raw() rlpData[0] = toBytes('0x0') try { - LegacyTransaction.fromValuesArray(rlpData) + createLegacyTxFromBytesArray(rlpData) assert.fail('should have thrown when nonce has leading zeroes') } catch (err: any) { assert.ok( @@ -173,7 +193,7 @@ describe('[BaseTransaction]', () => { rlpData[0] = toBytes('0x') rlpData[6] = toBytes('0x0') try { - LegacyTransaction.fromValuesArray(rlpData) + createLegacyTxFromBytesArray(rlpData) assert.fail('should have thrown when v has leading zeroes') } catch (err: any) { assert.ok( @@ -184,7 +204,7 @@ describe('[BaseTransaction]', () => { rlpData = eip2930Txs[0].raw() rlpData[3] = toBytes('0x0') try { - AccessListEIP2930Transaction.fromValuesArray(rlpData) + create2930AccessListTxFromBytesArray(rlpData) assert.fail('should have thrown when gasLimit has leading zeroes') } catch (err: any) { assert.ok( @@ -195,7 +215,7 @@ describe('[BaseTransaction]', () => { rlpData = eip1559Txs[0].raw() rlpData[2] = toBytes('0x0') try { - FeeMarketEIP1559Transaction.fromValuesArray(rlpData) + createEIP1559FeeMarketTxFromBytesArray(rlpData) assert.fail('should have thrown when maxPriorityFeePerGas has leading zeroes') } catch (err: any) { assert.ok( @@ -209,11 +229,11 @@ describe('[BaseTransaction]', () => { for (const txType of txTypes) { for (const tx of txType.txs) { assert.ok( - txType.class.fromSerializedTx(tx.serialize(), { common }), + txType.create.rlp(tx.serialize(), { common }), `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()` ) assert.ok( - txType.class.fromSerializedTx(tx.serialize(), { common }), + txType.create.rlp(tx.serialize(), { common }), `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()` ) } @@ -243,7 +263,7 @@ describe('[BaseTransaction]', () => { for (const txType of txTypes) { for (const tx of txType.txs) { assert.ok( - txType.class.fromValuesArray(tx.raw() as any, { common }), + txType.create.bytesArray(tx.raw() as any, { common }), `${txType.name}: should do roundtrip raw() -> fromValuesArray()` ) } @@ -263,7 +283,7 @@ describe('[BaseTransaction]', () => { for (const txFixture of txType.fixtures.slice(0, 4)) { // set `s` to a single zero txFixture.data.s = '0x' + '0' - const tx = txType.class.fromTxData((txFixture as any).data, { common }) + const tx = txType.create.txData((txFixture as any).data, { common }) assert.equal(tx.verifySignature(), false, `${txType.name}: signature should not be valid`) assert.ok( tx.getValidationErrors().includes('Invalid Signature'), @@ -298,7 +318,7 @@ describe('[BaseTransaction]', () => { ...txType.txs, // add unsigned variants ...txType.txs.map((tx) => - txType.class.fromTxData({ + txType.create.txData({ ...tx, v: undefined, r: undefined, @@ -386,7 +406,7 @@ describe('[BaseTransaction]', () => { it('initialization with defaults', () => { const bufferZero = toBytes('0x') - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ nonce: undefined, gasLimit: undefined, gasPrice: undefined, @@ -409,7 +429,7 @@ describe('[BaseTransaction]', () => { }) it('_validateCannotExceedMaxInteger()', () => { - const tx = FeeMarketEIP1559Transaction.fromTxData(eip1559Txs[0]) + const tx = create1559FeeMarketTx(eip1559Txs[0]) try { ;(tx as any)._validateCannotExceedMaxInteger({ a: MAX_INTEGER }, 256, true) } catch (err: any) { diff --git a/packages/tx/test/eip1559.spec.ts b/packages/tx/test/eip1559.spec.ts index a0833bfef6..8588d7929b 100644 --- a/packages/tx/test/eip1559.spec.ts +++ b/packages/tx/test/eip1559.spec.ts @@ -3,7 +3,7 @@ import { RLP } from '@ethereumjs/rlp' import { TWO_POW256, ecsign, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { FeeMarketEIP1559Transaction } from '../src/index.js' +import { create1559FeeMarketTx } from '../src/index.js' import testdata from './json/eip1559.json' // Source: Besu @@ -60,7 +60,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { ) { txData[value] = testCase assert.throws(() => { - FeeMarketEIP1559Transaction.fromTxData(txData) + create1559FeeMarketTx(txData) }) } } @@ -68,7 +68,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { }) it('getUpfrontCost()', () => { - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 8, @@ -89,7 +89,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { }) it('getEffectivePriorityFee()', () => { - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 8, @@ -109,7 +109,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { for (let index = 0; index < testdata.length; index++) { const data = testdata[index] const pkey = hexToBytes(data.privateKey as PrefixedHexString) - const txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { common }) + const txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common }) const signed = txn.sign(pkey) const rlpSerialized = RLP.encode(Uint8Array.from(signed.serialize())) assert.ok( @@ -121,7 +121,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('addSignature() -> correctly adds correct signature values', () => { const privKey = hexToBytes(testdata[0].privateKey as PrefixedHexString) - const tx = FeeMarketEIP1559Transaction.fromTxData({}) + const tx = create1559FeeMarketTx({}) const signedTx = tx.sign(privKey) const addSignatureTx = tx.addSignature(signedTx.v!, signedTx.r!, signedTx.s!) @@ -130,7 +130,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('addSignature() -> correctly converts raw ecrecover values', () => { const privKey = hexToBytes(testdata[0].privateKey as PrefixedHexString) - const tx = FeeMarketEIP1559Transaction.fromTxData({}) + const tx = create1559FeeMarketTx({}) const msgHash = tx.getHashedMessageToSign() const { v, r, s } = ecsign(msgHash, privKey) @@ -143,7 +143,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('addSignature() -> throws when adding the wrong v value', () => { const privKey = hexToBytes(testdata[0].privateKey as PrefixedHexString) - const tx = FeeMarketEIP1559Transaction.fromTxData({}) + const tx = create1559FeeMarketTx({}) const msgHash = tx.getHashedMessageToSign() const { v, r, s } = ecsign(msgHash, privKey) @@ -157,7 +157,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('hash()', () => { const data = testdata[0] const pkey = hexToBytes(data.privateKey as PrefixedHexString) - let txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { common }) + let txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common }) let signed = txn.sign(pkey) const expectedHash = hexToBytes( '0x2e564c87eb4b40e7f469b2eec5aa5d18b0b46a24e8bf0919439cfb0e8fcae446' @@ -166,7 +166,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { equalsBytes(signed.hash(), expectedHash), 'Should provide the correct hash when frozen' ) - txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { + txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common, freeze: false, }) @@ -180,7 +180,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('freeze property propagates from unsigned tx to signed tx', () => { const data = testdata[0] const pkey = hexToBytes(data.privateKey as PrefixedHexString) - const txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { + const txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common, freeze: false, }) @@ -192,7 +192,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('common propagates from the common of tx, not the common in TxOptions', () => { const data = testdata[0] const pkey = hexToBytes(data.privateKey as PrefixedHexString) - const txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { + const txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common, freeze: false, }) @@ -214,7 +214,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { }) it('unsigned tx -> getMessageToSign()/getHashedMessageToSign()', () => { - const unsignedTx = FeeMarketEIP1559Transaction.fromTxData( + const unsignedTx = create1559FeeMarketTx( { data: hexToBytes('0x010200'), to: validAddress, @@ -241,7 +241,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('toJSON()', () => { const data = testdata[0] const pkey = hexToBytes(data.privateKey as PrefixedHexString) - const txn = FeeMarketEIP1559Transaction.fromTxData(data as FeeMarketEIP1559TxData, { common }) + const txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common }) const signed = txn.sign(pkey) const json = signed.toJSON() @@ -266,7 +266,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { it('Fee validation', () => { assert.doesNotThrow(() => { - FeeMarketEIP1559Transaction.fromTxData( + create1559FeeMarketTx( { maxFeePerGas: TWO_POW256 - BigInt(1), maxPriorityFeePerGas: 100, @@ -278,7 +278,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { }, 'fee can be 2^256 - 1') assert.throws( () => { - FeeMarketEIP1559Transaction.fromTxData( + create1559FeeMarketTx( { maxFeePerGas: TWO_POW256 - BigInt(1), maxPriorityFeePerGas: 100, @@ -294,7 +294,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { ) assert.throws( () => { - FeeMarketEIP1559Transaction.fromTxData( + create1559FeeMarketTx( { maxFeePerGas: 1, maxPriorityFeePerGas: 2, diff --git a/packages/tx/test/eip4844.spec.ts b/packages/tx/test/eip4844.spec.ts index f97501f5b7..4bf52bfe47 100644 --- a/packages/tx/test/eip4844.spec.ts +++ b/packages/tx/test/eip4844.spec.ts @@ -16,7 +16,14 @@ import { loadKZG } from 'kzg-wasm' import { assert, beforeAll, describe, it } from 'vitest' import gethGenesis from '../../block/test/testdata/4844-hardfork.json' -import { BlobEIP4844Transaction, createTxFromTxData } from '../src/index.js' +import { + blobTxNetworkWrapperToJSON, + create4844BlobTx, + create4844BlobTxFromRLP, + create4844BlobTxFromSerializedNetworkWrapper, + createMinimal4844TxFromNetworkWrapper, + createTxFromTxData, +} from '../src/index.js' import blobTx from './json/serialized4844tx.json' @@ -37,7 +44,7 @@ describe('EIP4844 addSignature tests', () => { }) it('addSignature() -> correctly adds correct signature values', () => { const privateKey = pk - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], @@ -52,7 +59,7 @@ describe('EIP4844 addSignature tests', () => { it('addSignature() -> correctly converts raw ecrecover values', () => { const privKey = pk - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], @@ -71,7 +78,7 @@ describe('EIP4844 addSignature tests', () => { it('addSignature() -> throws when adding the wrong v value', () => { const privKey = pk - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], @@ -106,19 +113,19 @@ describe('EIP4844 constructor tests - valid scenarios', () => { maxFeePerBlobGas: 1n, to: Address.zero(), } - const tx = BlobEIP4844Transaction.fromTxData(txData, { common }) + const tx = create4844BlobTx(txData, { common }) assert.equal(tx.type, 3, 'successfully instantiated a blob transaction from txData') const factoryTx = createTxFromTxData(txData, { common }) assert.equal(factoryTx.type, 3, 'instantiated a blob transaction from the tx factory') const serializedTx = tx.serialize() assert.equal(serializedTx[0], 3, 'successfully serialized a blob tx') - const deserializedTx = BlobEIP4844Transaction.fromSerializedTx(serializedTx, { common }) + const deserializedTx = create4844BlobTxFromRLP(serializedTx, { common }) assert.equal(deserializedTx.type, 3, 'deserialized a blob tx') const signedTx = tx.sign(pk) const sender = signedTx.getSenderAddress().toString() - const decodedTx = BlobEIP4844Transaction.fromSerializedTx(signedTx.serialize(), { common }) + const decodedTx = create4844BlobTxFromRLP(signedTx.serialize(), { common }) assert.equal( decodedTx.getSenderAddress().toString(), sender, @@ -168,7 +175,7 @@ describe('fromTxData using from a json', () => { chainId: Number(txData.chainId), }) try { - const tx = BlobEIP4844Transaction.fromTxData(txData as BlobEIP4844TxData, { common: c }) + const tx = create4844BlobTx(txData as BlobEIP4844TxData, { common: c }) assert.ok(true, 'Should be able to parse a json data and hash it') assert.equal(typeof tx.maxFeePerBlobGas, 'bigint', 'should be able to parse correctly') @@ -184,7 +191,7 @@ describe('fromTxData using from a json', () => { 'toJSON should give correct json' ) - const fromSerializedTx = BlobEIP4844Transaction.fromSerializedTx( + const fromSerializedTx = create4844BlobTxFromRLP( hexToBytes(txMeta.serialized as PrefixedHexString), { common: c } ) @@ -229,7 +236,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { ], } try { - BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...shortVersionHash }, { common }) + create4844BlobTx({ ...baseTxData, ...shortVersionHash }, { common }) } catch (err: any) { assert.ok( err.message.includes('versioned hash is invalid length'), @@ -237,7 +244,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { ) } try { - BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...invalidVersionHash }, { common }) + create4844BlobTx({ ...baseTxData, ...invalidVersionHash }, { common }) } catch (err: any) { assert.ok( err.message.includes('does not start with KZG commitment'), @@ -245,7 +252,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { ) } try { - BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...tooManyBlobs }, { common }) + create4844BlobTx({ ...baseTxData, ...tooManyBlobs }, { common }) } catch (err: any) { assert.ok( err.message.includes('tx can contain at most'), @@ -271,7 +278,7 @@ describe('Network wrapper tests', () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobsToProofs(kzg, blobs, commitments) - const unsignedTx = BlobEIP4844Transaction.fromTxData( + const unsignedTx = create4844BlobTx( { blobVersionedHashes, blobs, @@ -288,7 +295,7 @@ describe('Network wrapper tests', () => { const sender = signedTx.getSenderAddress().toString() const wrapper = signedTx.serializeNetworkWrapper() - const jsonData = BlobEIP4844Transaction.networkWrapperToJson(wrapper, { common }) + const jsonData = blobTxNetworkWrapperToJSON(wrapper, { common }) assert.equal(jsonData.blobs?.length, blobs.length, 'contains the correct number of blobs') for (let i = 0; i < jsonData.blobs.length; i++) { const b1 = jsonData.blobs[i] @@ -316,7 +323,7 @@ describe('Network wrapper tests', () => { assert.equal(p1, p2, 'contains the same proofs') } - const deserializedTx = BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(wrapper, { + const deserializedTx = create4844BlobTxFromSerializedNetworkWrapper(wrapper, { common, }) @@ -331,14 +338,14 @@ describe('Network wrapper tests', () => { sender, 'decoded sender address correctly' ) - const minimalTx = BlobEIP4844Transaction.minimalFromNetworkWrapper(deserializedTx, { common }) + const minimalTx = createMinimal4844TxFromNetworkWrapper(deserializedTx, { common }) assert.ok(minimalTx.blobs === undefined, 'minimal representation contains no blobs') assert.ok( equalsBytes(minimalTx.hash(), deserializedTx.hash()), 'has the same hash as the network wrapper version' ) - const simpleBlobTx = BlobEIP4844Transaction.fromTxData( + const simpleBlobTx = create4844BlobTx( { blobsData: ['hello world'], maxFeePerBlobGas: 100000000n, @@ -356,7 +363,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromTxData( + create4844BlobTx( { blobsData: ['hello world'], blobs: ['hello world' as any], @@ -373,7 +380,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromTxData( + create4844BlobTx( { blobsData: ['hello world'], kzgCommitments: ['0xabcd'], @@ -390,7 +397,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromTxData( + create4844BlobTx( { blobsData: ['hello world'], blobVersionedHashes: ['0x01cd'], @@ -407,7 +414,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromTxData( + create4844BlobTx( { blobsData: ['hello world'], kzgProofs: ['0x01cd'], @@ -424,7 +431,7 @@ describe('Network wrapper tests', () => { assert.throws( () => { - BlobEIP4844Transaction.fromTxData( + create4844BlobTx( { blobVersionedHashes: [], blobs: [], @@ -442,7 +449,7 @@ describe('Network wrapper tests', () => { 'throws a transaction with no blobs' ) - const txWithMissingBlob = BlobEIP4844Transaction.fromTxData( + const txWithMissingBlob = create4844BlobTx( { blobVersionedHashes, blobs: blobs.slice(1), @@ -459,7 +466,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(serializedWithMissingBlob, { + create4844BlobTxFromSerializedNetworkWrapper(serializedWithMissingBlob, { common, }), 'Number of blobVersionedHashes, blobs, and commitments not all equal', @@ -470,7 +477,7 @@ describe('Network wrapper tests', () => { const mangledValue = commitments[0][0] commitments[0][0] = 154 - const txWithInvalidCommitment = BlobEIP4844Transaction.fromTxData( + const txWithInvalidCommitment = create4844BlobTx( { blobVersionedHashes, blobs, @@ -487,7 +494,7 @@ describe('Network wrapper tests', () => { assert.throws( () => - BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(serializedWithInvalidCommitment, { + create4844BlobTxFromSerializedNetworkWrapper(serializedWithInvalidCommitment, { common, }), 'KZG proof cannot be verified from blobs/commitments', @@ -498,7 +505,7 @@ describe('Network wrapper tests', () => { blobVersionedHashes[0][1] = 2 commitments[0][0] = mangledValue - const txWithInvalidVersionedHashes = BlobEIP4844Transaction.fromTxData( + const txWithInvalidVersionedHashes = create4844BlobTx( { blobVersionedHashes, blobs, @@ -515,12 +522,9 @@ describe('Network wrapper tests', () => { txWithInvalidVersionedHashes.serializeNetworkWrapper() assert.throws( () => - BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper( - serializedWithInvalidVersionedHashes, - { - common, - } - ), + create4844BlobTxFromSerializedNetworkWrapper(serializedWithInvalidVersionedHashes, { + common, + }), 'commitment for blob at index 0 does not match versionedHash', undefined, 'throws when versioned hashes dont match kzg commitments' @@ -539,7 +543,7 @@ describe('hash() and signature verification', () => { }) }) it('should work', async () => { - const unsignedTx = BlobEIP4844Transaction.fromTxData( + const unsignedTx = create4844BlobTx( { chainId: 1, nonce: 1, @@ -585,7 +589,7 @@ it('getEffectivePriorityFee()', async () => { hardfork: Hardfork.Cancun, customCrypto: { kzg }, }) - const tx = BlobEIP4844Transaction.fromTxData( + const tx = create4844BlobTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 8, @@ -651,7 +655,7 @@ describe('Network wrapper deserialization test', () => { const proofs = blobsToProofs(kzg, blobs, commitments) const wrapper = hexToBytes(blobTx.tx as PrefixedHexString) - const deserializedTx = BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(wrapper, { + const deserializedTx = create4844BlobTxFromSerializedNetworkWrapper(wrapper, { common, }) const jsonData = deserializedTx.toJSON() diff --git a/packages/tx/test/eip7702.spec.ts b/packages/tx/test/eip7702.spec.ts index 3e7383681b..6213a1085f 100644 --- a/packages/tx/test/eip7702.spec.ts +++ b/packages/tx/test/eip7702.spec.ts @@ -2,7 +2,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { EOACodeEIP7702Transaction } from '../src/index.js' +import { create7702EOACodeTx } from '../src/index.js' import type { PrefixedHexString } from '@ethereumjs/util' @@ -15,7 +15,7 @@ const ones32 = `0x${'01'.repeat(32)}` as PrefixedHexString describe('[EOACodeEIP7702Transaction]', () => { it('sign()', () => { - const txn = EOACodeEIP7702Transaction.fromTxData( + const txn = create7702EOACodeTx( { value: 1, maxFeePerGas: 1, @@ -37,7 +37,7 @@ describe('[EOACodeEIP7702Transaction]', () => { it('valid and invalid authorizationList values', () => { assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -55,7 +55,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'address length should be 20 bytes') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -73,7 +73,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'nonce list should consist of at most 1 item') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -91,7 +91,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 's is not defined') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -109,7 +109,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'r is not defined') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -127,7 +127,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'yParity is not defined') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -145,7 +145,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'nonce is not defined') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -163,7 +163,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'address is not defined') assert.throws(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { @@ -181,7 +181,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, 'chainId is not defined') assert.doesNotThrow(() => { - EOACodeEIP7702Transaction.fromTxData( + create7702EOACodeTx( { authorizationList: [ { diff --git a/packages/tx/test/inputValue.spec.ts b/packages/tx/test/inputValue.spec.ts index 2feac7f6f4..9d718a3cbd 100644 --- a/packages/tx/test/inputValue.spec.ts +++ b/packages/tx/test/inputValue.spec.ts @@ -3,10 +3,11 @@ import { Address, hexToBytes, toBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { - AccessListEIP2930Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, TransactionType, + create2930AccessListTxFromBytesArray, + createEIP1559FeeMarketTxFromBytesArray, + createLegacyTx, + createLegacyTxFromBytesArray, createTxFromTxData, } from '../src/index.js' @@ -117,7 +118,7 @@ describe('[Transaction Input Values]', () => { }) const randomSample = getRandomSubarray(legacyTxData, 100) for (const txData of randomSample) { - const tx = LegacyTransaction.fromTxData(txData, { common }) + const tx = createLegacyTx(txData, { common }) assert.throws(() => tx.hash(), undefined, undefined, 'tx.hash() throws if tx is unsigned') } }) @@ -136,7 +137,7 @@ describe('[Transaction Input Values]', () => { const randomSample = getRandomSubarray(eip1559TxData, 100) for (const txData of randomSample) { - const tx = LegacyTransaction.fromTxData(txData, { common }) + const tx = createLegacyTx(txData, { common }) assert.throws(() => tx.hash(), undefined, undefined, 'tx.hash() should throw if unsigned') } }) @@ -161,21 +162,19 @@ describe('[Invalid Array Input values]', () => { switch (txType) { case TransactionType.Legacy: assert.throws(() => - LegacyTransaction.fromValuesArray( - rawValues as TxValuesArray[TransactionType.Legacy] - ) + createLegacyTxFromBytesArray(rawValues as TxValuesArray[TransactionType.Legacy]) ) break case TransactionType.AccessListEIP2930: assert.throws(() => - AccessListEIP2930Transaction.fromValuesArray( + create2930AccessListTxFromBytesArray( rawValues as TxValuesArray[TransactionType.AccessListEIP2930] ) ) break case TransactionType.FeeMarketEIP1559: assert.throws(() => - FeeMarketEIP1559Transaction.fromValuesArray( + createEIP1559FeeMarketTxFromBytesArray( rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559] ) ) @@ -243,14 +242,14 @@ describe('[Invalid Access Lists]', () => { switch (txType) { case TransactionType.AccessListEIP2930: assert.throws(() => - AccessListEIP2930Transaction.fromValuesArray( + create2930AccessListTxFromBytesArray( rawValues as TxValuesArray[TransactionType.AccessListEIP2930] ) ) break case TransactionType.FeeMarketEIP1559: assert.throws(() => - FeeMarketEIP1559Transaction.fromValuesArray( + createEIP1559FeeMarketTxFromBytesArray( rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559] ) ) diff --git a/packages/tx/test/legacy.spec.ts b/packages/tx/test/legacy.spec.ts index c3d23bfc7a..9026ad2441 100644 --- a/packages/tx/test/legacy.spec.ts +++ b/packages/tx/test/legacy.spec.ts @@ -11,7 +11,11 @@ import { } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { LegacyTransaction } from '../src/index.js' +import { + createLegacyTx, + createLegacyTxFromBytesArray, + createLegacyTxFromRLP, +} from '../src/index.js' import txFixturesEip155 from './json/ttTransactionTestEip155VitaliksTests.json' import txFixtures from './json/txs.json' @@ -48,7 +52,7 @@ describe('[Transaction]', () => { for (const testCase of cases) { txData[value] = testCase assert.throws(() => { - LegacyTransaction.fromTxData(txData) + createLegacyTx(txData) }) } } @@ -57,27 +61,27 @@ describe('[Transaction]', () => { it('Initialization', () => { const nonEIP2930Common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) assert.ok( - LegacyTransaction.fromTxData({}, { common: nonEIP2930Common }), + createLegacyTx({}, { common: nonEIP2930Common }), 'should initialize on a pre-Berlin Harfork (EIP-2930 not activated)' ) const txData = txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) txData[6] = intToBytes(45) // v with 0-parity and chain ID 5 - let tx = LegacyTransaction.fromValuesArray(txData) + let tx = createLegacyTxFromBytesArray(txData) assert.ok( tx.common.chainId() === BigInt(5), 'should initialize Common with chain ID (supported) derived from v value (v with 0-parity)' ) txData[6] = intToBytes(46) // v with 1-parity and chain ID 5 - tx = LegacyTransaction.fromValuesArray(txData) + tx = createLegacyTxFromBytesArray(txData) assert.ok( tx.common.chainId() === BigInt(5), 'should initialize Common with chain ID (supported) derived from v value (v with 1-parity)' ) txData[6] = intToBytes(2033) // v with 0-parity and chain ID 999 - tx = LegacyTransaction.fromValuesArray(txData) + tx = createLegacyTxFromBytesArray(txData) assert.equal( tx.common.chainId(), BigInt(999), @@ -85,7 +89,7 @@ describe('[Transaction]', () => { ) txData[6] = intToBytes(2034) // v with 1-parity and chain ID 999 - tx = LegacyTransaction.fromValuesArray(txData) + tx = createLegacyTxFromBytesArray(txData) assert.equal( tx.common.chainId(), BigInt(999), @@ -96,7 +100,7 @@ describe('[Transaction]', () => { it('Initialization -> decode with fromValuesArray()', () => { for (const tx of txFixtures.slice(0, 4)) { const txData = tx.raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) - const pt = LegacyTransaction.fromValuesArray(txData) + const pt = createLegacyTxFromBytesArray(txData) assert.equal(bytesToHex(unpadBytes(toBytes(pt.nonce))), tx.raw[0]) assert.equal(bytesToHex(toBytes(pt.gasPrice)), tx.raw[1]) @@ -113,31 +117,31 @@ describe('[Transaction]', () => { }) it('Initialization -> should accept lesser r values', () => { - const tx = LegacyTransaction.fromTxData({ r: bytesToBigInt(hexToBytes('0x0005')) }) + const tx = createLegacyTx({ r: bytesToBigInt(hexToBytes('0x0005')) }) assert.equal(tx.r!.toString(16), '5') }) it('Initialization -> throws when creating a a transaction with incompatible chainid and v value', () => { let common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Petersburg }) - let tx = LegacyTransaction.fromTxData({}, { common }) + let tx = createLegacyTx({}, { common }) assert.equal(tx.common.chainId(), BigInt(5)) const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) tx = tx.sign(privKey) const serialized = tx.serialize() common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) - assert.throws(() => LegacyTransaction.fromSerializedTx(serialized, { common })) + assert.throws(() => createLegacyTxFromRLP(serialized, { common })) }) it('Initialization -> throws if v is set to an EIP155-encoded value incompatible with the chain id', () => { assert.throws(() => { const common = new Common({ chain: 42, hardfork: Hardfork.Petersburg }) - LegacyTransaction.fromTxData({ v: BigInt(1) }, { common }) + createLegacyTx({ v: BigInt(1) }, { common }) }) }) it('addSignature() -> correctly adds correct signature values', () => { const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) - const tx = LegacyTransaction.fromTxData({}) + const tx = createLegacyTx({}) const signedTx = tx.sign(privKey) const addSignatureTx = tx.addSignature(signedTx.v!, signedTx.r!, signedTx.s!) @@ -146,7 +150,7 @@ describe('[Transaction]', () => { it('addSignature() -> correctly adds correct signature values from ecrecover with ChainID protection enabled', () => { const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) - const tx = LegacyTransaction.fromTxData({}, { common: new Common({ chain: Chain.Sepolia }) }) + const tx = createLegacyTx({}, { common: new Common({ chain: Chain.Sepolia }) }) const signedTx = tx.sign(privKey) // `convertV` set to false, since we use the raw value from the signed tx const addSignatureTx = tx.addSignature(signedTx.v!, signedTx.r!, signedTx.s!, false) @@ -157,7 +161,7 @@ describe('[Transaction]', () => { it('addSignature() -> throws when adding the wrong v value', () => { const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) - const tx = LegacyTransaction.fromTxData({}, { common: new Common({ chain: Chain.Sepolia }) }) + const tx = createLegacyTx({}, { common: new Common({ chain: Chain.Sepolia }) }) const signedTx = tx.sign(privKey) // `convertV` set to true: this will apply EIP-155 replay transaction twice, so it should throw! assert.throws(() => { @@ -178,20 +182,20 @@ describe('[Transaction]', () => { }) it('getBaseFee() -> should return base fee', () => { - const tx = LegacyTransaction.fromTxData({}) + const tx = createLegacyTx({}) assert.equal(tx.getBaseFee(), BigInt(53000)) }) it('getDataFee() -> should return data fee', () => { - let tx = LegacyTransaction.fromTxData({}) + let tx = createLegacyTx({}) assert.equal(tx.getDataFee(), BigInt(0)) - tx = LegacyTransaction.fromValuesArray( + tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) ) assert.equal(tx.getDataFee(), BigInt(1716)) - tx = LegacyTransaction.fromValuesArray( + tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { freeze: false } ) @@ -200,10 +204,10 @@ describe('[Transaction]', () => { it('getDataFee() -> should return correct data fee for istanbul', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - let tx = LegacyTransaction.fromTxData({}, { common }) + let tx = createLegacyTx({}, { common }) assert.equal(tx.getDataFee(), BigInt(0)) - tx = LegacyTransaction.fromValuesArray( + tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, @@ -214,7 +218,7 @@ describe('[Transaction]', () => { it('getDataFee() -> should invalidate cached value on hardfork change', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) - const tx = LegacyTransaction.fromValuesArray( + const tx = createLegacyTxFromBytesArray( txFixtures[0].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, @@ -226,7 +230,7 @@ describe('[Transaction]', () => { }) it('getEffectivePriorityFee() -> should return correct values', () => { - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasPrice: BigInt(100), }) @@ -237,7 +241,7 @@ describe('[Transaction]', () => { }) it('getUpfrontCost() -> should return upfront cost', () => { - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasPrice: 1000, gasLimit: 10000000, value: 42, @@ -254,10 +258,10 @@ describe('[Transaction]', () => { }) it('serialize() -> should round trip decode a tx', () => { - const tx = LegacyTransaction.fromTxData({ value: 5000 }) + const tx = createLegacyTx({ value: 5000 }) const s1 = tx.serialize() - const tx2 = LegacyTransaction.fromSerializedTx(s1) + const tx2 = createLegacyTxFromRLP(s1) const s2 = tx2.serialize() assert.ok(equalsBytes(s1, s2)) @@ -269,7 +273,7 @@ describe('[Transaction]', () => { hardfork: Hardfork.TangerineWhistle, }) - let tx = LegacyTransaction.fromValuesArray( + let tx = createLegacyTxFromBytesArray( txFixtures[3].raw.slice(0, 6).map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, @@ -283,7 +287,7 @@ describe('[Transaction]', () => { undefined, 'should throw calling hash with unsigned tx' ) - tx = LegacyTransaction.fromValuesArray( + tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, @@ -305,7 +309,7 @@ describe('[Transaction]', () => { }) it('hash() -> with defined chainId', () => { - const tx = LegacyTransaction.fromValuesArray( + const tx = createLegacyTxFromBytesArray( txFixtures[4].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) ) assert.equal( @@ -324,7 +328,7 @@ describe('[Transaction]', () => { it("getHashedMessageToSign(), getSenderPublicKey() (implicit call) -> verify EIP155 signature based on Vitalik's tests", () => { for (const tx of txFixturesEip155) { - const pt = LegacyTransaction.fromSerializedTx(hexToBytes(tx.rlp as PrefixedHexString)) + const pt = createLegacyTxFromRLP(hexToBytes(tx.rlp as PrefixedHexString)) assert.equal(bytesToHex(pt.getHashedMessageToSign()), `0x${tx.hash}`) assert.equal(bytesToHex(pt.serialize()), tx.rlp) assert.equal(pt.getSenderAddress().toString(), `0x${tx.sender}`) @@ -344,7 +348,7 @@ describe('[Transaction]', () => { const privateKey = hexToBytes( '0x4646464646464646464646464646464646464646464646464646464646464646' ) - const pt = LegacyTransaction.fromValuesArray( + const pt = createLegacyTxFromBytesArray( txRaw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) ) @@ -369,7 +373,7 @@ describe('[Transaction]', () => { it('sign(), getSenderPublicKey() (implicit call) -> EIP155 hashing when singing', () => { const common = new Common({ chain: 1, hardfork: Hardfork.Petersburg }) for (const txData of txFixtures.slice(0, 3)) { - const tx = LegacyTransaction.fromValuesArray( + const tx = createLegacyTxFromBytesArray( txData.raw.slice(0, 6).map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, @@ -400,7 +404,7 @@ describe('[Transaction]', () => { '0xDE3128752F183E8930D7F00A2AAA302DCB5E700B2CBA2D8CA5795660F07DEFD5' ) const common = createCustomCommon({ chainId: 3 }) - const tx = LegacyTransaction.fromValuesArray( + const tx = createLegacyTxFromBytesArray( txRaw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common } ) @@ -430,25 +434,23 @@ describe('[Transaction]', () => { hardfork: Hardfork.TangerineWhistle, }) - const fixtureTxSignedWithoutEIP155 = LegacyTransaction.fromTxData(txData, { + const fixtureTxSignedWithoutEIP155 = createLegacyTx(txData, { common, }).sign(privateKey) - let signedWithEIP155 = LegacyTransaction.fromTxData(txData).sign(privateKey) + let signedWithEIP155 = createLegacyTx(txData).sign(privateKey) assert.isTrue(signedWithEIP155.verifySignature()) assert.notEqual(signedWithEIP155.v?.toString(16), '1c') assert.notEqual(signedWithEIP155.v?.toString(16), '1b') - signedWithEIP155 = LegacyTransaction.fromTxData( - fixtureTxSignedWithoutEIP155.toJSON() - ).sign(privateKey) + signedWithEIP155 = createLegacyTx(fixtureTxSignedWithoutEIP155.toJSON()).sign(privateKey) assert.isTrue(signedWithEIP155.verifySignature()) assert.notEqual(signedWithEIP155.v?.toString(16), '1c') assert.notEqual(signedWithEIP155.v?.toString(16), '1b') - let signedWithoutEIP155 = LegacyTransaction.fromTxData(txData, { + let signedWithoutEIP155 = createLegacyTx(txData, { common, }).sign(privateKey) @@ -458,7 +460,7 @@ describe('[Transaction]', () => { "v shouldn't be EIP155 encoded" ) - signedWithoutEIP155 = LegacyTransaction.fromTxData(txData, { + signedWithoutEIP155 = createLegacyTx(txData, { common, }).sign(privateKey) @@ -476,19 +478,19 @@ describe('[Transaction]', () => { } } for (let n = 0; n < 27; n++) { - assert.throws(() => LegacyTransaction.fromTxData(getTxData(n))) + assert.throws(() => createLegacyTx(getTxData(n))) } - assert.throws(() => LegacyTransaction.fromTxData(getTxData(29))) - assert.throws(() => LegacyTransaction.fromTxData(getTxData(36))) + assert.throws(() => createLegacyTx(getTxData(29))) + assert.throws(() => createLegacyTx(getTxData(36))) - assert.doesNotThrow(() => LegacyTransaction.fromTxData(getTxData(27))) - assert.doesNotThrow(() => LegacyTransaction.fromTxData(getTxData(28))) - assert.doesNotThrow(() => LegacyTransaction.fromTxData(getTxData(37))) + assert.doesNotThrow(() => createLegacyTx(getTxData(27))) + assert.doesNotThrow(() => createLegacyTx(getTxData(28))) + assert.doesNotThrow(() => createLegacyTx(getTxData(37))) }) it('sign(), verifySignature(): sign tx with chainId specified in params', () => { const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Petersburg }) - let tx = LegacyTransaction.fromTxData({}, { common }) + let tx = createLegacyTx({}, { common }) assert.equal(tx.common.chainId(), BigInt(5)) const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) @@ -496,13 +498,13 @@ describe('[Transaction]', () => { const serialized = tx.serialize() - const reTx = LegacyTransaction.fromSerializedTx(serialized, { common }) + const reTx = createLegacyTxFromRLP(serialized, { common }) assert.equal(reTx.verifySignature(), true) assert.equal(reTx.common.chainId(), BigInt(5)) }) it('freeze property propagates from unsigned tx to signed tx', () => { - const tx = LegacyTransaction.fromTxData({}, { freeze: false }) + const tx = createLegacyTx({}, { freeze: false }) assert.notOk(Object.isFrozen(tx), 'tx object is not frozen') const privKey = hexToBytes(`0x${txFixtures[0].privateKey}`) const signedTxn = tx.sign(privKey) @@ -512,7 +514,7 @@ describe('[Transaction]', () => { it('common propagates from the common of tx, not the common in TxOptions', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const pkey = hexToBytes(`0x${txFixtures[0].privateKey}`) - const txn = LegacyTransaction.fromTxData({}, { common, freeze: false }) + const txn = createLegacyTx({}, { common, freeze: false }) const newCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Paris }) assert.notDeepEqual(newCommon, common, 'new common is different than original common') Object.defineProperty(txn, 'common', { @@ -528,7 +530,7 @@ describe('[Transaction]', () => { }) it('isSigned() -> returns correct values', () => { - let tx = LegacyTransaction.fromTxData({}) + let tx = createLegacyTx({}) assert.notOk(tx.isSigned()) const txData: TxData[TransactionType.Legacy] = { @@ -542,29 +544,29 @@ describe('[Transaction]', () => { const privateKey = hexToBytes( '0x4646464646464646464646464646464646464646464646464646464646464646' ) - tx = LegacyTransaction.fromTxData(txData) + tx = createLegacyTx(txData) assert.notOk(tx.isSigned()) tx = tx.sign(privateKey) assert.ok(tx.isSigned()) - tx = LegacyTransaction.fromTxData(txData) + tx = createLegacyTx(txData) assert.notOk(tx.isSigned()) const rawUnsigned = tx.serialize() tx = tx.sign(privateKey) const rawSigned = tx.serialize() assert.ok(tx.isSigned()) - tx = LegacyTransaction.fromSerializedTx(rawUnsigned) + tx = createLegacyTxFromRLP(rawUnsigned) assert.notOk(tx.isSigned()) tx = tx.sign(privateKey) assert.ok(tx.isSigned()) - tx = LegacyTransaction.fromSerializedTx(rawSigned) + tx = createLegacyTxFromRLP(rawSigned) assert.ok(tx.isSigned()) const signedValues = RLP.decode(Uint8Array.from(rawSigned)) as Uint8Array[] - tx = LegacyTransaction.fromValuesArray(signedValues) + tx = createLegacyTxFromBytesArray(signedValues) assert.ok(tx.isSigned()) - tx = LegacyTransaction.fromValuesArray(signedValues.slice(0, 6)) + tx = createLegacyTxFromBytesArray(signedValues.slice(0, 6)) assert.notOk(tx.isSigned()) }) }) diff --git a/packages/tx/test/transactionFactory.spec.ts b/packages/tx/test/transactionFactory.spec.ts index c66d1fe456..ddb7c6f5ea 100644 --- a/packages/tx/test/transactionFactory.spec.ts +++ b/packages/tx/test/transactionFactory.spec.ts @@ -7,6 +7,9 @@ import { FeeMarketEIP1559Transaction, LegacyTransaction, TransactionType, + create1559FeeMarketTx, + create2930AccessListTx, + createLegacyTx, createTxFromBlockBodyData, createTxFromSerializedData, createTxFromTxData, @@ -19,15 +22,12 @@ const common = new Common({ const pKey = hexToBytes('0x4646464646464646464646464646464646464646464646464646464646464646') -const unsignedLegacyTx = LegacyTransaction.fromTxData({}) +const unsignedLegacyTx = createLegacyTx({}) const signedLegacyTx = unsignedLegacyTx.sign(pKey) -const unsignedEIP2930Tx = AccessListEIP2930Transaction.fromTxData( - { chainId: BigInt(1) }, - { common } -) +const unsignedEIP2930Tx = create2930AccessListTx({ chainId: BigInt(1) }, { common }) const signedEIP2930Tx = unsignedEIP2930Tx.sign(pKey) -const unsignedEIP1559Tx = FeeMarketEIP1559Transaction.fromTxData({ chainId: BigInt(1) }, { common }) +const unsignedEIP1559Tx = create1559FeeMarketTx({ chainId: BigInt(1) }, { common }) const signedEIP1559Tx = unsignedEIP1559Tx.sign(pKey) const txTypes = [ diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index b4c0faad44..b6e19e35eb 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -18,6 +18,11 @@ import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction, TransactionType, + create1559FeeMarketTx, + create1559FeeMarketTxFromRLP, + create2930AccessListTx, + create2930AccessListTxFromBytesArray, + create2930AccessListTxFromRLP, } from '../src/index.js' import type { AccessList, AccessListBytesItem, JsonTx } from '../src/index.js' @@ -35,11 +40,19 @@ const txTypes = [ class: AccessListEIP2930Transaction, name: 'AccessListEIP2930Transaction', type: TransactionType.AccessListEIP2930, + create: { + txData: create2930AccessListTx, + rlp: create2930AccessListTxFromRLP, + }, }, { class: FeeMarketEIP1559Transaction, name: 'FeeMarketEIP1559Transaction', type: TransactionType.FeeMarketEIP1559, + create: { + txData: create1559FeeMarketTx, + rlp: create1559FeeMarketTxFromRLP, + }, }, ] @@ -50,10 +63,10 @@ const chainId = BigInt(Chain.Mainnet) describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-2930 Compatibility', () => { it('Initialization / Getter -> fromTxData()', () => { for (const txType of txTypes) { - let tx = txType.class.fromTxData({}, { common }) + let tx = txType.create.txData({}, { common }) assert.ok(tx, `should initialize correctly (${txType.name})`) - tx = txType.class.fromTxData({ + tx = txType.create.txData({ chainId: Chain.Goerli, }) assert.ok( @@ -61,7 +74,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 'should initialize Common with chain ID provided (supported chain ID)' ) - tx = txType.class.fromTxData({ + tx = txType.create.txData({ chainId: 99999, }) assert.ok( @@ -72,7 +85,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 const nonEIP2930Common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) assert.throws( () => { - txType.class.fromTxData({}, { common: nonEIP2930Common }) + txType.create.txData({}, { common: nonEIP2930Common }) }, undefined, undefined, @@ -81,7 +94,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData( + txType.create.txData( { chainId: chainId + BigInt(1), }, @@ -95,7 +108,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData( + txType.create.txData( { v: 2, }, @@ -141,7 +154,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 ) { txData[value] = testCase assert.throws(() => { - AccessListEIP2930Transaction.fromTxData(txData) + create2930AccessListTx(txData) }) } } @@ -151,7 +164,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('Initialization / Getter -> fromSerializedTx()', () => { for (const txType of txTypes) { try { - txType.class.fromSerializedTx(new Uint8Array([99]), {}) + txType.create.rlp(new Uint8Array([99]), {}) } catch (e: any) { assert.ok( e.message.includes('wrong tx type'), @@ -162,7 +175,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 try { // Correct tx type + RLP-encoded 5 const serialized = concatBytes(new Uint8Array([txType.type]), new Uint8Array([5])) - txType.class.fromSerializedTx(serialized, {}) + txType.create.rlp(serialized, {}) } catch (e: any) { assert.ok( e.message.includes('must be array'), @@ -173,7 +186,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 try { // Correct tx type + RLP-encoded empty list const serialized = concatBytes(new Uint8Array([txType.type]), hexToBytes('0xc0')) - txType.class.fromSerializedTx(serialized, {}) + txType.create.rlp(serialized, {}) } catch (e: any) { assert.ok( e.message.includes('values (for unsigned tx)'), @@ -191,7 +204,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 storageKeys: [bytesToHex(validSlot)], }, ] - const txn = txType.class.fromTxData( + const txn = txType.create.txData( { accessList: access, chainId: Chain.Mainnet, @@ -211,7 +224,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 // also verify that we can always get the json access list, even if we don't provide one. - const txnRaw = txType.class.fromTxData( + const txnRaw = txType.create.txData( { accessList: bytes, chainId: Chain.Mainnet, @@ -236,7 +249,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -254,7 +267,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -265,7 +278,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -276,7 +289,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -287,7 +300,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -298,7 +311,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { - txType.class.fromTxData({ chainId, accessList }, { common }) + txType.create.txData({ chainId, accessList }, { common }) }, undefined, undefined, @@ -309,7 +322,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('sign()', () => { for (const txType of txTypes) { - let tx = txType.class.fromTxData( + let tx = txType.create.txData( { data: hexToBytes('0x010200'), to: validAddress, @@ -326,7 +339,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 ) signed.verifySignature() // If this throws, test will not end. - tx = txType.class.fromTxData({}, { common }) + tx = txType.create.txData({}, { common }) signed = tx.sign(pKey) assert.deepEqual( @@ -336,7 +349,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 ) assert.deepEqual(signed.accessList, []) - tx = txType.class.fromTxData({}, { common }) + tx = txType.create.txData({}, { common }) assert.throws( () => { @@ -354,7 +367,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.throws( () => { const high = SECP256K1_ORDER_DIV_2 + BigInt(1) - const tx = txType.class.fromTxData({ s: high, r: 1, v: 1 }, { common }) + const tx = txType.create.txData({ s: high, r: 1, v: 1 }, { common }) const signed = tx.sign(pKey) signed.getSenderPublicKey() }, @@ -367,7 +380,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('addSignature() -> correctly adds correct signature values', () => { const privateKey = pKey - const tx = AccessListEIP2930Transaction.fromTxData({}) + const tx = create2930AccessListTx({}) const signedTx = tx.sign(privateKey) const addSignatureTx = tx.addSignature(signedTx.v!, signedTx.r!, signedTx.s!) @@ -376,7 +389,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('addSignature() -> correctly converts raw ecrecover values', () => { const privKey = pKey - const tx = AccessListEIP2930Transaction.fromTxData({}) + const tx = create2930AccessListTx({}) const msgHash = tx.getHashedMessageToSign() const { v, r, s } = ecsign(msgHash, privKey) @@ -389,7 +402,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('addSignature() -> throws when adding the wrong v value', () => { const privKey = pKey - const tx = AccessListEIP2930Transaction.fromTxData({}) + const tx = create2930AccessListTx({}) const msgHash = tx.getHashedMessageToSign() const { v, r, s } = ecsign(msgHash, privKey) @@ -402,14 +415,14 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 it('getDataFee()', () => { for (const txType of txTypes) { - let tx = txType.class.fromTxData({}, { common }) + let tx = txType.create.txData({}, { common }) assert.equal(tx.getDataFee(), BigInt(0), 'Should return data fee when frozen') - tx = txType.class.fromTxData({}, { common, freeze: false }) + tx = txType.create.txData({}, { common, freeze: false }) assert.equal(tx.getDataFee(), BigInt(0), 'Should return data fee when not frozen') const mutableCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - tx = txType.class.fromTxData({}, { common: mutableCommon }) + tx = txType.create.txData({}, { common: mutableCommon }) tx.common.setHardfork(Hardfork.Istanbul) assert.equal(tx.getDataFee(), BigInt(0), 'Should invalidate cached value on hardfork change') } @@ -418,9 +431,9 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { it(`Initialization`, () => { - const tx = AccessListEIP2930Transaction.fromTxData({}, { common }) + const tx = create2930AccessListTx({}, { common }) assert.ok( - AccessListEIP2930Transaction.fromTxData(tx, { common }), + create2930AccessListTx(tx, { common }), 'should initialize correctly from its own data' ) @@ -428,7 +441,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const validSlot = hexToBytes(`0x${'01'.repeat(32)}`) const chainId = BigInt(1) try { - AccessListEIP2930Transaction.fromTxData( + create2930AccessListTx( { data: hexToBytes('0x010200'), to: validAddress, @@ -453,7 +466,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const address = new Uint8Array(0) const storageKeys = [new Uint8Array(0), new Uint8Array(0)] const aclBytes: AccessListBytesItem = [address, storageKeys] - AccessListEIP2930Transaction.fromValuesArray( + create2930AccessListTxFromBytesArray( [bytes, bytes, bytes, bytes, bytes, bytes, bytes, [aclBytes], bytes], {} ) @@ -464,7 +477,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) it(`should return right upfront cost`, () => { - let tx = AccessListEIP2930Transaction.fromTxData( + let tx = create2930AccessListTx( { data: hexToBytes('0x010200'), to: validAddress, @@ -494,7 +507,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) // In this Tx, `to` is `undefined`, so we should charge homestead creation gas. - tx = AccessListEIP2930Transaction.fromTxData( + tx = create2930AccessListTx( { data: hexToBytes('0x010200'), accessList: [[validAddress, [validSlot]]], @@ -516,7 +529,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) // Explicitly check that even if we have duplicates in our list, we still charge for those - tx = AccessListEIP2930Transaction.fromTxData( + tx = create2930AccessListTx( { to: validAddress, accessList: [ @@ -534,7 +547,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { }) it('getEffectivePriorityFee() -> should return correct values', () => { - const tx = AccessListEIP2930Transaction.fromTxData({ + const tx = create2930AccessListTx({ gasPrice: BigInt(100), }) @@ -545,7 +558,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { }) it('getUpfrontCost() -> should return upfront cost', () => { - const tx = AccessListEIP2930Transaction.fromTxData( + const tx = create2930AccessListTx( { gasPrice: 1000, gasLimit: 10000000, @@ -557,7 +570,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { }) it('unsigned tx -> getHashedMessageToSign()/getMessageToSign()', () => { - const unsignedTx = AccessListEIP2930Transaction.fromTxData( + const unsignedTx = create2930AccessListTx( { data: hexToBytes('0x010200'), to: validAddress, @@ -627,7 +640,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { hexToBytes('0x0be950468ba1c25a5cb50e9f6d8aa13c8cd21f24ba909402775b262ac76d374d') ) - const unsignedTx = AccessListEIP2930Transaction.fromTxData(txData, { common: usedCommon }) + const unsignedTx = create2930AccessListTx(txData, { common: usedCommon }) const serializedMessageRaw = unsignedTx.serialize() @@ -669,14 +682,14 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { }) it('freeze property propagates from unsigned tx to signed tx', () => { - const tx = AccessListEIP2930Transaction.fromTxData({}, { freeze: false }) + const tx = create2930AccessListTx({}, { freeze: false }) assert.notOk(Object.isFrozen(tx), 'tx object is not frozen') const signedTxn = tx.sign(pKey) assert.notOk(Object.isFrozen(signedTxn), 'tx object is not frozen') }) it('common propagates from the common of tx, not the common in TxOptions', () => { - const txn = AccessListEIP2930Transaction.fromTxData({}, { common, freeze: false }) + const txn = create2930AccessListTx({}, { common, freeze: false }) const newCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Paris }) assert.notDeepEqual(newCommon, common, 'new common is different than original common') Object.defineProperty(txn, 'common', { diff --git a/packages/vm/examples/buildBlock.ts b/packages/vm/examples/buildBlock.ts index f04d89a0e3..c94159478b 100644 --- a/packages/vm/examples/buildBlock.ts +++ b/packages/vm/examples/buildBlock.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { buildBlock, VM } from '@ethereumjs/vm' @@ -30,7 +30,7 @@ const main = async () => { const address = Address.fromPrivateKey(pk) const account = new Account(0n, 0xfffffffffn) await vm.stateManager.putAccount(address, account) // create a sending account and give it a big balance - const tx = LegacyTransaction.fromTxData({ gasLimit: 0xffffff, gasPrice: 75n }).sign(pk) + const tx = createLegacyTx({ gasLimit: 0xffffff, gasPrice: 75n }).sign(pk) await blockBuilder.addTransaction(tx) // Add more transactions diff --git a/packages/vm/examples/run-solidity-contract.ts b/packages/vm/examples/run-solidity-contract.ts index d490107fb9..4e7b928c00 100644 --- a/packages/vm/examples/run-solidity-contract.ts +++ b/packages/vm/examples/run-solidity-contract.ts @@ -1,15 +1,15 @@ +import { createBlockFromBlockData } from '@ethereumjs/block' +import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { createLegacyTx } from '@ethereumjs/tx' +import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { runTx, VM } from '@ethereumjs/vm' +import { defaultAbiCoder as AbiCoder, Interface } from '@ethersproject/abi' +import { readFileSync } from 'fs' import path from 'path' +import solc from 'solc' import { fileURLToPath } from 'url' -import { readFileSync } from 'fs' -import { defaultAbiCoder as AbiCoder, Interface } from '@ethersproject/abi' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' -import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' -import { VM, runTx } from '@ethereumjs/vm' -import { buildTransaction, encodeDeployment, encodeFunction } from './helpers/tx-builder.js' import { getAccountNonce, insertAccount } from './helpers/account-utils.js' -import { createBlockFromBlockData } from '@ethereumjs/block' -import solc from 'solc' +import { buildTransaction, encodeDeployment, encodeFunction } from './helpers/tx-builder.js' const INITIAL_GREETING = 'Hello, World!' const SECOND_GREETING = 'Hola, Mundo!' @@ -105,9 +105,7 @@ async function deployContract( nonce: await getAccountNonce(vm, senderPrivateKey), } - const tx = LegacyTransaction.fromTxData(buildTransaction(txData as any), { common }).sign( - senderPrivateKey - ) + const tx = createLegacyTx(buildTransaction(txData as any), { common }).sign(senderPrivateKey) const deploymentResult = await runTx(vm, { tx, block }) @@ -135,9 +133,7 @@ async function setGreeting( nonce: await getAccountNonce(vm as any, senderPrivateKey), } - const tx = LegacyTransaction.fromTxData(buildTransaction(txData as any), { common }).sign( - senderPrivateKey - ) + const tx = createLegacyTx(buildTransaction(txData as any), { common }).sign(senderPrivateKey) const setGreetingResult = await runTx(vm, { tx, block }) diff --git a/packages/vm/examples/runTx.ts b/packages/vm/examples/runTx.ts index 6ee7cf745c..cb76ff24f6 100644 --- a/packages/vm/examples/runTx.ts +++ b/packages/vm/examples/runTx.ts @@ -1,13 +1,13 @@ -import { Address } from '@ethereumjs/util' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' +import { Address } from '@ethereumjs/util' import { runTx, VM } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) const vm = await VM.create({ common }) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: BigInt(21000), gasPrice: BigInt(1000000000), value: BigInt(1), diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 06742865dd..8c89a53ba7 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -7,7 +7,7 @@ import { import { ConsensusType, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { BlobEIP4844Transaction, createMinimal4844TxFromNetworkWrapper } from '@ethereumjs/tx' import { Address, BIGINT_0, @@ -264,7 +264,7 @@ export class BlockBuilder { if (tx instanceof BlobEIP4844Transaction) { const txData = tx as BlobEIP4844Transaction this.blobGasUsed += BigInt(txData.blobVersionedHashes.length) * blobGasPerBlob - tx = BlobEIP4844Transaction.minimalFromNetworkWrapper(txData, { + tx = createMinimal4844TxFromNetworkWrapper(txData, { common: this.blockOpts.common, }) } diff --git a/packages/vm/test/api/EIPs/eip-1153.spec.ts b/packages/vm/test/api/EIPs/eip-1153.spec.ts index 2bd33912a9..f27569126c 100644 --- a/packages/vm/test/api/EIPs/eip-1153.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1153.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, bytesToInt, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -74,7 +74,7 @@ describe('EIP 1153: transient storage', () => { returndata[31] = 0x02 const address = new Address(hexToBytes('0x00000000000000000000000636F6E7472616374')) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: BigInt(21000 + 9000), to: address, value: BigInt(1), @@ -117,12 +117,12 @@ describe('EIP 1153: transient storage', () => { const test = { contracts: [{ address, code }], transactions: [ - LegacyTransaction.fromTxData({ + createLegacyTx({ gasLimit: BigInt(15000000), to: address, data: new Uint8Array(32), }).sign(senderKey), - LegacyTransaction.fromTxData({ + createLegacyTx({ nonce: 1, gasLimit: BigInt(15000000), to: address, @@ -186,7 +186,7 @@ describe('EIP 1153: transient storage', () => { const callingCode = '0x6362fdb9be600052602060006020600060007f000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec861fffff163afc874d2600052602060006020600060007f000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec861fffff16343ac1c39600052602060006020600060007f000000000000000000000000ea674fdde714fd979de3edf0f56aa9716b898ec861fffff1366000803760206000f3' - const unsignedTx = LegacyTransaction.fromTxData({ + const unsignedTx = createLegacyTx({ gasLimit: BigInt(15000000), to: callingAddress, }) diff --git a/packages/vm/test/api/EIPs/eip-2929.spec.ts b/packages/vm/test/api/EIPs/eip-2929.spec.ts index 1d983ca078..91f3a7baca 100644 --- a/packages/vm/test/api/EIPs/eip-2929.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2929.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -49,7 +49,7 @@ describe('EIP 2929: gas cost tests', () => { await vm.stateManager.putContractCode(address, hexToBytes(test.code)) - const unsignedTx = LegacyTransaction.fromTxData({ + const unsignedTx = createLegacyTx({ gasLimit: initialGas, // ensure we pass a lot of gas, so we do not run out of gas to: address, // call to the contract address, }) @@ -76,7 +76,7 @@ describe('EIP 2929: gas cost tests', () => { await vm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code // setup the call arguments - const unsignedTx = LegacyTransaction.fromTxData({ + const unsignedTx = createLegacyTx({ gasLimit: BigInt(21000 + 9000), // ensure we pass a lot of gas, so we do not run out of gas to: contractAddress, // call to the contract address, value: BigInt(1), diff --git a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts index 8ba549f17c..379696aede 100644 --- a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { AccessListEIP2930Transaction } from '@ethereumjs/tx' +import { create2930AccessListTx } from '@ethereumjs/tx' import { Address, bytesToHex, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -26,7 +26,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { storageKeys: [bytesToHex(validSlot)], }, ] - const txnWithAccessList = AccessListEIP2930Transaction.fromTxData( + const txnWithAccessList = create2930AccessListTx( { accessList: access, chainId: BigInt(1), @@ -35,7 +35,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { }, { common } ).sign(privateKey) - const txnWithoutAccessList = AccessListEIP2930Transaction.fromTxData( + const txnWithoutAccessList = create2930AccessListTx( { accessList: [], chainId: BigInt(1), 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 49a2f317ed..ad658433fc 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 @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Hardfork, createCustomCommon } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, @@ -120,7 +120,7 @@ describe('EIP 2935: historical block hashes', () => { // eslint-disable-next-line no-inner-declarations async function testBlockhashContract(vm: VM, block: Block, i: bigint): Promise { - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: historyAddress, gasLimit: 1000000, gasPrice: 10, @@ -155,7 +155,7 @@ describe('EIP 2935: historical block hashes', () => { s: deploymentS, } - const deployTx = LegacyTransaction.fromTxData(deployContractTxData) + const deployTx = createLegacyTx(deployContractTxData) const txSender = Address.fromPublicKey(deployTx.getSenderPublicKey()).toString() assert.equal(txSender, deploymentSender, 'tx sender should match') diff --git a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts index 2da4678de8..f5913e816d 100644 --- a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { EVMErrorMessage } from '@ethereumjs/evm' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, @@ -240,7 +240,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -264,7 +264,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -289,7 +289,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, contractAddress), RETURNTOP) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -312,7 +312,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -336,7 +336,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -365,7 +365,7 @@ describe('EIP-3074 AUTH', () => { ) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -391,7 +391,7 @@ describe('EIP-3074 AUTH', () => { ) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -414,7 +414,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNMEMSIZE) await vm.stateManager.putContractCode(contractAddress, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -440,7 +440,7 @@ describe('EIP-3074 AUTH', () => { ) await vm.stateManager.putContractCode(contractAddress, code2) - const tx2 = LegacyTransaction.fromTxData({ + const tx2 = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -485,7 +485,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -519,7 +519,7 @@ describe('EIP-3074 AUTHCALL', () => { } }) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -560,7 +560,7 @@ describe('EIP-3074 AUTHCALL', () => { } }) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -604,7 +604,7 @@ describe('EIP-3074 AUTHCALL', () => { } }) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 900000, gasPrice: 10, @@ -648,7 +648,7 @@ describe('EIP-3074 AUTHCALL', () => { const value = 3n const gasPrice = 10n - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: PREBALANCE / gasPrice - value * gasPrice, gasPrice, @@ -698,7 +698,7 @@ describe('EIP-3074 AUTHCALL', () => { const value = 3n const gasPrice = 10n - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: PREBALANCE / gasPrice - value * gasPrice, gasPrice, @@ -719,7 +719,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -755,7 +755,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -783,7 +783,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -811,7 +811,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, @@ -844,7 +844,7 @@ describe('EIP-3074 AUTHCALL', () => { ) const vm = await setupVM(code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, gasPrice: 10, diff --git a/packages/vm/test/api/EIPs/eip-3529.spec.ts b/packages/vm/test/api/EIPs/eip-3529.spec.ts index b41f1acbf1..0e7d90cab0 100644 --- a/packages/vm/test/api/EIPs/eip-3529.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3529.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -160,7 +160,7 @@ describe('EIP-3529 tests', () => { it('should not refund selfdestructs', async () => { const vm = await VM.create({ common }) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ data: '0x6000ff', gasLimit: 100000, }).sign(pkey) @@ -212,7 +212,7 @@ describe('EIP-3529 tests', () => { await vm.stateManager.putContractCode(address, hexToBytes(code)) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: address, gasLimit: 10000000, }).sign(pkey) diff --git a/packages/vm/test/api/EIPs/eip-3541.spec.ts b/packages/vm/test/api/EIPs/eip-3541.spec.ts index 53d49464ed..d30c7fd17e 100644 --- a/packages/vm/test/api/EIPs/eip-3541.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3541.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -16,7 +16,7 @@ describe('EIP 3541 tests', () => { it('deposit 0xEF code if 3541 is active', async () => { // put 0xEF contract - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ data: '0x7FEF0000000000000000000000000000000000000000000000000000000000000060005260206000F3', gasLimit: 1000000, }).sign(pkey) @@ -33,7 +33,7 @@ describe('EIP 3541 tests', () => { // Test if we can put a valid contract // put a valid contract starting with SELFDESTRUCT - const tx1 = LegacyTransaction.fromTxData({ + const tx1 = createLegacyTx({ data: '0x7FFF0000000000000000000000000000000000000000000000000000000000000060005260206000F3', gasLimit: 1000000, nonce: 1, @@ -49,7 +49,7 @@ describe('EIP 3541 tests', () => { // check if we can deposit a contract on non-EIP3541 chains vm = await VM.create({ common: commonNoEIP3541 }) - const tx2 = LegacyTransaction.fromTxData({ + const tx2 = createLegacyTx({ data: '0x7FEF0000000000000000000000000000000000000000000000000000000000000060005260206000F3', gasLimit: 1000000, }).sign(pkey) @@ -64,7 +64,7 @@ describe('EIP 3541 tests', () => { it('deploy contracts starting with 0xEF using CREATE', async () => { // put 0xEF contract - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ data: '0x7F60EF60005360016000F300000000000000000000000000000000000000000000600052602060006000F000', gasLimit: 1000000, }).sign(pkey) @@ -84,7 +84,7 @@ describe('EIP 3541 tests', () => { assert.equal(code.length, 0, 'did not deposit code') // put 0xFF contract - const tx1 = LegacyTransaction.fromTxData({ + const tx1 = createLegacyTx({ data: '0x7F60FF60005360016000F300000000000000000000000000000000000000000000600052602060006000F000', gasLimit: 1000000, nonce: 1, @@ -99,7 +99,7 @@ describe('EIP 3541 tests', () => { it('deploy contracts starting with 0xEF using CREATE2', async () => { // put 0xEF contract - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ data: '0x7F60EF60005360016000F3000000000000000000000000000000000000000000006000526000602060006000F500', gasLimit: 1000000, }).sign(pkey) @@ -119,7 +119,7 @@ describe('EIP 3541 tests', () => { assert.equal(code.length, 0, 'did not deposit code') // put 0xFF contract - const tx1 = LegacyTransaction.fromTxData({ + const tx1 = createLegacyTx({ data: '0x7F60FF60005360016000F3000000000000000000000000000000000000000000006000526000602060006000F500', gasLimit: 1000000, nonce: 1, diff --git a/packages/vm/test/api/EIPs/eip-3607.spec.ts b/packages/vm/test/api/EIPs/eip-3607.spec.ts index af86803aab..4a8b12b977 100644 --- a/packages/vm/test/api/EIPs/eip-3607.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3607.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -13,7 +13,7 @@ describe('EIP-3607 tests', () => { it('should reject txs from senders with deployed code when EIP is enabled', async () => { const vm = await VM.create({ common }) await vm.stateManager.putContractCode(precompileAddr, new Uint8Array(32).fill(1)) - const tx = LegacyTransaction.fromTxData({ gasLimit: 100000 }, { freeze: false }) + const tx = createLegacyTx({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { await runTx(vm, { tx, skipHardForkValidation: true }) @@ -30,7 +30,7 @@ describe('EIP-3607 tests', () => { it('should not reject txs from senders with deployed code when EIP is not enabled', async () => { const vm = await VM.create({ common: commonNoEIP3607 }) await vm.stateManager.putContractCode(precompileAddr, new Uint8Array(32).fill(1)) - const tx = LegacyTransaction.fromTxData({ gasLimit: 100000 }, { freeze: false }) + const tx = createLegacyTx({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { await runTx(vm, { tx, skipHardForkValidation: true }) diff --git a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts index d6babfbca1..47583ee3b1 100644 --- a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -46,7 +46,7 @@ describe('EIP 3651 tests', () => { it('invalid contract code transactions', async () => { const vm = await getVM(common) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ to: contractAddress, value: 1, gasLimit: 1000000, diff --git a/packages/vm/test/api/EIPs/eip-3860.spec.ts b/packages/vm/test/api/EIPs/eip-3860.spec.ts index af2687df0b..18fac79da6 100644 --- a/packages/vm/test/api/EIPs/eip-3860.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3860.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -27,7 +27,7 @@ describe('EIP 3860 tests', () => { // We create a tx with a common which has eip not yet activated else tx creation will // throw error const txCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { data: `0x7F6000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060005260206000F3${bytesToHex( bytes diff --git a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts index a6fd6abaf4..efcf4aab0f 100644 --- a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { BlobEIP4844Transaction } from '@ethereumjs/tx' +import { create4844BlobTx } from '@ethereumjs/tx' import { Address, blobsToCommitments, @@ -65,7 +65,7 @@ describe('EIP4844 tests', () => { const commitments = blobsToCommitments(kzg, blobs) const blobVersionedHashes = commitmentsToVersionedHashes(commitments) const proofs = blobsToProofs(kzg, blobs, commitments) - const unsignedTx = BlobEIP4844Transaction.fromTxData( + const unsignedTx = create4844BlobTx( { blobVersionedHashes, blobs, diff --git a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts index adec4770bf..166b55288a 100644 --- a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData, genWithdrawalsTrieRoot } from '@ethereumjs/bl import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' import { decode } from '@ethereumjs/rlp' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { Account, Address, @@ -67,7 +67,7 @@ describe('EIP4895 tests', () => { hexToBytes(`0x73${addresses[0]}3160005260206000F3`) ) - const transaction = FeeMarketEIP1559Transaction.fromTxData({ + const transaction = create1559FeeMarketTx({ to: contractAddress, maxFeePerGas: BigInt(7), maxPriorityFeePerGas: BigInt(0), diff --git a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts index 8a97911208..9364c2653b 100644 --- a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, equalsBytes, hexToBytes, privateToAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -41,7 +41,7 @@ describe('EIP 6780 tests', () => { const vm = await getVM(common) const value = 1 - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ value, gasLimit: 1000000, gasPrice: 10, @@ -78,7 +78,7 @@ describe('EIP 6780 tests', () => { await vm.stateManager.putAccount(target, targetContract) const value = 1 - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ value, gasLimit: 1000000, gasPrice: 10, diff --git a/packages/vm/test/api/EIPs/eip-7002.spec.ts b/packages/vm/test/api/EIPs/eip-7002.spec.ts index 5612e5de29..db84982302 100644 --- a/packages/vm/test/api/EIPs/eip-7002.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7002.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, @@ -40,7 +40,7 @@ const deploymentTxData = { s: BigInt('0xaba653c9d105790c'), } -const deploymentTx = LegacyTransaction.fromTxData(deploymentTxData) +const deploymentTx = createLegacyTx(deploymentTxData) const sender = deploymentTx.getSenderAddress() const upfrontCost = deploymentTx.getUpfrontCost() const acc = new Account() @@ -57,7 +57,7 @@ function generateTx(nonce: bigint) { ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) - return LegacyTransaction.fromTxData({ + return createLegacyTx({ nonce, gasPrice: BigInt(100), data: concatBytes(validatorPubkey, amountBytes), diff --git a/packages/vm/test/api/EIPs/eip-7702.spec.ts b/packages/vm/test/api/EIPs/eip-7702.spec.ts index 70afc3bc80..566dcdc599 100644 --- a/packages/vm/test/api/EIPs/eip-7702.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7702.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { EOACodeEIP7702Transaction } from '@ethereumjs/tx' +import { create7702EOACodeTx } from '@ethereumjs/tx' import { Account, Address, @@ -66,7 +66,7 @@ async function runTest( ) { vm = vm ?? (await VM.create({ common })) const authList = authorizationListOpts.map((opt) => getAuthorizationListItem(opt)) - const tx = EOACodeEIP7702Transaction.fromTxData( + const tx = create7702EOACodeTx( { gasLimit: 100000, maxFeePerGas: 1000, @@ -207,7 +207,7 @@ describe('EIP 7702: set code to EOA accounts', () => { await vm.stateManager.putContractCode(checkAddressWarm, checkAddressWarmCode) - const tx = EOACodeEIP7702Transaction.fromTxData( + const tx = create7702EOACodeTx( { gasLimit: 100000, maxFeePerGas: 1000, @@ -239,7 +239,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code1Addr, }), ] - const tx = EOACodeEIP7702Transaction.fromTxData( + const tx = create7702EOACodeTx( { gasLimit: 100000, maxFeePerGas: 1000, diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index 33cebdfee5..52ca540938 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -8,7 +8,7 @@ import { createCommonFromGethGenesis, } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' -import { FeeMarketEIP1559Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx, createLegacyTx } from '@ethereumjs/tx' import { Address, concatBytes, createAccount, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -40,7 +40,7 @@ describe('BlockBuilder', () => { }) // Set up tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, { common, freeze: false } ).sign(privateKey) @@ -66,7 +66,7 @@ describe('BlockBuilder', () => { const blockBuilder = await buildBlock(vm, { parentBlock: genesis }) const gasLimit = genesis.header.gasLimit + BigInt(1) - const tx = LegacyTransaction.fromTxData({ gasLimit }, { common }) + const tx = createLegacyTx({ gasLimit }, { common }) try { await blockBuilder.addTransaction(tx) assert.fail('should throw error') @@ -110,7 +110,7 @@ describe('BlockBuilder', () => { }) // Set up tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, { common, freeze: false } ).sign(privateKey) @@ -209,7 +209,7 @@ describe('BlockBuilder', () => { }) // Set up tx - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, { common, freeze: false } ).sign(signer.privateKey) @@ -239,7 +239,7 @@ describe('BlockBuilder', () => { blockOpts: { calcDifficultyFromHeader: genesisBlock.header }, }) - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, { common, freeze: false } ).sign(privateKey) @@ -260,7 +260,7 @@ describe('BlockBuilder', () => { blockBuilder = await buildBlock(vm, { parentBlock: genesisBlock }) - const tx2 = LegacyTransaction.fromTxData( + const tx2 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1, nonce: 1 }, { common, freeze: false } ).sign(privateKey) @@ -322,12 +322,12 @@ describe('BlockBuilder', () => { }) // Set up underpriced txs to test error response - const tx1 = LegacyTransaction.fromTxData( + const tx1 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, { common, freeze: false } ).sign(privateKey) - const tx2 = FeeMarketEIP1559Transaction.fromTxData( + const tx2 = create1559FeeMarketTx( { to: Address.zero(), value: 1000, gasLimit: 21000, maxFeePerGas: 10 }, { common, freeze: false } ).sign(privateKey) @@ -345,12 +345,12 @@ describe('BlockBuilder', () => { } // Set up correctly priced txs - const tx3 = LegacyTransaction.fromTxData( + const tx3 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 101 }, { common, freeze: false } ).sign(privateKey) - const tx4 = FeeMarketEIP1559Transaction.fromTxData( + const tx4 = create1559FeeMarketTx( { to: Address.zero(), value: 1000, gasLimit: 21000, maxFeePerGas: 101, nonce: 1 }, { common, freeze: false } ).sign(privateKey) diff --git a/packages/vm/test/api/events.spec.ts b/packages/vm/test/api/events.spec.ts index 3226f73609..580f3c97c0 100644 --- a/packages/vm/test/api/events.spec.ts +++ b/packages/vm/test/api/events.spec.ts @@ -1,5 +1,5 @@ import { Block } from '@ethereumjs/block' -import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { Account, Address, bytesToHex, toBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -56,7 +56,7 @@ describe('VM events', () => { emitted = val }) - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, to: '0x1111111111111111111111111111111111111111', @@ -76,7 +76,7 @@ describe('VM events', () => { emitted = val }) - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, to: '0x1111111111111111111111111111111111111111', @@ -97,7 +97,7 @@ describe('VM events', () => { emitted = val }) - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, to: '0x1111111111111111111111111111111111111111', @@ -119,7 +119,7 @@ describe('VM events', () => { emitted = val }) - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, to: '0x1111111111111111111111111111111111111111', @@ -142,7 +142,7 @@ describe('VM events', () => { // This is a deployment transaction that pushes 0x41 (i.e. ascii A) followed by 31 0s to // the stack, stores that in memory, and then returns the first byte from memory. // This deploys a contract which has a single byte of code, 0x41. - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, data: '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3', @@ -164,7 +164,7 @@ describe('VM events', () => { // This is a deployment transaction that pushes 0x41 (i.e. ascii A) followed by 31 0s to // the stack, stores that in memory, and then returns the first byte from memory. // This deploys a contract which has a single byte of code, 0x41. - const tx = FeeMarketEIP1559Transaction.fromTxData({ + const tx = create1559FeeMarketTx({ gasLimit: 90000, maxFeePerGas: 40000, data: '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3', diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 491c84db70..56d7d43f36 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -6,11 +6,12 @@ import { import { Chain, Common, Hardfork, createCustomCommon } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { - AccessListEIP2930Transaction, Capability, - EOACodeEIP7702Transaction, - FeeMarketEIP1559Transaction, LegacyTransaction, + create1559FeeMarketTx, + create2930AccessListTx, + create7702EOACodeTx, + createLegacyTx, } from '@ethereumjs/tx' import { Account, @@ -179,7 +180,7 @@ describe('runBlock() -> successful API parameter usage', async () => { number: BigInt(10000000), }, transactions: [ - LegacyTransaction.fromTxData( + createLegacyTx( { data: '0x600154', // PUSH 01 SLOAD gasLimit: BigInt(100000), @@ -374,7 +375,7 @@ describe('runBlock() -> runtime behavior', async () => { // add balance to otherUser to send two txs to zero address await vm.stateManager.putAccount(otherUser.address, new Account(BigInt(0), BigInt(42000))) - const tx = LegacyTransaction.fromTxData( + const tx = createLegacyTx( { to: Address.zero(), gasLimit: 21000, gasPrice: 1 }, { common } ).sign(otherUser.privateKey) @@ -514,10 +515,7 @@ describe('runBlock() -> tx types', async () => { const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') await setBalance(vm, address) - const tx = LegacyTransaction.fromTxData( - { gasLimit: 53000, value: 1 }, - { common, freeze: false } - ) + const tx = createLegacyTx({ gasLimit: 53000, value: 1 }, { common, freeze: false }) tx.getSenderAddress = () => { return address @@ -533,7 +531,7 @@ describe('runBlock() -> tx types', async () => { const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') await setBalance(vm, address) - const tx = AccessListEIP2930Transaction.fromTxData( + const tx = create2930AccessListTx( { gasLimit: 53000, value: 1, v: 1, r: 1, s: 1 }, { common, freeze: false } ) @@ -552,7 +550,7 @@ describe('runBlock() -> tx types', async () => { const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') await setBalance(vm, address) - const tx = FeeMarketEIP1559Transaction.fromTxData( + const tx = create1559FeeMarketTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 4, gasLimit: 100000, value: 6 }, { common, freeze: false } ) @@ -638,7 +636,7 @@ describe('runBlock() -> tx types', async () => { const authList = authorizationListOpts.map((opt) => getAuthorizationListItem(opt)) const authList2 = authorizationListOpts2.map((opt) => getAuthorizationListItem(opt)) - const tx1 = EOACodeEIP7702Transaction.fromTxData( + const tx1 = create7702EOACodeTx( { gasLimit: 1000000000, maxFeePerGas: 100000, @@ -649,7 +647,7 @@ describe('runBlock() -> tx types', async () => { }, { common } ).sign(defaultSenderPkey) - const tx2 = EOACodeEIP7702Transaction.fromTxData( + const tx2 = create7702EOACodeTx( { gasLimit: 1000000000, maxFeePerGas: 100000, diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index c725748f80..9aeb284ad0 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -4,8 +4,9 @@ import { Chain, Common, Hardfork, createCommonFromGethGenesis } from '@ethereumj import { BlobEIP4844Transaction, FeeMarketEIP1559Transaction, - LegacyTransaction, TransactionType, + create1559FeeMarketTx, + createLegacyTx, createTxFromTxData, } from '@ethereumjs/tx' import { @@ -27,7 +28,7 @@ import { VM } from '../../src/vm.js' import { createAccountWithDefaults, getTransaction, setBalance } from './utils.js' -import type { FeeMarketEIP1559TxData, TypedTxData } from '@ethereumjs/tx' +import type { FeeMarketEIP1559TxData, LegacyTransaction, TypedTxData } from '@ethereumjs/tx' const TRANSACTION_TYPES = [ { @@ -680,7 +681,7 @@ describe('runTx() -> consensus bugs', () => { acc!.nonce = BigInt(2) await vm.stateManager.putAccount(addr, acc!) - const tx = LegacyTransaction.fromTxData(txData, { common }) + const tx = createLegacyTx(txData, { common }) await runTx(vm, { tx }) const newBalance = (await vm.stateManager.getAccount(addr))!.balance @@ -717,7 +718,7 @@ describe('runTx() -> consensus bugs', () => { acc!.balance = BigInt(10000000000000) await vm.stateManager.putAccount(addr, acc!) - const tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }).sign(pkey) + const tx = create1559FeeMarketTx(txData, { common }).sign(pkey) const block = createBlockFromBlockData({ header: { baseFeePerGas: 0x0c } }, { common }) const result = await runTx(vm, { tx, block }) @@ -768,7 +769,7 @@ it('runTx() -> skipBalance behavior', async () => { if (balance !== undefined) { await vm.stateManager.modifyAccountFields(sender, { nonce: BigInt(0), balance }) } - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: BigInt(21000), value: BigInt(1), to: Address.zero(), @@ -798,7 +799,7 @@ it('Validate EXTCODEHASH puts KECCAK256_NULL on stack if calling account has no const codeAddr = Address.fromString('0x' + '20'.repeat(20)) await vm.stateManager.putContractCode(codeAddr, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: 100000, gasPrice: 1, to: codeAddr, @@ -831,7 +832,7 @@ it('Validate CALL does not charge new account gas when calling CALLER and caller const codeAddr = Address.fromString('0x' + '20'.repeat(20)) await vm.stateManager.putContractCode(codeAddr, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: 100000, gasPrice: 1, value: 1, @@ -862,7 +863,7 @@ it('Validate SELFDESTRUCT does not charge new account gas when calling CALLER an const codeAddr = Address.fromString('0x' + '20'.repeat(20)) await vm.stateManager.putContractCode(codeAddr, code) - const tx = LegacyTransaction.fromTxData({ + const tx = createLegacyTx({ gasLimit: 100000, gasPrice: 1, value: 1, diff --git a/packages/vm/test/api/types.spec.ts b/packages/vm/test/api/types.spec.ts index e223ba8d8b..ed8102e275 100644 --- a/packages/vm/test/api/types.spec.ts +++ b/packages/vm/test/api/types.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { AccessListEIP2930Transaction, LegacyTransaction } from '@ethereumjs/tx' +import { create2930AccessListTx, createLegacyTx } from '@ethereumjs/tx' import { assert, describe, it } from 'vitest' import type { BlockData } from '@ethereumjs/block' @@ -32,12 +32,12 @@ describe('[Types]', () => { // Legacy tx const legacyTx: RequiredExceptOptionals = - LegacyTransaction.fromTxData({}, { common }) + createLegacyTx({}, { common }) assert.ok(legacyTx, 'legacy tx') // Access List tx const accessListTx: RequiredExceptOptionals = - AccessListEIP2930Transaction.fromTxData({}, { common }) + create2930AccessListTx({}, { common }) assert.ok(accessListTx, 'accessList tx') }) }) diff --git a/packages/vm/test/retesteth/transition-child.cts b/packages/vm/test/retesteth/transition-child.cts index 38ca7ce0ea..9ddde4511a 100644 --- a/packages/vm/test/retesteth/transition-child.cts +++ b/packages/vm/test/retesteth/transition-child.cts @@ -1,7 +1,7 @@ import { Block, BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { RLP } from '@ethereumjs/rlp' -import { createTxFromSerializedData, LegacyTransaction } from '@ethereumjs/tx' +import { createLegacyTxFromBytesArray, createTxFromSerializedData } from '@ethereumjs/tx' import { Account, bytesToHex, unprefixedHexToBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import { readFileSync, writeFileSync } from 'fs' @@ -12,9 +12,9 @@ import { BlockBuilder } from '../../dist/cjs/buildBlock' import { getCommon } from '../tester/config' import { makeBlockFromEnv, setupPreConditions } from '../util' -import type { PostByzantiumTxReceipt } from '../../dist/cjs' import type { TypedTransaction } from '@ethereumjs/tx' import type { NestedUint8Array } from '@ethereumjs/util' +import type { PostByzantiumTxReceipt } from '../../dist/cjs' const yargs = require('yargs/yargs') @@ -109,7 +109,7 @@ async function runTransition(argsIn: any) { if (txData instanceof Uint8Array) { tx = createTxFromSerializedData(txData as Uint8Array, { common }) } else { - tx = LegacyTransaction.fromValuesArray(txData as Uint8Array[], { common }) + tx = createLegacyTxFromBytesArray(txData as Uint8Array[], { common }) } await builder.addTransaction(tx) } catch (e: any) { diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 93bf1d247a..626019ac52 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -2,11 +2,11 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork, createCustomCommon } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { - AccessListEIP2930Transaction, - BlobEIP4844Transaction, - EOACodeEIP7702Transaction, - FeeMarketEIP1559Transaction, - LegacyTransaction, + create1559FeeMarketTx, + create2930AccessListTx, + create4844BlobTx, + create7702EOACodeTx, + createLegacyTx, } from '@ethereumjs/tx' import { Account, @@ -27,7 +27,14 @@ import { keccak256 } from 'ethereum-cryptography/keccak' import type { BlockOptions } from '@ethereumjs/block' import type { EVMStateManagerInterface } from '@ethereumjs/common' -import type { TxOptions } from '@ethereumjs/tx' +import type { + AccessListEIP2930Transaction, + BlobEIP4844Transaction, + EOACodeEIP7702Transaction, + FeeMarketEIP1559Transaction, + LegacyTransaction, + TxOptions, +} from '@ethereumjs/tx' import type * as tape from 'tape' export function dumpState(state: any, cb: Function) { @@ -136,15 +143,15 @@ export function makeTx( signature.nonce[0] = '0x' } } - tx = EOACodeEIP7702Transaction.fromTxData(txData, opts) + tx = create7702EOACodeTx(txData, opts) } else if (txData.blobVersionedHashes !== undefined) { - tx = BlobEIP4844Transaction.fromTxData(txData, opts) + tx = create4844BlobTx(txData, opts) } else if (txData.maxFeePerGas !== undefined) { - tx = FeeMarketEIP1559Transaction.fromTxData(txData, opts) + tx = create1559FeeMarketTx(txData, opts) } else if (txData.accessLists !== undefined) { - tx = AccessListEIP2930Transaction.fromTxData(txData, opts) + tx = create2930AccessListTx(txData, opts) } else { - tx = LegacyTransaction.fromTxData(txData, opts) + tx = createLegacyTx(txData, opts) } if (txData.secretKey !== undefined) { From 6a685317cb2fb4373f42bc84b8c12fc86303289e Mon Sep 17 00:00:00 2001 From: Scorbajio Date: Wed, 24 Jul 2024 04:08:54 -0700 Subject: [PATCH 17/58] Stream dependency replacement with walk all value nodes (#3519) * Refactor dumpStorage to use walkAllValueNodes * Refactor dumpStorageRange to use walkAllValueNodes * Fix linting issues * append nibbles to current key * remove readable-stream * Revert bundler config change * type parameter * Remove duplicate code * Micro change to re-trigger CI * lint and obsolete test cleanup * add getValueMap to api [no ci] * Merge branch 'master' into stream-dependency-replacement-with-walkAllValueNodes * Merge remote-tracking branch 'origin/master' into stream-dependency-replacement-with-walkAllValueNodes * Fix test * Merge branch 'stream-dependency-replacement-with-walkAllValueNodes' of github.com:ethereumjs/ethereumjs-monorepo into stream-dependency-replacement-with-walkAllValueNodes * Fix lint issue * Replace walkAllNodes usage with getValueMap in statemanager * Merge branch 'master' into stream-dependency-replacement-with-walkAllValueNodes * Update test * Merge branch 'stream-dependency-replacement-with-walkAllValueNodes' of github.com:ethereumjs/ethereumjs-monorepo into stream-dependency-replacement-with-walkAllValueNodes * Fix lint issues --- package-lock.json | 3 +- packages/statemanager/src/stateManager.ts | 67 +++------ packages/trie/package.json | 3 +- packages/trie/src/trie.ts | 53 +++++-- packages/trie/src/util/index.ts | 1 - packages/trie/src/util/readStream.ts | 66 --------- packages/trie/test/stream.spec.ts | 164 ---------------------- packages/trie/test/trie/trie.spec.ts | 17 +++ 8 files changed, 79 insertions(+), 295 deletions(-) delete mode 100644 packages/trie/src/util/readStream.ts delete mode 100644 packages/trie/test/stream.spec.ts diff --git a/package-lock.json b/package-lock.json index f8a2659734..191f1c226a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16938,8 +16938,7 @@ "@types/readable-stream": "^2.3.13", "debug": "^4.3.4", "ethereum-cryptography": "^2.2.1", - "lru-cache": "10.1.0", - "readable-stream": "^3.6.0" + "lru-cache": "10.1.0" }, "devDependencies": { "@ethereumjs/genesis": "^0.2.2", diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 84a0da6e8a..e4261d9163 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -9,7 +9,6 @@ import { KECCAK256_RLP, KECCAK256_RLP_S, bigIntToHex, - bytesToBigInt, bytesToHex, bytesToUnprefixedHex, concatBytes, @@ -231,7 +230,6 @@ export class DefaultStateManager implements EVMStateManagerInterface { type: opts.accountCacheOpts?.type ?? CacheType.ORDERED_MAP, size: opts.accountCacheOpts?.size ?? 100000, } - if (!this._accountCacheSettings.deactivate) { this._accountCache = new AccountCache({ size: this._accountCacheSettings.size, @@ -245,7 +243,6 @@ export class DefaultStateManager implements EVMStateManagerInterface { type: opts.storageCacheOpts?.type ?? CacheType.ORDERED_MAP, size: opts.storageCacheOpts?.size ?? 20000, } - if (!this._storageCacheSettings.deactivate) { this._storageCache = new StorageCache({ size: this._storageCacheSettings.size, @@ -259,7 +256,6 @@ export class DefaultStateManager implements EVMStateManagerInterface { type: opts.codeCacheOpts?.type ?? CacheType.ORDERED_MAP, size: opts.codeCacheOpts?.size ?? 20000, } - if (!this._codeCacheSettings.deactivate) { this._codeCache = new CodeCache({ size: this._codeCacheSettings.size, @@ -991,19 +987,8 @@ export class DefaultStateManager implements EVMStateManagerInterface { } const trie = this._getStorageTrie(address, account) - return new Promise((resolve, reject) => { - const storage: StorageDump = {} - const stream = trie.createReadStream() - - stream.on('data', (val: any) => { - storage[bytesToHex(val.key)] = bytesToHex(val.value) - }) - stream.on('end', () => { - resolve(storage) - }) - stream.on('error', (e) => { - reject(e) - }) + return trie.getValueMap().then((value) => { + return value.values }) } @@ -1026,44 +1011,24 @@ export class DefaultStateManager implements EVMStateManagerInterface { if (!account) { throw new Error(`Account does not exist.`) } - const trie = this._getStorageTrie(address, account) - return new Promise((resolve, reject) => { - let inRange = false - let i = 0 - - /** Object conforming to {@link StorageRange.storage}. */ - const storageMap: StorageRange['storage'] = {} - const stream = trie.createReadStream() - - stream.on('data', (val: any) => { - if (!inRange) { - // Check if the key is already in the correct range. - if (bytesToBigInt(val.key) >= startKey) { - inRange = true - } else { - return - } - } + const trie = this._getStorageTrie(address, account) - if (i < limit) { - storageMap[bytesToHex(val.key)] = { key: null, value: bytesToHex(val.value) } - i++ - } else if (i === limit) { - resolve({ - storage: storageMap, - nextKey: bytesToHex(val.key), - }) + return trie.getValueMap(startKey, limit).then((value) => { + const values = value.values + const dump = Object.create(null) + for (const key of Object.keys(values)) { + const val = values[key] + dump[key] = { + key: null, + value: val, } - }) + } - stream.on('end', () => { - resolve({ - storage: storageMap, - nextKey: null, - }) - }) - stream.on('error', (e) => reject(e)) + return { + storage: dump, + nextKey: value.nextKey, + } }) } diff --git a/packages/trie/package.json b/packages/trie/package.json index 17251fd4de..3eed919db0 100644 --- a/packages/trie/package.json +++ b/packages/trie/package.json @@ -59,8 +59,7 @@ "@types/readable-stream": "^2.3.13", "debug": "^4.3.4", "lru-cache": "10.1.0", - "ethereum-cryptography": "^2.2.1", - "readable-stream": "^3.6.0" + "ethereum-cryptography": "^2.2.1" }, "devDependencies": { "@ethereumjs/genesis": "^0.2.2", diff --git a/packages/trie/src/trie.ts b/packages/trie/src/trie.ts index 4cb59f7afe..703c099519 100644 --- a/packages/trie/src/trie.ts +++ b/packages/trie/src/trie.ts @@ -3,11 +3,13 @@ import { RLP } from '@ethereumjs/rlp' import { + BIGINT_0, KeyEncoding, Lock, MapDB, RLP_EMPTY_STRING, ValueEncoding, + bytesToBigInt, bytesToHex, bytesToUnprefixedHex, bytesToUtf8, @@ -29,8 +31,8 @@ import { import { verifyRangeProof } from './proof/range.js' import { ROOT_DB_KEY } from './types.js' import { _walkTrie } from './util/asyncWalk.js' +import { nibbleTypeToPackedBytes } from './util/encoding.js' import { bytesToNibbles, matchingNibbleLength } from './util/nibbles.js' -import { TrieReadStream as ReadStream } from './util/readStream.js' import { WalkController } from './util/walkController.js' import type { @@ -1081,14 +1083,6 @@ export class Trie { return true } - /** - * The `data` event is given an `Object` that has two properties; the `key` and the `value`. Both should be Uint8Arrays. - * @return Returns a [stream](https://nodejs.org/dist/latest-v12.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` - */ - createReadStream(): ReadStream { - return new ReadStream(this) - } - /** * Returns a copy of the underlying trie. * @@ -1227,4 +1221,45 @@ export class Trie { this.debug(`Deleting ${this._db.checkpoints.length} checkpoints.`, ['FLUSH_CHECKPOINTS']) this._db.checkpoints = [] } + + /** + * Returns a list of values stored in the trie + * @param startKey first unhashed key in the range to be returned (defaults to 0) + * @param limit - the number of keys to be returned (undefined means all keys) + * @returns an object with two properties (a map of all key/value pairs in the trie - or in the specified range) and then a `nextKey` reference if a range is specified + */ + async getValueMap( + startKey = BIGINT_0, + limit?: number + ): Promise<{ values: { [key: string]: string }; nextKey: null | string }> { + // If limit is undefined, all keys are inRange + let inRange = limit !== undefined ? false : true + let i = 0 + const values: { [key: string]: string } = {} + let nextKey: string | null = null + await this.walkAllValueNodes(async (node: TrieNode, currentKey: number[]) => { + if (node instanceof LeafNode) { + const keyBytes = nibbleTypeToPackedBytes(currentKey.concat(node.key())) + if (!inRange) { + // Check if the key is already in the correct range. + if (bytesToBigInt(keyBytes) >= startKey) { + inRange = true + } else { + return + } + } + + if (limit === undefined || i < limit) { + values[bytesToHex(keyBytes)] = bytesToHex(node._value) + i++ + } else if (i === limit) { + nextKey = bytesToHex(keyBytes) + } + } + }) + return { + values, + nextKey, + } + } } diff --git a/packages/trie/src/util/index.ts b/packages/trie/src/util/index.ts index 1297a1dbca..d86ae67d7d 100644 --- a/packages/trie/src/util/index.ts +++ b/packages/trie/src/util/index.ts @@ -1,5 +1,4 @@ export * from './encoding.js' export * from './genesisState.js' -export * from './readStream.js' export * from './tasks.js' export * from './walkController.js' diff --git a/packages/trie/src/util/readStream.ts b/packages/trie/src/util/readStream.ts deleted file mode 100644 index dfc002d29c..0000000000 --- a/packages/trie/src/util/readStream.ts +++ /dev/null @@ -1,66 +0,0 @@ -// eslint-disable-next-line implicit-dependencies/no-implicit -import { Readable } from 'readable-stream' - -import { BranchNode, LeafNode } from '../node/index.js' - -import { nibblestoBytes } from './nibbles.js' - -import type { Trie } from '../trie.js' -import type { FoundNodeFunction } from '../types.js' - -const _findValueNodes = async (trie: Trie, onFound: FoundNodeFunction): Promise => { - const outerOnFound: FoundNodeFunction = async (nodeRef, node, key, walkController) => { - let fullKey = key - if (node instanceof LeafNode) { - fullKey = key.concat(node.key()) - // found leaf node! - onFound(nodeRef, node, fullKey, walkController) - } else if (node instanceof BranchNode && node.value()) { - // found branch with value - onFound(nodeRef, node, fullKey, walkController) - } else { - // keep looking for value nodes - if (node !== null) { - walkController.allChildren(node, key) - } - } - } - await trie.walkTrie(trie.root(), outerOnFound) -} - -export class TrieReadStream extends Readable { - private trie: Trie - private _started: boolean - - constructor(trie: Trie) { - super({ objectMode: true }) - - this.trie = trie - this._started = false - } - - async _read() { - if (this._started) { - return - } - this._started = true - try { - await _findValueNodes(this.trie, async (_, node, key, walkController) => { - if (node !== null) { - this.push({ - key: nibblestoBytes(key), - value: node.value(), - }) - walkController.allChildren(node, key) - } - }) - } catch (error: any) { - if (error.message === 'Missing node in DB') { - // pass - } else { - throw error - } - } - this.push(null) - } -} diff --git a/packages/trie/test/stream.spec.ts b/packages/trie/test/stream.spec.ts deleted file mode 100644 index 5c4d05ff43..0000000000 --- a/packages/trie/test/stream.spec.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { utf8ToBytes } from '@ethereumjs/util' -import { assert, describe, it } from 'vitest' - -import { Trie } from '../src/index.js' - -import type { BatchDBOp } from '@ethereumjs/util' - -describe('kv stream test', () => { - const trie = new Trie() - const ops = [ - { - type: 'del', - key: utf8ToBytes('father'), - }, - { - type: 'put', - key: utf8ToBytes('name'), - value: utf8ToBytes('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: utf8ToBytes('dob'), - value: utf8ToBytes('16 February 1941'), - }, - { - type: 'put', - key: utf8ToBytes('spouse'), - value: utf8ToBytes('Kim Young-sook'), - }, - { - type: 'put', - key: utf8ToBytes('occupation'), - value: utf8ToBytes('Clown'), - }, - { - type: 'put', - key: utf8ToBytes('nameads'), - value: utf8ToBytes('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: utf8ToBytes('namfde'), - value: utf8ToBytes('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: utf8ToBytes('namsse'), - value: utf8ToBytes('Yuri Irsenovich Kim'), - }, - { - type: 'put', - key: utf8ToBytes('dofab'), - value: utf8ToBytes('16 February 1941'), - }, - { - type: 'put', - key: utf8ToBytes('spoudse'), - value: utf8ToBytes('Kim Young-sook'), - }, - { - type: 'put', - key: utf8ToBytes('occupdsation'), - value: utf8ToBytes('Clown'), - }, - { - type: 'put', - key: utf8ToBytes('dozzzb'), - value: utf8ToBytes('16 February 1941'), - }, - { - type: 'put', - key: utf8ToBytes('spouszze'), - value: utf8ToBytes('Kim Young-sook'), - }, - { - type: 'put', - key: utf8ToBytes('occupatdfion'), - value: utf8ToBytes('Clown'), - }, - { - type: 'put', - key: utf8ToBytes('dssob'), - value: utf8ToBytes('16 February 1941'), - }, - { - type: 'put', - key: utf8ToBytes('spossuse'), - value: utf8ToBytes('Kim Young-sook'), - }, - { - type: 'put', - key: utf8ToBytes('occupssation'), - value: utf8ToBytes('Clown'), - }, - ] as BatchDBOp[] - - const valObj1 = {} as any - const valObj2 = {} as any - for (const op of ops) { - if (op.type === 'put') { - valObj1[op.key.toString()] = op.value.toString() - valObj2[op.key.toString()] = op.value.toString() - } - } - - it('should populate trie', async () => { - await trie.batch(ops) - }) - - it('should fetch all of the nodes', () => { - const stream = trie.createReadStream() - stream.on('data', (d: any) => { - const key = d.key.toString() - const value = d.value.toString() - assert.equal(valObj1[key], value) - delete valObj1[key] - }) - stream.on('end', () => { - const keys = Object.keys(valObj1) - assert.equal(keys.length, 0) - }) - }) -}) - -describe('db stream test', () => { - const trie = new Trie() - const ops = [ - { - type: 'put', - key: utf8ToBytes('color'), - value: utf8ToBytes('purple'), - }, - { - type: 'put', - key: utf8ToBytes('food'), - value: utf8ToBytes('sushi'), - }, - { - type: 'put', - key: utf8ToBytes('fight'), - value: utf8ToBytes('fire'), - }, - { - type: 'put', - key: utf8ToBytes('colo'), - value: utf8ToBytes('trolo'), - }, - { - type: 'put', - key: utf8ToBytes('color'), - value: utf8ToBytes('blue'), - }, - { - type: 'put', - key: utf8ToBytes('color'), - value: utf8ToBytes('pink'), - }, - ] as BatchDBOp[] - - it('should populate trie', async () => { - trie.checkpoint() - await trie.batch(ops) - }) -}) diff --git a/packages/trie/test/trie/trie.spec.ts b/packages/trie/test/trie/trie.spec.ts index 9f06d99b08..a3f35ca252 100644 --- a/packages/trie/test/trie/trie.spec.ts +++ b/packages/trie/test/trie/trie.spec.ts @@ -1,6 +1,7 @@ import { KECCAK256_RLP, MapDB, + bigIntToBytes, bytesToHex, concatBytes, equalsBytes, @@ -286,3 +287,19 @@ describe('keyHashingFunction', async () => { assert.equal(bytesToHex(trieWithCommonCopy.root()), '0x80', 'used hash function from common') }) }) + +describe('getValueMap', () => { + it('should return a map of all hashed keys and values', async () => { + const trie = await createTrie({}) + const entries: [Uint8Array, string][] = [ + [bigIntToBytes(1n), '0x' + '0a'.repeat(32)], + [bigIntToBytes(2n), '0x' + '0b'.repeat(32)], + [bigIntToBytes(3n), '0x' + '0c'.repeat(32)], + ] + for (const entry of entries) { + await trie.put(entry[0], utf8ToBytes(entry[1])) + } + const dump = await trie.getValueMap() + assert.equal(Object.entries(dump.values).length, 3) + }) +}) From da22a3881cab3baa9c655ffd48273ae9bbd3b028 Mon Sep 17 00:00:00 2001 From: Scorbajio Date: Wed, 24 Jul 2024 04:39:29 -0700 Subject: [PATCH 18/58] Refactor trie util helpers (#3534) * Rename nibblestoBytes to nibblesTypeToPackedBytes * Rename function * Fix function name * Make nibblesToBytes return a byte array to conform to how bytesToNibbles returns one * Fix lint issues * Fix function name * Fix lint issue * update import --------- Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> --- packages/trie/src/node/node.ts | 4 +-- packages/trie/src/proof/range.ts | 10 +++--- packages/trie/src/trie.ts | 5 ++- packages/trie/src/util/encoding.ts | 35 ++++++------------- packages/trie/src/util/nibbles.ts | 2 +- packages/trie/test/util/encodingUtils.spec.ts | 4 +-- 6 files changed, 23 insertions(+), 37 deletions(-) diff --git a/packages/trie/src/node/node.ts b/packages/trie/src/node/node.ts index 76b6888811..c4952532ac 100644 --- a/packages/trie/src/node/node.ts +++ b/packages/trie/src/node/node.ts @@ -1,7 +1,7 @@ import { RLP } from '@ethereumjs/rlp' import { addHexPrefix, removeHexPrefix } from '../util/hex.js' -import { nibblestoBytes } from '../util/nibbles.js' +import { nibblesTypeToPackedBytes } from '../util/nibbles.js' import type { Nibbles } from '../types.js' @@ -45,7 +45,7 @@ export class Node { } raw(): [Uint8Array, Uint8Array] { - return [nibblestoBytes(this.encodedKey()), this._value] + return [nibblesTypeToPackedBytes(this.encodedKey()), this._value] } serialize(): Uint8Array { diff --git a/packages/trie/src/proof/range.ts b/packages/trie/src/proof/range.ts index 57aafdbd57..98003d2dc1 100644 --- a/packages/trie/src/proof/range.ts +++ b/packages/trie/src/proof/range.ts @@ -3,7 +3,7 @@ import { equalsBytes } from '@ethereumjs/util' import { createTrieFromProof } from '../index.js' import { BranchNode, ExtensionNode, LeafNode } from '../node/index.js' import { Trie } from '../trie.js' -import { nibblesCompare, nibblestoBytes } from '../util/nibbles.js' +import { nibblesCompare, nibblesTypeToPackedBytes } from '../util/nibbles.js' import type { HashKeysFunction, Nibbles, TrieNode } from '../types.js' @@ -439,7 +439,7 @@ export async function verifyRangeProof( if (proof === null && firstKey === null && lastKey === null) { const trie = new Trie({ useKeyHashingFunction }) for (let i = 0; i < keys.length; i++) { - await trie.put(nibblestoBytes(keys[i]), values[i]) + await trie.put(nibblesTypeToPackedBytes(keys[i]), values[i]) } if (!equalsBytes(rootHash, trie.root())) { throw new Error('invalid all elements proof: root mismatch') @@ -452,7 +452,7 @@ export async function verifyRangeProof( if (keys.length === 0) { const { trie, value } = await verifyProof( rootHash, - nibblestoBytes(firstKey), + nibblesTypeToPackedBytes(firstKey), proof, useKeyHashingFunction ) @@ -475,7 +475,7 @@ export async function verifyRangeProof( if (keys.length === 1 && nibblesCompare(firstKey, lastKey) === 0) { const { trie, value } = await verifyProof( rootHash, - nibblestoBytes(firstKey), + nibblesTypeToPackedBytes(firstKey), proof, useKeyHashingFunction ) @@ -513,7 +513,7 @@ export async function verifyRangeProof( // Put all elements to the trie for (let i = 0; i < keys.length; i++) { - await trie.put(nibblestoBytes(keys[i]), values[i]) + await trie.put(nibblesTypeToPackedBytes(keys[i]), values[i]) } // Compare rootHash diff --git a/packages/trie/src/trie.ts b/packages/trie/src/trie.ts index 703c099519..1792c30b30 100644 --- a/packages/trie/src/trie.ts +++ b/packages/trie/src/trie.ts @@ -31,8 +31,7 @@ import { import { verifyRangeProof } from './proof/range.js' import { ROOT_DB_KEY } from './types.js' import { _walkTrie } from './util/asyncWalk.js' -import { nibbleTypeToPackedBytes } from './util/encoding.js' -import { bytesToNibbles, matchingNibbleLength } from './util/nibbles.js' +import { bytesToNibbles, matchingNibbleLength, nibblesTypeToPackedBytes } from './util/nibbles.js' import { WalkController } from './util/walkController.js' import type { @@ -1239,7 +1238,7 @@ export class Trie { let nextKey: string | null = null await this.walkAllValueNodes(async (node: TrieNode, currentKey: number[]) => { if (node instanceof LeafNode) { - const keyBytes = nibbleTypeToPackedBytes(currentKey.concat(node.key())) + const keyBytes = nibblesTypeToPackedBytes(currentKey.concat(node.key())) if (!inRange) { // Check if the key is already in the correct range. if (bytesToBigInt(keyBytes) >= startKey) { diff --git a/packages/trie/src/util/encoding.ts b/packages/trie/src/util/encoding.ts index 43b1ea10d6..5212d2f708 100644 --- a/packages/trie/src/util/encoding.ts +++ b/packages/trie/src/util/encoding.ts @@ -1,4 +1,6 @@ -import { hexToBytes, toBytes, unprefixedHexToBytes } from '@ethereumjs/util' +import { concatBytes, hexToBytes, toBytes, unprefixedHexToBytes } from '@ethereumjs/util' + +import { nibblesTypeToPackedBytes } from './nibbles.js' import type { Nibbles } from '../types.js' @@ -32,10 +34,13 @@ export const hasTerminator = (nibbles: Uint8Array) => { return nibbles.length > 0 && nibbles[nibbles.length - 1] === 16 } -export const nibblesToBytes = (nibbles: Uint8Array, bytes: Uint8Array) => { +export const nibblesToBytes = (nibbles: Uint8Array) => { + const bytes = new Uint8Array(nibbles.length / 2) for (let bi = 0, ni = 0; ni < nibbles.length; bi += 1, ni += 2) { bytes[bi] = (nibbles[ni] << 4) | nibbles[ni + 1] } + + return bytes } export const hexToKeybytes = (hex: Uint8Array) => { @@ -45,10 +50,8 @@ export const hexToKeybytes = (hex: Uint8Array) => { if (hex.length % 2 === 1) { throw Error("Can't convert hex key of odd length") } - const key = new Uint8Array(hex.length / 2) - nibblesToBytes(hex, key) - return key + return nibblesToBytes(hex) } // hex to compact @@ -69,9 +72,9 @@ export const nibblesToCompactBytes = (nibbles: Uint8Array) => { buf[0] |= nibbles[0] nibbles = nibbles.subarray(1) } + // create bytes out of the rest even nibbles - nibblesToBytes(nibbles, buf.subarray(1)) - return buf + return concatBytes(buf.subarray(0, 1), nibblesToBytes(nibbles)) } export const bytesToNibbles = (str: Uint8Array) => { @@ -103,22 +106,6 @@ export const compactBytesToNibbles = (compact: Uint8Array) => { return base.subarray(chop) } -/** - * Packs every two nibbles into a single byte - * - * @param arr Nibble typed nibble array - * @returns Uint8Array typed byte array - */ -export const nibbleTypeToPackedBytes = (arr: Nibbles): Uint8Array => { - const buf = new Uint8Array(arr.length / 2) - for (let i = 0; i < buf.length; i++) { - let q = i * 2 - buf[i] = (arr[q] << 4) + arr[++q] - } - - return buf -} - /** * Converts each nibble into a single byte * @@ -167,7 +154,7 @@ export const pathToHexKey = (path: string, extension: Nibbles, retType: string): if (retType === 'hex') { return nibbleTypeToByteType(n.concat(extension)) } else if (retType === 'keybyte') { - return nibbleTypeToPackedBytes(n.concat(extension)) + return nibblesTypeToPackedBytes(n.concat(extension)) } throw Error('retType must be either "keybyte" or "hex"') } diff --git a/packages/trie/src/util/nibbles.ts b/packages/trie/src/util/nibbles.ts index 3c5d9c231f..9bc473f310 100644 --- a/packages/trie/src/util/nibbles.ts +++ b/packages/trie/src/util/nibbles.ts @@ -26,7 +26,7 @@ export function bytesToNibbles(key: Uint8Array): Nibbles { * @private * @param arr - Nibble array */ -export function nibblestoBytes(arr: Nibbles): Uint8Array { +export function nibblesTypeToPackedBytes(arr: Nibbles): Uint8Array { const buf = new Uint8Array(arr.length / 2) for (let i = 0; i < buf.length; i++) { let q = i * 2 diff --git a/packages/trie/test/util/encodingUtils.spec.ts b/packages/trie/test/util/encodingUtils.spec.ts index 08152f8406..cf09a89d8d 100644 --- a/packages/trie/test/util/encodingUtils.spec.ts +++ b/packages/trie/test/util/encodingUtils.spec.ts @@ -7,10 +7,10 @@ import { compactBytesToNibbles, mergeAndFormatKeyPaths, nibbleTypeToByteType, - nibbleTypeToPackedBytes, nibblesToCompactBytes, pathToHexKey, } from '../../src/util/encoding.js' +import { nibblesTypeToPackedBytes } from '../../src/util/nibbles.js' import type { Nibbles } from '../../src/types.js' @@ -93,7 +93,7 @@ describe('encoding', () => { // Calculate the expected result manually based on the functions used in the pathToHexKey function const b = hexToBytes(`0x${path}`) const n = byteTypeToNibbleType(b) - const expected = nibbleTypeToPackedBytes(n.concat(extension)) + const expected = nibblesTypeToPackedBytes(n.concat(extension)) assert.deepEqual( result, From 759dcd2cc49372243f78b20990a6124f8e3d8c11 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Wed, 24 Jul 2024 14:22:35 +0200 Subject: [PATCH 19/58] tx: clarify some method names (#3535) Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> --- packages/tx/src/1559/tx.ts | 4 ++-- packages/tx/src/2930/tx.ts | 4 ++-- packages/tx/src/4844/tx.ts | 4 ++-- packages/tx/src/7702/tx.ts | 4 ++-- packages/tx/src/baseTransaction.ts | 21 +++++++++------- packages/tx/src/capabilities/eip2930.ts | 4 ++-- packages/tx/src/capabilities/eip7702.ts | 6 ++--- packages/tx/src/capabilities/legacy.ts | 4 ++-- packages/tx/src/legacy/tx.ts | 4 ++-- packages/tx/src/types.ts | 4 ++-- packages/tx/src/util.ts | 4 ++-- packages/tx/test/eip3860.spec.ts | 2 +- packages/tx/test/legacy.spec.ts | 24 +++++++++---------- packages/tx/test/typedTxsAndEIP2930.spec.ts | 15 ++++++------ packages/vm/src/runTx.ts | 14 +++++------ .../vm/test/api/EIPs/eip-3198-BaseFee.spec.ts | 2 +- packages/vm/test/api/runTx.spec.ts | 4 ++-- 17 files changed, 65 insertions(+), 59 deletions(-) diff --git a/packages/tx/src/1559/tx.ts b/packages/tx/src/1559/tx.ts index 67db0d1cf9..df4a3f155a 100644 --- a/packages/tx/src/1559/tx.ts +++ b/packages/tx/src/1559/tx.ts @@ -107,8 +107,8 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction errors.push('Invalid Signature') } - if (this.getBaseFee() > this.gasLimit) { - errors.push(`gasLimit is too low. given ${this.gasLimit}, need at least ${this.getBaseFee()}`) + if (this.getIntrinsicGas() > this.gasLimit) { + errors.push( + `gasLimit is too low. given ${this.gasLimit}, need at least ${this.getIntrinsicGas()}` + ) } return errors @@ -171,11 +173,14 @@ export abstract class BaseTransaction } /** - * The minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) + * The minimum gas limit which the tx to have to be valid. + * This covers costs as the standard fee (21000 gas), the data fee (paid for each calldata byte), + * the optional creation fee (if the transaction creates a contract), and if relevant the gas + * to be paid for access lists (EIP-2930) and authority lists (EIP-7702). */ - getBaseFee(): bigint { + getIntrinsicGas(): bigint { const txFee = this.common.param('txGas') - let fee = this.getDataFee() + let fee = this.getDataGas() if (txFee) fee += txFee if (this.common.gteHardfork('homestead') && this.toCreationAddress()) { const txCreationFee = this.common.param('txCreationGas') @@ -185,9 +190,9 @@ export abstract class BaseTransaction } /** - * The amount of gas paid for the data in this tx + * The amount of gas paid for the calldata in this tx */ - getDataFee(): bigint { + getDataGas(): bigint { const txDataZero = this.common.param('txDataZeroGas') const txDataNonZero = this.common.param('txDataNonZeroGas') @@ -213,7 +218,7 @@ export abstract class BaseTransaction abstract getEffectivePriorityFee(baseFee: bigint | undefined): bigint /** - * The up front amount that an account must have for this transaction to be valid + * The upfront amount of wei to be paid in order for this tx to be valid and included in a block */ abstract getUpfrontCost(): bigint diff --git a/packages/tx/src/capabilities/eip2930.ts b/packages/tx/src/capabilities/eip2930.ts index 1d9daa12b5..38043b782e 100644 --- a/packages/tx/src/capabilities/eip2930.ts +++ b/packages/tx/src/capabilities/eip2930.ts @@ -7,6 +7,6 @@ import type { EIP2930CompatibleTx } from '../types.js' /** * The amount of gas paid for the data in this tx */ -export function getDataFee(tx: EIP2930CompatibleTx): bigint { - return Legacy.getDataFee(tx, BigInt(AccessLists.getDataFeeEIP2930(tx.accessList, tx.common))) +export function getDataGas(tx: EIP2930CompatibleTx): bigint { + return Legacy.getDataGas(tx, BigInt(AccessLists.getDataGasEIP2930(tx.accessList, tx.common))) } diff --git a/packages/tx/src/capabilities/eip7702.ts b/packages/tx/src/capabilities/eip7702.ts index 67a3d2f285..52c1b3bc91 100644 --- a/packages/tx/src/capabilities/eip7702.ts +++ b/packages/tx/src/capabilities/eip7702.ts @@ -7,10 +7,10 @@ import type { EIP7702CompatibleTx } from '../types.js' /** * The amount of gas paid for the data in this tx */ -export function getDataFee(tx: EIP7702CompatibleTx): bigint { - const eip2930Cost = BigInt(AccessLists.getDataFeeEIP2930(tx.accessList, tx.common)) +export function getDataGas(tx: EIP7702CompatibleTx): bigint { + const eip2930Cost = BigInt(AccessLists.getDataGasEIP2930(tx.accessList, tx.common)) const eip7702Cost = BigInt( tx.authorizationList.length * Number(tx.common.param('perAuthBaseGas')) ) - return Legacy.getDataFee(tx, eip2930Cost + eip7702Cost) + return Legacy.getDataGas(tx, eip2930Cost + eip7702Cost) } diff --git a/packages/tx/src/capabilities/legacy.ts b/packages/tx/src/capabilities/legacy.ts index e2eda09199..342acd39a4 100644 --- a/packages/tx/src/capabilities/legacy.ts +++ b/packages/tx/src/capabilities/legacy.ts @@ -22,12 +22,12 @@ export function isSigned(tx: LegacyTxInterface): boolean { /** * The amount of gas paid for the data in this tx */ -export function getDataFee(tx: LegacyTxInterface, extraCost?: bigint): bigint { +export function getDataGas(tx: LegacyTxInterface, extraCost?: bigint): bigint { if (tx.cache.dataFee && tx.cache.dataFee.hardfork === tx.common.hardfork()) { return tx.cache.dataFee.value } - const cost = BaseTransaction.prototype.getDataFee.bind(tx)() + (extraCost ?? 0n) + const cost = BaseTransaction.prototype.getDataGas.bind(tx)() + (extraCost ?? 0n) if (Object.isFrozen(tx)) { tx.cache.dataFee = { diff --git a/packages/tx/src/legacy/tx.ts b/packages/tx/src/legacy/tx.ts index f0e59036a0..29ec2c64d2 100644 --- a/packages/tx/src/legacy/tx.ts +++ b/packages/tx/src/legacy/tx.ts @@ -176,8 +176,8 @@ export class LegacyTransaction extends BaseTransaction { /** * The amount of gas paid for the data in this tx */ - getDataFee(): bigint { - return Legacy.getDataFee(this) + getDataGas(): bigint { + return Legacy.getDataGas(this) } /** diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index e59367ab40..792fbe0427 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -199,8 +199,8 @@ export interface TransactionInterface { { common, allowUnlimitedInitCodeSize: false } ) assert.ok( - eip3860ActiveTx.getDataFee() === eip3860DeactivedTx.getDataFee(), + eip3860ActiveTx.getDataGas() === eip3860DeactivedTx.getDataGas(), 'charged initcode analysis gas' ) } diff --git a/packages/tx/test/legacy.spec.ts b/packages/tx/test/legacy.spec.ts index 9026ad2441..0f23043122 100644 --- a/packages/tx/test/legacy.spec.ts +++ b/packages/tx/test/legacy.spec.ts @@ -181,31 +181,31 @@ describe('[Transaction]', () => { } }) - it('getBaseFee() -> should return base fee', () => { + it('getIntrinsicGas() -> should return base fee', () => { const tx = createLegacyTx({}) - assert.equal(tx.getBaseFee(), BigInt(53000)) + assert.equal(tx.getIntrinsicGas(), BigInt(53000)) }) - it('getDataFee() -> should return data fee', () => { + it('getDataGas() -> should return data fee', () => { let tx = createLegacyTx({}) - assert.equal(tx.getDataFee(), BigInt(0)) + assert.equal(tx.getDataGas(), BigInt(0)) tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) ) - assert.equal(tx.getDataFee(), BigInt(1716)) + assert.equal(tx.getDataGas(), BigInt(1716)) tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { freeze: false } ) - assert.equal(tx.getDataFee(), BigInt(1716)) + assert.equal(tx.getDataGas(), BigInt(1716)) }) - it('getDataFee() -> should return correct data fee for istanbul', () => { + it('getDataGas() -> should return correct data fee for istanbul', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) let tx = createLegacyTx({}, { common }) - assert.equal(tx.getDataFee(), BigInt(0)) + assert.equal(tx.getDataGas(), BigInt(0)) tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), @@ -213,10 +213,10 @@ describe('[Transaction]', () => { common, } ) - assert.equal(tx.getDataFee(), BigInt(1716)) + assert.equal(tx.getDataGas(), BigInt(1716)) }) - it('getDataFee() -> should invalidate cached value on hardfork change', () => { + it('getDataGas() -> should invalidate cached value on hardfork change', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) const tx = createLegacyTxFromBytesArray( txFixtures[0].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), @@ -224,9 +224,9 @@ describe('[Transaction]', () => { common, } ) - assert.equal(tx.getDataFee(), BigInt(656)) + assert.equal(tx.getDataGas(), BigInt(656)) tx.common.setHardfork(Hardfork.Istanbul) - assert.equal(tx.getDataFee(), BigInt(240)) + assert.equal(tx.getDataGas(), BigInt(240)) }) it('getEffectivePriorityFee() -> should return correct values', () => { diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index b6e19e35eb..5edf37d877 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -413,18 +413,18 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }) }) - it('getDataFee()', () => { + it('getDataGas()', () => { for (const txType of txTypes) { let tx = txType.create.txData({}, { common }) - assert.equal(tx.getDataFee(), BigInt(0), 'Should return data fee when frozen') + assert.equal(tx.getDataGas(), BigInt(0), 'Should return data fee when frozen') tx = txType.create.txData({}, { common, freeze: false }) - assert.equal(tx.getDataFee(), BigInt(0), 'Should return data fee when not frozen') + assert.equal(tx.getDataGas(), BigInt(0), 'Should return data fee when not frozen') const mutableCommon = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) tx = txType.create.txData({}, { common: mutableCommon }) tx.common.setHardfork(Hardfork.Istanbul) - assert.equal(tx.getDataFee(), BigInt(0), 'Should invalidate cached value on hardfork change') + assert.equal(tx.getDataGas(), BigInt(0), 'Should invalidate cached value on hardfork change') } }) }) @@ -496,7 +496,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const creationFee: number = Number(common.param('txCreationGas')) assert.ok( - tx.getBaseFee() === + tx.getIntrinsicGas() === BigInt( txDataNonZero * 2 + txDataZero + @@ -517,7 +517,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) assert.ok( - tx.getBaseFee() === + tx.getIntrinsicGas() === BigInt( txDataNonZero * 2 + txDataZero + @@ -542,7 +542,8 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ) assert.ok( - tx.getBaseFee() === BigInt(baseFee + accessListAddressCost * 2 + accessListStorageKeyCost * 3) + tx.getIntrinsicGas() === + BigInt(baseFee + accessListAddressCost * 2 + accessListStorageKeyCost * 3) ) }) diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 4ea07f89c4..40c58cdc5a 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -271,12 +271,12 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { } // Validate gas limit against tx base fee (DataFee + TxFee + Creation Fee) - const txBaseFee = tx.getBaseFee() + const intrinsicGas = tx.getIntrinsicGas() let gasLimit = tx.gasLimit - if (gasLimit < txBaseFee) { + if (gasLimit < intrinsicGas) { const msg = _errorMsg( `tx gas limit ${Number(gasLimit)} is lower than the minimum gas limit of ${Number( - txBaseFee + intrinsicGas )}`, vm, block, @@ -284,9 +284,9 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { ) throw new Error(msg) } - gasLimit -= txBaseFee + gasLimit -= intrinsicGas if (vm.DEBUG) { - debugGas(`Subtracting base fee (${txBaseFee}) from gasLimit (-> ${gasLimit})`) + debugGas(`Subtracting base fee (${intrinsicGas}) from gasLimit (-> ${gasLimit})`) } if (vm.common.isActivatedEIP(1559)) { @@ -576,9 +576,9 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { } // Calculate the total gas used - results.totalGasSpent = results.execResult.executionGasUsed + txBaseFee + results.totalGasSpent = results.execResult.executionGasUsed + intrinsicGas if (vm.DEBUG) { - debugGas(`tx add baseFee ${txBaseFee} to totalGasSpent (-> ${results.totalGasSpent})`) + debugGas(`tx add baseFee ${intrinsicGas} to totalGasSpent (-> ${results.totalGasSpent})`) } // Add blob gas used to result diff --git a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts index 90a91fa843..1557b8fd7b 100644 --- a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts @@ -91,7 +91,7 @@ describe('EIP3198 tests', () => { tx: block.transactions[0], block, }) - const txBaseFee = block.transactions[0].getBaseFee() + const txBaseFee = block.transactions[0].getIntrinsicGas() const gasUsed = results.totalGasSpent - txBaseFee assert.equal(gasUsed, BigInt(2), 'gas used correct') assert.equal(stack[0], fee, 'right item pushed on stack') diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index 9aeb284ad0..dd716efc46 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -601,8 +601,8 @@ describe('runTx() -> API return values', () => { assert.equal( res.totalGasSpent, - tx.getBaseFee(), - `runTx result -> gasUsed -> tx.getBaseFee() (${txType.name})` + tx.getIntrinsicGas(), + `runTx result -> gasUsed -> tx.getIntrinsicGas() (${txType.name})` ) if (tx instanceof FeeMarketEIP1559Transaction) { const baseFee = BigInt(7) From 23d796d9223958af937aa2039f45f7cd5f323ab9 Mon Sep 17 00:00:00 2001 From: acolytec3 <17355484+acolytec3@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:48:35 -0400 Subject: [PATCH 20/58] Update linting (#3539) --- config/eslint.cjs | 5 +- config/tsconfig.lint.json | 15 ++ package-lock.json | 135 ++++++------- package.json | 10 +- packages/block/.eslintrc.cjs | 16 +- packages/block/examples/1559.ts | 6 +- packages/block/examples/4844.ts | 8 +- packages/block/examples/clique.ts | 2 +- packages/block/examples/pos.ts | 4 +- packages/block/examples/pow.ts | 2 +- packages/block/examples/withdrawals.ts | 9 +- packages/block/src/block.ts | 22 +-- packages/block/src/constructors.ts | 24 +-- packages/block/src/from-beacon-payload.ts | 2 +- packages/block/src/from-rpc.ts | 4 +- packages/block/src/header-from-rpc.ts | 2 +- packages/block/src/header.ts | 50 ++--- packages/block/src/helpers.ts | 4 +- packages/block/src/types.ts | 4 +- packages/block/test/block.spec.ts | 52 ++--- packages/block/test/clique.spec.ts | 26 +-- packages/block/test/difficulty.spec.ts | 12 +- packages/block/test/eip1559block.spec.ts | 60 +++--- packages/block/test/eip4788block.spec.ts | 14 +- packages/block/test/eip4844block.spec.ts | 48 ++--- packages/block/test/eip4895block.spec.ts | 44 ++--- packages/block/test/eip7685block.spec.ts | 16 +- .../block/test/from-beacon-payload.spec.ts | 8 +- packages/block/test/from-rpc.spec.ts | 26 +-- packages/block/test/header.spec.ts | 48 ++--- packages/block/test/mergeBlock.spec.ts | 4 +- packages/block/test/util.ts | 4 +- packages/block/tsconfig.lint.json | 3 + packages/blockchain/.eslintrc.cjs | 16 +- packages/blockchain/examples/clique.ts | 4 +- packages/blockchain/examples/gethGenesis.ts | 7 +- packages/blockchain/examples/simple.ts | 8 +- packages/blockchain/src/blockchain.ts | 28 +-- packages/blockchain/src/consensus/clique.ts | 24 +-- packages/blockchain/src/constructors.ts | 8 +- packages/blockchain/src/db/helpers.ts | 6 +- packages/blockchain/src/db/manager.ts | 4 +- packages/blockchain/src/db/operation.ts | 2 +- packages/blockchain/src/helpers.ts | 2 +- packages/blockchain/src/types.ts | 4 +- .../blockchain/test/blockValidation.spec.ts | 42 ++--- packages/blockchain/test/clique.spec.ts | 178 +++++++++--------- .../blockchain/test/customConsensus.spec.ts | 20 +- packages/blockchain/test/index.spec.ts | 40 ++-- packages/blockchain/test/iterator.spec.ts | 14 +- packages/blockchain/test/pos.spec.ts | 12 +- packages/blockchain/test/reorg.spec.ts | 42 ++--- packages/blockchain/test/util.ts | 16 +- packages/blockchain/test/utils.spec.ts | 4 +- packages/blockchain/tsconfig.lint.json | 3 + packages/client/.eslintrc.cjs | 7 +- packages/client/bin/cli.ts | 26 +-- packages/client/bin/startRpc.ts | 26 +-- packages/client/src/blockchain/chain.ts | 18 +- packages/client/src/client.ts | 8 +- packages/client/src/config.ts | 6 +- packages/client/src/execution/level.ts | 4 +- packages/client/src/execution/receipt.ts | 20 +- packages/client/src/execution/vmexecution.ts | 66 +++---- packages/client/src/ext/jwt-simple.ts | 4 +- packages/client/src/ext/qheap.ts | 4 +- packages/client/src/logging.ts | 4 +- packages/client/src/miner/miner.ts | 18 +- packages/client/src/miner/pendingBlock.ts | 30 +-- packages/client/src/net/peer/rlpxpeer.ts | 6 +- packages/client/src/net/peerpool.ts | 4 +- .../client/src/net/protocol/boundprotocol.ts | 4 +- .../client/src/net/protocol/ethprotocol.ts | 6 +- .../client/src/net/protocol/flowcontrol.ts | 2 +- .../client/src/net/protocol/lesprotocol.ts | 8 +- .../client/src/net/protocol/snapprotocol.ts | 8 +- packages/client/src/net/server/rlpxserver.ts | 8 +- packages/client/src/rpc/index.ts | 4 +- packages/client/src/rpc/modules/debug.ts | 22 +-- .../rpc/modules/engine/CLConnectionManager.ts | 42 ++--- .../client/src/rpc/modules/engine/engine.ts | 134 ++++++------- .../src/rpc/modules/engine/util/generic.ts | 10 +- .../src/rpc/modules/engine/util/newPayload.ts | 8 +- packages/client/src/rpc/modules/eth.ts | 90 ++++----- packages/client/src/rpc/modules/net.ts | 4 +- packages/client/src/rpc/validation.ts | 10 +- .../client/src/service/fullethereumservice.ts | 18 +- packages/client/src/service/service.ts | 10 +- packages/client/src/service/skeleton.ts | 158 ++++++++-------- packages/client/src/service/txpool.ts | 36 ++-- packages/client/src/sync/beaconsync.ts | 12 +- .../client/src/sync/fetcher/accountfetcher.ts | 58 +++--- .../client/src/sync/fetcher/blockfetcher.ts | 10 +- .../src/sync/fetcher/blockfetcherbase.ts | 14 +- .../src/sync/fetcher/bytecodefetcher.ts | 10 +- packages/client/src/sync/fetcher/fetcher.ts | 42 ++--- .../client/src/sync/fetcher/headerfetcher.ts | 4 +- .../src/sync/fetcher/reverseblockfetcher.ts | 8 +- .../client/src/sync/fetcher/storagefetcher.ts | 58 +++--- .../src/sync/fetcher/trienodefetcher.ts | 22 +-- packages/client/src/sync/fullsync.ts | 8 +- packages/client/src/sync/lightsync.ts | 2 +- packages/client/src/sync/snapsync.ts | 16 +- packages/client/src/sync/sync.ts | 4 +- packages/client/src/util/debug.ts | 4 +- packages/client/src/util/index.ts | 4 +- packages/client/src/util/parse.ts | 2 +- packages/client/src/util/rpc.ts | 4 +- packages/client/test/blockchain/chain.spec.ts | 4 +- packages/client/test/cli/cli.spec.ts | 84 ++++----- .../client/test/execution/vmexecution.spec.ts | 6 +- packages/client/test/ext/jwt-simple.spec.ts | 2 +- .../integration/fullethereumservice.spec.ts | 10 +- .../test/integration/lightsync.spec.backup.ts | 6 +- .../client/test/integration/merge.spec.ts | 8 +- .../client/test/integration/miner.spec.ts | 8 +- .../test/integration/mocks/mockchain.ts | 2 +- .../client/test/integration/mocks/mockpeer.ts | 2 +- .../client/test/integration/mocks/network.ts | 2 +- .../client/test/integration/peerpool.spec.ts | 2 +- packages/client/test/integration/util.ts | 4 +- packages/client/test/logging.spec.ts | 10 +- packages/client/test/miner/miner.spec.ts | 14 +- .../client/test/miner/pendingBlock.spec.ts | 40 ++-- packages/client/test/net/peer/peer.spec.ts | 4 +- .../client/test/net/peer/rlpxpeer.spec.ts | 6 +- packages/client/test/net/peerpool.spec.ts | 2 +- .../test/net/protocol/ethprotocol.spec.ts | 22 +-- .../test/net/protocol/lesprotocol.spec.ts | 4 +- .../test/net/protocol/snapprotocol.spec.ts | 88 ++++----- .../client/test/net/server/rlpxserver.spec.ts | 20 +- .../client/test/rpc/debug/getRawBlock.spec.ts | 14 +- .../test/rpc/debug/getRawHeader.spec.ts | 16 +- .../test/rpc/debug/getRawReceipts.spec.ts | 8 +- .../test/rpc/debug/getRawTransaction.spec.ts | 6 +- .../test/rpc/debug/storageRangeAt.spec.ts | 28 +-- .../client/test/rpc/debug/traceCall.spec.ts | 4 +- .../test/rpc/debug/traceTransaction.spec.ts | 12 +- .../rpc/engine/CLConnectionManager.spec.ts | 6 +- .../rpc/engine/exchangeCapabilities.spec.ts | 2 +- .../rpc/engine/forkchoiceUpdatedV1.spec.ts | 20 +- .../engine/getPayloadBodiesByHashV1.spec.ts | 30 +-- .../engine/getPayloadBodiesByRangeV1.spec.ts | 30 +-- .../test/rpc/engine/getPayloadV3.spec.ts | 6 +- .../client/test/rpc/engine/kaustinen6.spec.ts | 4 +- .../test/rpc/engine/newPayloadV1.spec.ts | 18 +- .../test/rpc/engine/newPayloadV2.spec.ts | 14 +- .../test/rpc/engine/newPayloadV3.spec.ts | 2 +- .../newPayloadV3VersionedHashes.spec.ts | 8 +- .../test/rpc/engine/newPayloadV4.spec.ts | 6 +- .../client/test/rpc/engine/preimages.spec.ts | 10 +- .../test/rpc/engine/withdrawals.spec.ts | 10 +- .../client/test/rpc/eth/blobBaseFee.spec.ts | 6 +- packages/client/test/rpc/eth/call.spec.ts | 8 +- packages/client/test/rpc/eth/chainId.spec.ts | 2 +- .../client/test/rpc/eth/estimateGas.spec.ts | 18 +- packages/client/test/rpc/eth/gasPrice.spec.ts | 34 ++-- .../client/test/rpc/eth/getBalance.spec.ts | 10 +- .../test/rpc/eth/getBlockByHash.spec.ts | 2 +- .../test/rpc/eth/getBlockByNumber.spec.ts | 14 +- .../test/rpc/eth/getBlockReceipts.spec.ts | 12 +- .../getBlockTransactionCountByNumber.spec.ts | 4 +- packages/client/test/rpc/eth/getCode.spec.ts | 4 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 28 +-- packages/client/test/rpc/eth/getLogs.spec.ts | 34 ++-- packages/client/test/rpc/eth/getProof.spec.ts | 4 +- .../client/test/rpc/eth/getStorageAt.spec.ts | 6 +- .../getTransactionByBlockHashAndIndex.spec.ts | 4 +- .../test/rpc/eth/getTransactionByHash.spec.ts | 8 +- .../test/rpc/eth/getTransactionCount.spec.ts | 2 +- .../rpc/eth/getTransactionReceipt.spec.ts | 8 +- .../test/rpc/eth/sendRawTransaction.spec.ts | 12 +- packages/client/test/rpc/eth/syncing.spec.ts | 4 +- packages/client/test/rpc/helpers.ts | 6 +- packages/client/test/rpc/net/version.spec.ts | 6 +- .../client/test/rpc/txpool/content.spec.ts | 8 +- packages/client/test/rpc/validation.spec.ts | 164 ++++++++-------- packages/client/test/rpc/web3/sha3.spec.ts | 4 +- .../test/service/fullethereumservice.spec.ts | 24 +-- .../test/service/lightethereumservice.spec.ts | 2 +- .../client/test/sim/4844-blobpost.spec.ts | 8 +- packages/client/test/sim/4844-devnet.spec.ts | 18 +- packages/client/test/sim/beaconsync.spec.ts | 16 +- packages/client/test/sim/eof.spec.ts | 10 +- packages/client/test/sim/mainnet.spec.ts | 4 +- packages/client/test/sim/simutils.ts | 34 ++-- packages/client/test/sim/snapsync.spec.ts | 22 +-- packages/client/test/sync/beaconsync.spec.ts | 14 +- .../test/sync/fetcher/accountfetcher.spec.ts | 22 +-- .../test/sync/fetcher/blockfetcher.spec.ts | 10 +- .../test/sync/fetcher/bytecodefetcher.spec.ts | 2 +- .../client/test/sync/fetcher/fetcher.spec.ts | 6 +- .../test/sync/fetcher/headerfetcher.spec.ts | 8 +- .../sync/fetcher/reverseblockfetcher.spec.ts | 20 +- .../test/sync/fetcher/storagefetcher.spec.ts | 50 ++--- .../test/sync/fetcher/trienodefetcher.spec.ts | 10 +- packages/client/test/sync/fullsync.spec.ts | 4 +- packages/client/test/sync/lightsync.spec.ts | 10 +- packages/client/test/sync/skeleton.spec.ts | 178 +++++++++--------- packages/client/test/sync/txpool.spec.ts | 78 ++++---- packages/client/test/util/parse.spec.ts | 16 +- packages/client/test/util/rpc.spec.ts | 4 +- packages/client/test/util/wasmCrypto.spec.ts | 8 +- packages/client/tsconfig.eslint.json | 3 - packages/client/tsconfig.lint.json | 3 + packages/common/.eslintrc.cjs | 16 +- packages/common/examples/common.ts | 2 +- packages/common/examples/customChain.ts | 1 + packages/common/examples/customChains.ts | 1 + packages/common/examples/customCrypto.ts | 6 +- packages/common/examples/fromGeth.ts | 2 +- packages/common/examples/initKzg.ts | 4 +- packages/common/src/common.ts | 16 +- packages/common/src/constructors.ts | 16 +- packages/common/src/interfaces.ts | 10 +- packages/common/src/types.ts | 2 +- packages/common/src/utils.ts | 19 +- packages/common/test/chains.spec.ts | 22 +-- packages/common/test/customChains.spec.ts | 24 +-- packages/common/test/customCrypto.spec.ts | 6 +- packages/common/test/hardforks.spec.ts | 34 ++-- packages/common/test/mergePOS.spec.ts | 30 +-- packages/common/test/params.spec.ts | 2 +- packages/common/test/timestamp.spec.ts | 22 +-- packages/common/test/utils.spec.ts | 24 +-- packages/common/tsconfig.lint.json | 3 + packages/devp2p/.eslintrc.cjs | 9 + packages/devp2p/examples/dpt.ts | 6 +- .../devp2p/examples/peer-communication-les.ts | 33 ++-- .../devp2p/examples/peer-communication.ts | 43 ++--- packages/devp2p/examples/rlpx.ts | 8 +- packages/devp2p/examples/simple.ts | 5 +- packages/devp2p/src/dns/dns.ts | 2 +- packages/devp2p/src/dns/enr.ts | 10 +- packages/devp2p/src/dpt/ban-list.ts | 2 +- packages/devp2p/src/dpt/dpt.ts | 11 +- packages/devp2p/src/dpt/message.ts | 2 +- packages/devp2p/src/dpt/server.ts | 12 +- packages/devp2p/src/protocol/eth.ts | 20 +- packages/devp2p/src/protocol/les.ts | 22 +-- packages/devp2p/src/protocol/protocol.ts | 4 +- packages/devp2p/src/protocol/snap.ts | 6 +- packages/devp2p/src/rlpx/ecies.ts | 20 +- packages/devp2p/src/rlpx/peer.ts | 22 +-- packages/devp2p/src/rlpx/rlpx.ts | 10 +- packages/devp2p/src/util.ts | 2 +- packages/devp2p/test/dns.spec.ts | 2 +- packages/devp2p/test/dpt-message.spec.ts | 10 +- packages/devp2p/test/dpt.spec.ts | 12 +- packages/devp2p/test/enr.spec.ts | 14 +- .../test/integration/dpt-simulator.spec.ts | 4 +- .../test/integration/eth-simulator.spec.ts | 6 +- .../test/integration/les-simulator.spec.ts | 2 +- .../test/integration/rlpx-simulator.spec.ts | 8 +- packages/devp2p/test/integration/util.ts | 12 +- packages/devp2p/test/rlpx-ecies.spec.ts | 10 +- packages/devp2p/test/rlpx.spec.ts | 4 +- packages/devp2p/tsconfig.lint.json | 3 + packages/ethash/.eslintrc.cjs | 16 +- packages/ethash/examples/example.ts | 1 + packages/ethash/examples/miner.ts | 6 +- packages/ethash/examples/powBlock.ts | 6 +- packages/ethash/examples/rawExample.ts | 9 +- packages/ethash/src/index.ts | 4 +- packages/ethash/src/util.ts | 2 +- packages/ethash/test/miner.spec.ts | 14 +- packages/ethash/tsconfig.lint.json | 3 + packages/evm/.eslintrc.cjs | 3 +- packages/evm/examples/4844.ts | 2 +- packages/evm/examples/decode-opcodes.ts | 3 +- packages/evm/examples/eips.ts | 4 +- packages/evm/examples/runCode.ts | 6 +- packages/evm/examples/simple.ts | 4 +- packages/evm/examples/withBlockchain.ts | 8 +- packages/evm/src/eof/container.ts | 10 +- packages/evm/src/eof/verify.ts | 4 +- packages/evm/src/evm.ts | 36 ++-- packages/evm/src/interpreter.ts | 26 +-- packages/evm/src/journal.ts | 4 +- packages/evm/src/logger.ts | 2 +- packages/evm/src/opcodes/EIP1283.ts | 12 +- packages/evm/src/opcodes/EIP2200.ts | 12 +- packages/evm/src/opcodes/EIP2929.ts | 6 +- packages/evm/src/opcodes/codes.ts | 4 +- packages/evm/src/opcodes/functions.ts | 42 ++--- packages/evm/src/opcodes/gas.ts | 58 +++--- packages/evm/src/opcodes/util.ts | 4 +- packages/evm/src/precompiles/01-ecrecover.ts | 6 +- packages/evm/src/precompiles/02-sha256.ts | 2 +- packages/evm/src/precompiles/03-ripemd160.ts | 2 +- packages/evm/src/precompiles/04-identity.ts | 2 +- packages/evm/src/precompiles/05-modexp.ts | 2 +- packages/evm/src/precompiles/06-ecadd.ts | 2 +- packages/evm/src/precompiles/07-ecmul.ts | 2 +- packages/evm/src/precompiles/08-ecpairing.ts | 4 +- packages/evm/src/precompiles/09-blake2f.ts | 6 +- .../precompiles/0a-kzg-point-evaluation.ts | 12 +- .../src/precompiles/bls12_381/constants.ts | 2 +- packages/evm/src/precompiles/bls12_381/mcl.ts | 16 +- .../evm/src/precompiles/bls12_381/noble.ts | 14 +- .../evm/src/precompiles/bls12_381/util.ts | 10 +- packages/evm/src/precompiles/index.ts | 4 +- packages/evm/test/blobVersionedHashes.spec.ts | 6 +- packages/evm/test/customCrypto.spec.ts | 4 +- packages/evm/test/customOpcodes.spec.ts | 6 +- packages/evm/test/customPrecompiles.spec.ts | 6 +- packages/evm/test/eips/eip-3860.spec.ts | 26 +-- .../evm/test/eips/eof-header-validation.ts | 4 +- packages/evm/test/memory.spec.ts | 4 +- packages/evm/test/opcodes.spec.ts | 14 +- .../evm/test/precompiles/01-ecrecover.spec.ts | 2 +- .../evm/test/precompiles/03-ripemd160.spec.ts | 2 +- .../evm/test/precompiles/08-ecpairing.spec.ts | 4 +- .../evm/test/precompiles/09-blake2f.spec.ts | 2 +- .../precompiles/0a-pointevaluation.spec.ts | 12 +- .../evm/test/precompiles/eip-2537-bls.spec.ts | 2 +- packages/evm/test/runCall.spec.ts | 30 +-- packages/evm/test/runCode.spec.ts | 4 +- packages/evm/test/transientStorage.spec.ts | 4 +- packages/evm/tsconfig.lint.json | 3 + packages/genesis/.eslintrc.cjs | 16 +- packages/genesis/examples/simple.ts | 6 +- packages/genesis/test/index.spec.ts | 6 +- packages/genesis/tsconfig.lint.json | 3 + packages/rlp/.eslintrc.cjs | 11 +- packages/rlp/examples/simple.ts | 2 +- packages/rlp/src/index.ts | 1 - packages/rlp/test/cli.spec.ts | 4 +- packages/rlp/test/dataTypes.spec.ts | 15 +- packages/rlp/test/integration.spec.ts | 6 +- packages/rlp/test/invalid.spec.ts | 8 +- packages/rlp/test/official.spec.ts | 4 +- packages/rlp/test/utils.ts | 1 - packages/rlp/tsconfig.lint.json | 3 + packages/statemanager/.eslintrc.cjs | 9 + packages/statemanager/examples/basicUsage.ts | 7 +- packages/statemanager/examples/evm.ts | 6 +- .../examples/fromProofInstantiation.ts | 13 +- .../statemanager/examples/rpcStateManager.ts | 4 +- packages/statemanager/examples/simple.ts | 5 +- packages/statemanager/src/accessWitness.ts | 22 +-- packages/statemanager/src/cache/account.ts | 2 +- packages/statemanager/src/cache/cache.ts | 2 +- packages/statemanager/src/cache/storage.ts | 2 +- packages/statemanager/src/rpcStateManager.ts | 8 +- packages/statemanager/src/stateManager.ts | 32 ++-- .../src/statelessVerkleStateManager.ts | 26 +-- .../statemanager/test/cache/account.spec.ts | 2 +- .../test/checkpointing.account.spec.ts | 2 +- .../test/checkpointing.code.spec.ts | 2 +- .../test/checkpointing.storage.spec.ts | 4 +- .../test/proofStateManager.spec.ts | 2 +- .../statemanager/test/rpcStateManager.spec.ts | 56 +++--- .../test/stateManager.account.spec.ts | 8 +- .../test/stateManager.code.spec.ts | 2 +- .../statemanager/test/stateManager.spec.ts | 30 +-- .../test/statelessVerkleStateManager.spec.ts | 28 +-- .../testdata/providerData/mockProvider.ts | 2 +- packages/statemanager/test/vmState.spec.ts | 6 +- packages/statemanager/tsconfig.lint.json | 3 + packages/trie/.eslintrc.cjs | 4 +- packages/trie/examples/basicUsage.ts | 6 +- packages/trie/examples/createFromProof.ts | 5 +- packages/trie/examples/customLevelDB.ts | 11 +- packages/trie/examples/level-legacy.js | 13 +- packages/trie/examples/level.js | 11 +- packages/trie/examples/lmdb.js | 11 +- packages/trie/examples/logDemo.ts | 4 +- .../merkle_patricia_trees/example1a.js | 5 +- .../merkle_patricia_trees/example1b.js | 5 +- .../merkle_patricia_trees/example1c.js | 6 +- .../merkle_patricia_trees/example1d.js | 5 +- .../merkle_patricia_trees/example2a.js | 5 +- .../merkle_patricia_trees/example2b.js | 9 +- .../merkle_patricia_trees/example2c.js | 5 +- .../merkle_patricia_trees/example2d.js | 5 +- .../merkle_patricia_trees/example3a.js | 8 +- .../merkle_patricia_trees/example3b.js | 6 +- .../merkle_patricia_trees/example4a.js | 3 +- .../merkle_patricia_trees/example4b.js | 3 +- packages/trie/examples/proofs.ts | 4 +- packages/trie/examples/rootPersistence.ts | 4 +- packages/trie/examples/trieWalking.ts | 4 +- packages/trie/src/constructors.ts | 2 +- packages/trie/src/proof/index.ts | 6 +- packages/trie/src/proof/range.ts | 14 +- packages/trie/src/trie.ts | 54 +++--- packages/trie/src/types.ts | 2 +- packages/trie/src/util/asyncWalk.ts | 2 +- packages/trie/src/util/encoding.ts | 2 +- packages/trie/src/util/genesisState.ts | 2 +- packages/trie/src/util/walkController.ts | 4 +- packages/trie/test/encoding.spec.ts | 2 +- packages/trie/test/index.spec.ts | 42 ++--- packages/trie/test/proof.spec.ts | 6 +- packages/trie/test/proof/range.spec.ts | 20 +- packages/trie/test/trie/checkpoint.spec.ts | 6 +- packages/trie/test/trie/secure.spec.ts | 14 +- packages/trie/test/trie/trie.spec.ts | 22 +-- packages/trie/test/util/encodingUtils.spec.ts | 12 +- packages/trie/test/util/genesisState.spec.ts | 4 +- packages/trie/tsconfig.lint.json | 3 + packages/tx/.eslintrc.cjs | 16 +- packages/tx/examples/blobTx.ts | 2 +- packages/tx/examples/custom-chain-id-tx.ts | 4 +- packages/tx/examples/custom-chain-tx.ts | 7 +- packages/tx/examples/initKzg.ts | 4 +- packages/tx/examples/l2tx.ts | 2 +- packages/tx/examples/legacyTx.ts | 10 +- packages/tx/examples/londonTx.ts | 2 +- packages/tx/examples/transactions.ts | 2 +- packages/tx/examples/txFactory.ts | 6 +- packages/tx/src/1559/constructors.ts | 8 +- packages/tx/src/1559/tx.ts | 6 +- packages/tx/src/2930/constructors.ts | 6 +- packages/tx/src/2930/tx.ts | 4 +- packages/tx/src/4844/constructors.ts | 32 ++-- packages/tx/src/4844/tx.ts | 12 +- packages/tx/src/7702/constructors.ts | 6 +- packages/tx/src/7702/tx.ts | 8 +- packages/tx/src/baseTransaction.ts | 16 +- packages/tx/src/capabilities/eip1559.ts | 2 +- packages/tx/src/capabilities/eip7702.ts | 2 +- packages/tx/src/capabilities/legacy.ts | 4 +- packages/tx/src/legacy/constructors.ts | 4 +- packages/tx/src/legacy/tx.ts | 8 +- packages/tx/src/transactionFactory.ts | 10 +- packages/tx/src/types.ts | 14 +- packages/tx/src/util.ts | 8 +- packages/tx/test/base.spec.ts | 52 ++--- packages/tx/test/eip1559.spec.ts | 34 ++-- packages/tx/test/eip3860.spec.ts | 6 +- packages/tx/test/eip4844.spec.ts | 82 ++++---- packages/tx/test/eip7702.spec.ts | 20 +- packages/tx/test/fromRpc.spec.ts | 2 +- packages/tx/test/inputValue.spec.ts | 18 +- packages/tx/test/legacy.spec.ts | 68 +++---- packages/tx/test/testLoader.ts | 4 +- packages/tx/test/transactionFactory.spec.ts | 16 +- packages/tx/test/transactionRunner.spec.ts | 6 +- packages/tx/test/typedTxsAndEIP2930.spec.ts | 96 +++++----- packages/tx/tsconfig.lint.json | 3 + packages/util/.eslintrc.cjs | 16 +- packages/util/src/account.ts | 12 +- packages/util/src/asyncEventEmitter.ts | 4 +- packages/util/src/bytes.ts | 6 +- packages/util/src/constants.ts | 6 +- packages/util/src/db.ts | 6 +- packages/util/src/genesis.ts | 2 +- packages/util/src/internal.ts | 8 +- packages/util/src/kzg.ts | 4 +- packages/util/src/mapDB.ts | 2 +- packages/util/src/provider.ts | 4 +- packages/util/src/requests.ts | 24 ++- packages/util/src/signature.ts | 10 +- packages/util/src/types.ts | 8 +- packages/util/src/units.ts | 2 +- packages/util/src/verkle.ts | 12 +- packages/util/src/withdrawal.ts | 2 +- packages/util/test/account.spec.ts | 168 ++++++++--------- packages/util/test/address.spec.ts | 8 +- packages/util/test/bytes.spec.ts | 18 +- packages/util/test/constants.spec.ts | 18 +- packages/util/test/genesis.spec.ts | 4 +- packages/util/test/internal.spec.ts | 8 +- packages/util/test/provider.spec.ts | 4 +- packages/util/test/requests.spec.ts | 2 +- packages/util/test/signature.spec.ts | 28 +-- packages/util/test/verkle.spec.ts | 10 +- packages/util/test/withdrawal.spec.ts | 6 +- packages/util/tsconfig.lint.json | 3 + packages/verkle/.eslintrc.cjs | 4 +- packages/verkle/src/node/internalNode.ts | 2 +- packages/verkle/src/node/leafNode.ts | 16 +- packages/verkle/src/verkleTree.ts | 42 ++--- packages/verkle/test/internalNode.spec.ts | 6 +- packages/verkle/test/leafNode.spec.ts | 4 +- packages/verkle/test/verkle.spec.ts | 4 +- packages/verkle/tsconfig.lint.json | 3 + packages/vm/.eslintrc.cjs | 6 +- packages/vm/examples/buildBlock.ts | 6 +- packages/vm/examples/helpers/account-utils.ts | 5 +- packages/vm/examples/helpers/tx-builder.ts | 9 +- packages/vm/examples/run-blockchain.ts | 30 ++- packages/vm/examples/run-solidity-contract.ts | 13 +- packages/vm/examples/runGoerliBlock.ts | 10 +- packages/vm/examples/runTx.ts | 4 +- packages/vm/examples/vmWith4844.ts | 5 +- packages/vm/examples/vmWithEIPs.ts | 2 +- packages/vm/examples/vmWithGenesisState.ts | 8 +- packages/vm/src/buildBlock.ts | 2 +- packages/vm/src/emitEVMProfile.ts | 2 +- packages/vm/src/requests.ts | 24 +-- packages/vm/src/runBlock.ts | 46 ++--- packages/vm/src/runTx.ts | 38 ++-- packages/vm/src/vm.ts | 4 +- packages/vm/test/api/EIPs/eip-1153.spec.ts | 6 +- .../test/api/EIPs/eip-1559-FeeMarket.spec.ts | 10 +- .../api/EIPs/eip-2565-modexp-gas-cost.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 10 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 6 +- .../eip-2935-historical-block-hashes.spec.ts | 6 +- .../test/api/EIPs/eip-3074-authcall.spec.ts | 60 +++--- .../vm/test/api/EIPs/eip-3198-BaseFee.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-3529.spec.ts | 2 +- .../api/EIPs/eip-3651-warm-coinbase.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-3860.spec.ts | 6 +- ...t-difficulty-opcode-with-prevrando.spec.ts | 4 +- .../test/api/EIPs/eip-4788-beaconroot.spec.ts | 11 +- .../vm/test/api/EIPs/eip-4844-blobs.spec.ts | 6 +- .../api/EIPs/eip-4895-withdrawals.spec.ts | 26 +-- packages/vm/test/api/EIPs/eip-6110.spec.ts | 4 +- .../eip-6780-selfdestruct-same-tx.spec.ts | 4 +- .../vm/test/api/EIPs/eip-6800-verkle.spec.ts | 9 +- packages/vm/test/api/EIPs/eip-7002.spec.ts | 12 +- packages/vm/test/api/EIPs/eip-7685.spec.ts | 12 +- packages/vm/test/api/EIPs/eip-7702.spec.ts | 22 +-- packages/vm/test/api/bloom.spec.ts | 6 +- packages/vm/test/api/buildBlock.spec.ts | 42 ++--- packages/vm/test/api/copy.spec.ts | 8 +- packages/vm/test/api/customChain.spec.ts | 6 +- packages/vm/test/api/events.spec.ts | 2 +- packages/vm/test/api/index.spec.ts | 26 +-- .../vm/test/api/istanbul/eip-1108.spec.ts | 4 +- .../vm/test/api/istanbul/eip-2200.spec.ts | 2 +- packages/vm/test/api/level.ts | 2 +- packages/vm/test/api/runBlock.spec.ts | 60 +++--- packages/vm/test/api/runTx.spec.ts | 90 ++++----- .../vm/test/api/state/accountExists.spec.ts | 14 +- .../vm/test/api/tester/tester.config.spec.ts | 2 +- packages/vm/test/api/utils.ts | 16 +- packages/vm/test/tester/config.ts | 8 +- packages/vm/test/tester/index.ts | 16 +- .../tester/runners/BlockchainTestsRunner.ts | 4 +- .../tester/runners/GeneralStateTestsRunner.ts | 4 +- packages/vm/test/tester/testLoader.ts | 6 +- packages/vm/test/util.ts | 14 +- packages/vm/tsconfig.lint.json | 3 + packages/wallet/.eslintrc.cjs | 5 +- .../wallet/examples/{hdKey.js => hdKey.cjs} | 0 packages/wallet/examples/hdKey.ts | 2 +- .../{thirdparty.js => thirdparty.cjs} | 0 .../wallet/examples/{wallet.js => wallet.cjs} | 0 packages/wallet/src/thirdparty.ts | 2 +- packages/wallet/src/wallet.ts | 20 +- packages/wallet/test/hdkey.spec.ts | 32 ++-- packages/wallet/test/index.spec.ts | 94 ++++----- packages/wallet/tsconfig.lint.json | 3 + 548 files changed, 3995 insertions(+), 3790 deletions(-) create mode 100644 config/tsconfig.lint.json create mode 100644 packages/block/tsconfig.lint.json create mode 100644 packages/blockchain/tsconfig.lint.json delete mode 100644 packages/client/tsconfig.eslint.json create mode 100644 packages/client/tsconfig.lint.json create mode 100644 packages/common/tsconfig.lint.json create mode 100644 packages/devp2p/tsconfig.lint.json create mode 100644 packages/ethash/tsconfig.lint.json create mode 100644 packages/evm/tsconfig.lint.json create mode 100644 packages/genesis/tsconfig.lint.json create mode 100644 packages/rlp/tsconfig.lint.json create mode 100644 packages/statemanager/tsconfig.lint.json create mode 100644 packages/trie/tsconfig.lint.json create mode 100644 packages/tx/tsconfig.lint.json create mode 100644 packages/util/tsconfig.lint.json create mode 100644 packages/verkle/tsconfig.lint.json create mode 100644 packages/vm/tsconfig.lint.json rename packages/wallet/examples/{hdKey.js => hdKey.cjs} (100%) rename packages/wallet/examples/{thirdparty.js => thirdparty.cjs} (100%) rename packages/wallet/examples/{wallet.js => wallet.cjs} (100%) create mode 100644 packages/wallet/tsconfig.lint.json diff --git a/config/eslint.cjs b/config/eslint.cjs index ce8c6e484b..d2f97618a8 100644 --- a/config/eslint.cjs +++ b/config/eslint.cjs @@ -19,7 +19,6 @@ module.exports = { 'benchmarks', 'coverage', 'dist', - 'examples', 'node_modules', 'prettier.config.js', 'recipes', @@ -116,11 +115,11 @@ module.exports = { parserOptions: { extraFileExtensions: ['.json'], sourceType: 'module', - project: './tsconfig.json', + project: './tsconfig.lint.json', }, overrides: [ { - files: ['test/**/*.ts', 'tests/**/*.ts'], + files: ['test/**/*.ts', 'tests/**/*.ts', 'examples/**/*.ts'], rules: { 'implicit-dependencies/no-implicit': 'off', 'import/no-extraneous-dependencies': 'off', diff --git a/config/tsconfig.lint.json b/config/tsconfig.lint.json new file mode 100644 index 0000000000..574cc64e1f --- /dev/null +++ b/config/tsconfig.lint.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "../packages/**/src/**/*.ts", + "../packages/**/test/**/*.ts", + "../packages/**/examples/**/*.ts", + "../packages/**/examples/**/*.cjs", + "../packages/**/examples/**/*.js", + "../packages/**/benchmarks/**/*.ts", + "../packages/**/bin/**/*.ts" + ], + "compilerOptions": { + "noEmit": true + } +} diff --git a/package-lock.json b/package-lock.json index 191f1c226a..efe96a9f05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,20 +19,20 @@ "@vitest/ui": "^v2.0.0-beta.12", "c8": "7.12.0", "embedme": "1.22.1", - "eslint": "8.45.0", - "eslint-config-prettier": "8.8.0", - "eslint-config-typestrict": "1.0.5", + "eslint": "8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-config-typestrict": "^1.0.5", "eslint-formatter-codeframe": "7.32.1", "eslint-plugin-ethereumjs": "file:./eslint", "eslint-plugin-github": "4.9.2", "eslint-plugin-implicit-dependencies": "1.1.1", "eslint-plugin-import": "2.26.0", - "eslint-plugin-prettier": "4.2.1", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "7.0.0", "eslint-plugin-sonarjs": "0.19.0", "lint-staged": "13.0.3", "lockfile-lint-api": "^5.5.1", - "prettier": "2.7.1", + "prettier": "^3.3.3", "sort-package-json": "1.57.0", "tape": "5.6.0", "tsx": "^4.6.2", @@ -1011,9 +1011,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3719,6 +3719,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vitest/browser": { "version": "2.0.0-beta.12", "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-2.0.0-beta.12.tgz", @@ -7069,27 +7075,28 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7123,9 +7130,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -7492,36 +7499,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/eslint-plugin-github/node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-plugin-github/node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -7537,21 +7514,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-plugin-github/node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/eslint-plugin-i18n-text": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz", @@ -7674,21 +7636,30 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } @@ -12812,15 +12783,15 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -14719,9 +14690,9 @@ } }, "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { "@pkgr/core": "^0.1.0", diff --git a/package.json b/package.json index 356faf9b30..59d32a1b05 100644 --- a/package.json +++ b/package.json @@ -34,20 +34,20 @@ "@vitest/ui": "^v2.0.0-beta.12", "c8": "7.12.0", "embedme": "1.22.1", - "eslint": "8.45.0", - "eslint-config-prettier": "8.8.0", - "eslint-config-typestrict": "1.0.5", + "eslint": "8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-config-typestrict": "^1.0.5", "eslint-formatter-codeframe": "7.32.1", "eslint-plugin-ethereumjs": "file:./eslint", "eslint-plugin-github": "4.9.2", "eslint-plugin-implicit-dependencies": "1.1.1", "eslint-plugin-import": "2.26.0", - "eslint-plugin-prettier": "4.2.1", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "7.0.0", "eslint-plugin-sonarjs": "0.19.0", "lint-staged": "13.0.3", "lockfile-lint-api": "^5.5.1", - "prettier": "2.7.1", + "prettier": "^3.3.3", "sort-package-json": "1.57.0", "tape": "5.6.0", "tsx": "^4.6.2", diff --git a/packages/block/.eslintrc.cjs b/packages/block/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/block/.eslintrc.cjs +++ b/packages/block/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/block/examples/1559.ts b/packages/block/examples/1559.ts index a77afbc323..ed836dec4f 100644 --- a/packages/block/examples/1559.ts +++ b/packages/block/examples/1559.ts @@ -1,4 +1,4 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) @@ -10,7 +10,7 @@ const block = createBlockFromBlockData( gasUsed: BigInt(60), }, }, - { common } + { common }, ) // Base fee will increase for next block since the @@ -27,7 +27,7 @@ const blockWithMatchingBaseFee = createBlockFromBlockData( gasUsed: BigInt(60), }, }, - { common } + { common }, ) console.log(Number(blockWithMatchingBaseFee.header.baseFeePerGas)) // 11 diff --git a/packages/block/examples/4844.ts b/packages/block/examples/4844.ts index a73cb682ba..5331a68e20 100644 --- a/packages/block/examples/4844.ts +++ b/packages/block/examples/4844.ts @@ -17,7 +17,7 @@ const main = async () => { }) const blobTx = create4844BlobTx( { blobsData: ['myFirstBlob'], to: Address.fromPrivateKey(randomBytes(32)) }, - { common } + { common }, ) const block = createBlockFromBlockData( @@ -30,14 +30,14 @@ const main = async () => { { common, skipConsensusFormatValidation: true, - } + }, ) console.log( `4844 block header with excessBlobGas=${block.header.excessBlobGas} created and ${ block.transactions.filter((tx) => tx.type === 3).length - } blob transactions` + } blob transactions`, ) } -main() +void main() diff --git a/packages/block/examples/clique.ts b/packages/block/examples/clique.ts index ba32b58cc1..2caa565d64 100644 --- a/packages/block/examples/clique.ts +++ b/packages/block/examples/clique.ts @@ -1,4 +1,4 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Chainstart }) diff --git a/packages/block/examples/pos.ts b/packages/block/examples/pos.ts index 1096669d55..c05220b05c 100644 --- a/packages/block/examples/pos.ts +++ b/packages/block/examples/pos.ts @@ -1,4 +1,4 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' const common = new Common({ chain: Chain.Mainnet }) @@ -7,7 +7,7 @@ const block = createBlockFromBlockData( { // Provide your block data here or use default values }, - { common } + { common }, ) console.log(`Proof-of-Stake (default) block created with hardfork=${block.common.hardfork()}`) diff --git a/packages/block/examples/pow.ts b/packages/block/examples/pow.ts index 997e47c26c..8f2c1f4075 100644 --- a/packages/block/examples/pow.ts +++ b/packages/block/examples/pow.ts @@ -1,4 +1,4 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) diff --git a/packages/block/examples/withdrawals.ts b/packages/block/examples/withdrawals.ts index 73e5e7dfc1..5229db9dfa 100644 --- a/packages/block/examples/withdrawals.ts +++ b/packages/block/examples/withdrawals.ts @@ -1,6 +1,7 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' -import { Common, Chain } from '@ethereumjs/common' +import { createBlockFromBlockData } from '@ethereumjs/block' +import { Chain, Common } from '@ethereumjs/common' import { Address, hexToBytes } from '@ethereumjs/util' + import type { WithdrawalData } from '@ethereumjs/util' const common = new Common({ chain: Chain.Mainnet }) @@ -16,14 +17,14 @@ const block = createBlockFromBlockData( { header: { withdrawalsRoot: hexToBytes( - '0x69f28913c562b0d38f8dc81e72eb0d99052444d301bf8158dc1f3f94a4526357' + '0x69f28913c562b0d38f8dc81e72eb0d99052444d301bf8158dc1f3f94a4526357', ), }, withdrawals: [withdrawal], }, { common, - } + }, ) console.log(`Block with ${block.withdrawals!.length} withdrawal(s) created`) diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 725e14879a..82b8597d94 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -98,7 +98,7 @@ export class Block { withdrawals?: Withdrawal[], opts: BlockOptions = {}, requests?: CLRequest[], - executionWitness?: VerkleExecutionWitness | null + executionWitness?: VerkleExecutionWitness | null, ) { this.header = header ?? BlockHeader.fromHeaderData({}, opts) this.common = this.header.common @@ -132,13 +132,13 @@ export class Block { this.validateUncles() if (this.common.consensusType() === ConsensusType.ProofOfAuthority) { const msg = this._errorMsg( - 'Block initialization with uncleHeaders on a PoA network is not allowed' + 'Block initialization with uncleHeaders on a PoA network is not allowed', ) throw new Error(msg) } if (this.common.consensusType() === ConsensusType.ProofOfStake) { const msg = this._errorMsg( - 'Block initialization with uncleHeaders on a PoS network is not allowed' + 'Block initialization with uncleHeaders on a PoS network is not allowed', ) throw new Error(msg) } @@ -181,7 +181,7 @@ export class Block { const bytesArray = [ this.header.raw(), this.transactions.map((tx) => - tx.supports(Capability.EIP2718TypedTransaction) ? tx.serialize() : tx.raw() + tx.supports(Capability.EIP2718TypedTransaction) ? tx.serialize() : tx.raw(), ) as Uint8Array[], this.uncleHeaders.map((uh) => uh.raw()), ] @@ -301,7 +301,7 @@ export class Block { blobGasUsed += BigInt(tx.numBlobs()) * blobGasPerBlob if (blobGasUsed > blobGasLimit) { errs.push( - `tx causes total blob gas of ${blobGasUsed} to exceed maximum blob gas per block of ${blobGasLimit}` + `tx causes total blob gas of ${blobGasUsed} to exceed maximum blob gas per block of ${blobGasLimit}`, ) } } @@ -357,7 +357,7 @@ export class Block { for (const [index, tx] of this.transactions.entries()) { if (!tx.isSigned()) { const msg = this._errorMsg( - `invalid transactions: transaction at index ${index} is unsigned` + `invalid transactions: transaction at index ${index} is unsigned`, ) throw new Error(msg) } @@ -406,7 +406,7 @@ export class Block { const expectedExcessBlobGas = parentHeader.calcNextExcessBlobGas() if (this.header.excessBlobGas !== expectedExcessBlobGas) { throw new Error( - `block excessBlobGas mismatch: have ${this.header.excessBlobGas}, want ${expectedExcessBlobGas}` + `block excessBlobGas mismatch: have ${this.header.excessBlobGas}, want ${expectedExcessBlobGas}`, ) } @@ -419,7 +419,7 @@ export class Block { throw new Error( `blob transaction maxFeePerBlobGas ${ tx.maxFeePerBlobGas - } < than block blob gas price ${blobGasPrice} - ${this.errorStr()}` + } < than block blob gas price ${blobGasPrice} - ${this.errorStr()}`, ) } @@ -427,7 +427,7 @@ export class Block { if (blobGasUsed > blobGasLimit) { throw new Error( - `tx causes total blob gas of ${blobGasUsed} to exceed maximum blob gas per block of ${blobGasLimit}` + `tx causes total blob gas of ${blobGasUsed} to exceed maximum blob gas per block of ${blobGasLimit}`, ) } } @@ -435,7 +435,7 @@ export class Block { if (this.header.blobGasUsed !== blobGasUsed) { throw new Error( - `block blobGasUsed mismatch: have ${this.header.blobGasUsed}, want ${blobGasUsed}` + `block blobGasUsed mismatch: have ${this.header.blobGasUsed}, want ${blobGasUsed}`, ) } } @@ -472,7 +472,7 @@ export class Block { if (this.cache.withdrawalsTrieRoot === undefined) { this.cache.withdrawalsTrieRoot = await genWithdrawalsTrieRoot( this.withdrawals!, - new Trie({ common: this.common }) + new Trie({ common: this.common }), ) } result = equalsBytes(this.cache.withdrawalsTrieRoot, this.header.withdrawalsRoot!) diff --git a/packages/block/src/constructors.ts b/packages/block/src/constructors.ts index bf409c6ec5..dee8d97578 100644 --- a/packages/block/src/constructors.ts +++ b/packages/block/src/constructors.ts @@ -108,7 +108,7 @@ export function createBlockFromBlockData(blockData: BlockData = {}, opts?: Block withdrawals, opts, clRequests, - executionWitness + executionWitness, ) } @@ -146,7 +146,7 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio (withdrawalBytes === undefined || !Array.isArray(withdrawalBytes)) ) { throw new Error( - 'Invalid serialized block input: EIP-4895 is active, and no withdrawals were provided as array' + 'Invalid serialized block input: EIP-4895 is active, and no withdrawals were provided as array', ) } @@ -155,13 +155,13 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio (requestBytes === undefined || !Array.isArray(requestBytes)) ) { throw new Error( - 'Invalid serialized block input: EIP-7685 is active, and no requestBytes were provided as array' + 'Invalid serialized block input: EIP-7685 is active, and no requestBytes were provided as array', ) } if (header.common.isActivatedEIP(6800) && executionWitnessBytes === undefined) { throw new Error( - 'Invalid serialized block input: EIP-6800 is active, and execution witness is undefined' + 'Invalid serialized block input: EIP-6800 is active, and execution witness is undefined', ) } @@ -173,7 +173,7 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio ...opts, // Use header common in case of setHardfork being activated common: header.common, - }) + }), ) } @@ -206,7 +206,7 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio let requests if (header.common.isActivatedEIP(7685)) { requests = (requestBytes as RequestBytes[]).map((bytes) => - CLRequestFactory.fromSerializedRequest(bytes) + CLRequestFactory.fromSerializedRequest(bytes), ) } // executionWitness are not part of the EL fetched blocks via eth_ bodies method @@ -231,7 +231,7 @@ export function createBlockFromValuesArray(values: BlockBytes, opts?: BlockOptio withdrawals, opts, requests, - executionWitness + executionWitness, ) } @@ -272,7 +272,7 @@ export function createBlockFromRPC(blockData: JsonRpcBlock, uncles?: any[], opts export const createBlockFromJsonRpcProvider = async ( provider: string | EthersProvider, blockTag: string | bigint, - opts: BlockOptions + opts: BlockOptions, ) => { let blockData const providerUrl = getProvider(provider) @@ -301,7 +301,7 @@ export const createBlockFromJsonRpcProvider = async ( }) } else { throw new Error( - `expected blockTag to be block hash, bigint, hex prefixed string, or earliest/latest/pending; got ${blockTag}` + `expected blockTag to be block hash, bigint, hex prefixed string, or earliest/latest/pending; got ${blockTag}`, ) } @@ -331,7 +331,7 @@ export const createBlockFromJsonRpcProvider = async ( */ export async function createBlockFromExecutionPayload( payload: ExecutionPayload, - opts?: BlockOptions + opts?: BlockOptions, ): Promise { const { blockNumber: number, @@ -409,7 +409,7 @@ export async function createBlockFromExecutionPayload( // we are not setting setHardfork as common is already set to the correct hf const block = createBlockFromBlockData( { header, transactions: txs, withdrawals, executionWitness, requests }, - opts + opts, ) if ( block.common.isActivatedEIP(6800) && @@ -436,7 +436,7 @@ export async function createBlockFromExecutionPayload( */ export async function createBlockFromBeaconPayloadJson( payload: BeaconPayloadJson, - opts?: BlockOptions + opts?: BlockOptions, ): Promise { const executionPayload = executionPayloadFromBeaconPayload(payload) return createBlockFromExecutionPayload(executionPayload, opts) diff --git a/packages/block/src/from-beacon-payload.ts b/packages/block/src/from-beacon-payload.ts index b72679d8a5..ec9c4d275f 100644 --- a/packages/block/src/from-beacon-payload.ts +++ b/packages/block/src/from-beacon-payload.ts @@ -185,7 +185,7 @@ export function executionPayloadFromBeaconPayload(payload: BeaconPayloadJson): E payload.execution_witness.verkleProof !== undefined ? payload.execution_witness : parseExecutionWitnessFromSnakeJson( - payload.execution_witness as unknown as VerkleExecutionWitnessSnakeJson + payload.execution_witness as unknown as VerkleExecutionWitnessSnakeJson, ) } diff --git a/packages/block/src/from-rpc.ts b/packages/block/src/from-rpc.ts index c0105afac9..513e7b402c 100644 --- a/packages/block/src/from-rpc.ts +++ b/packages/block/src/from-rpc.ts @@ -46,7 +46,7 @@ function normalizeTxParams(_txParams: any) { export function createBlockFromRpc( blockParams: JsonRpcBlock, uncles: any[] = [], - options?: BlockOptions + options?: BlockOptions, ) { const header = blockHeaderFromRpc(blockParams, options) @@ -66,6 +66,6 @@ export function createBlockFromRpc( }) return createBlockFromBlockData( { header, transactions, uncleHeaders, withdrawals: blockParams.withdrawals, requests }, - options + options, ) } diff --git a/packages/block/src/header-from-rpc.ts b/packages/block/src/header-from-rpc.ts index a4ba8f3d45..a22678b574 100644 --- a/packages/block/src/header-from-rpc.ts +++ b/packages/block/src/header-from-rpc.ts @@ -58,7 +58,7 @@ export function blockHeaderFromRpc(blockParams: JsonRpcBlock, options?: BlockOpt parentBeaconBlockRoot, requestsRoot, }, - options + options, ) return blockHeader diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index c07740a173..9a8939c001 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -79,7 +79,7 @@ export class BlockHeader { get prevRandao() { if (!this.common.isActivatedEIP(4399)) { const msg = this._errorMsg( - 'The prevRandao parameter can only be accessed when EIP-4399 is activated' + 'The prevRandao parameter can only be accessed when EIP-4399 is activated', ) throw new Error(msg) } @@ -192,7 +192,7 @@ export class BlockHeader { const parentHash = toType(headerData.parentHash, TypeOutput.Uint8Array) ?? defaults.parentHash const uncleHash = toType(headerData.uncleHash, TypeOutput.Uint8Array) ?? defaults.uncleHash const coinbase = new Address( - toType(headerData.coinbase ?? defaults.coinbase, TypeOutput.Uint8Array) + toType(headerData.coinbase ?? defaults.coinbase, TypeOutput.Uint8Array), ) const stateRoot = toType(headerData.stateRoot, TypeOutput.Uint8Array) ?? defaults.stateRoot const transactionsTrie = @@ -257,7 +257,7 @@ export class BlockHeader { if (!this.common.isActivatedEIP(4895) && withdrawalsRoot !== undefined) { throw new Error( - 'A withdrawalsRoot for a header can only be provided with EIP4895 being activated' + 'A withdrawalsRoot for a header can only be provided with EIP4895 being activated', ) } @@ -273,7 +273,7 @@ export class BlockHeader { if (!this.common.isActivatedEIP(4788) && parentBeaconBlockRoot !== undefined) { throw new Error( - 'A parentBeaconBlockRoot for a header can only be provided with EIP4788 being activated' + 'A parentBeaconBlockRoot for a header can only be provided with EIP4788 being activated', ) } @@ -352,13 +352,13 @@ export class BlockHeader { } if (transactionsTrie.length !== 32) { const msg = this._errorMsg( - `transactionsTrie must be 32 bytes, received ${transactionsTrie.length} bytes` + `transactionsTrie must be 32 bytes, received ${transactionsTrie.length} bytes`, ) throw new Error(msg) } if (receiptTrie.length !== 32) { const msg = this._errorMsg( - `receiptTrie must be 32 bytes, received ${receiptTrie.length} bytes` + `receiptTrie must be 32 bytes, received ${receiptTrie.length} bytes`, ) throw new Error(msg) } @@ -375,7 +375,7 @@ export class BlockHeader { // check if the block used too much gas if (this.gasUsed > this.gasLimit) { const msg = this._errorMsg( - `Invalid block: too much gas used. Used: ${this.gasUsed}, gas limit: ${this.gasLimit}` + `Invalid block: too much gas used. Used: ${this.gasUsed}, gas limit: ${this.gasLimit}`, ) throw new Error(msg) } @@ -407,7 +407,7 @@ export class BlockHeader { } if (this.withdrawalsRoot?.length !== 32) { const msg = this._errorMsg( - `withdrawalsRoot must be 32 bytes, received ${this.withdrawalsRoot!.length} bytes` + `withdrawalsRoot must be 32 bytes, received ${this.withdrawalsRoot!.length} bytes`, ) throw new Error(msg) } @@ -422,7 +422,7 @@ export class BlockHeader { const msg = this._errorMsg( `parentBeaconBlockRoot must be 32 bytes, received ${ this.parentBeaconBlockRoot!.length - } bytes` + } bytes`, ) throw new Error(msg) } @@ -459,7 +459,7 @@ export class BlockHeader { // ExtraData length on epoch transition if (this.extraData.length !== minLength) { const msg = this._errorMsg( - `extraData must be ${minLength} bytes on non-epoch transition blocks, received ${this.extraData.length} bytes` + `extraData must be ${minLength} bytes on non-epoch transition blocks, received ${this.extraData.length} bytes`, ) throw new Error(msg) } @@ -467,14 +467,14 @@ export class BlockHeader { const signerLength = this.extraData.length - minLength if (signerLength % 20 !== 0) { const msg = this._errorMsg( - `invalid signer list length in extraData, received signer length of ${signerLength} (not divisible by 20)` + `invalid signer list length in extraData, received signer length of ${signerLength} (not divisible by 20)`, ) throw new Error(msg) } // coinbase (beneficiary) on epoch transition if (!this.coinbase.isZero()) { const msg = this._errorMsg( - `coinbase must be filled with zeros on epoch transition blocks, received ${this.coinbase}` + `coinbase must be filled with zeros on epoch transition blocks, received ${this.coinbase}`, ) throw new Error(msg) } @@ -492,7 +492,7 @@ export class BlockHeader { if (!equalsBytes(uncleHash, KECCAK256_RLP_ARRAY)) { errorMsg += `, uncleHash: ${bytesToHex(uncleHash)} (expected: ${bytesToHex( - KECCAK256_RLP_ARRAY + KECCAK256_RLP_ARRAY, )})` error = true } @@ -504,7 +504,7 @@ export class BlockHeader { } if (extraData.length > 32) { errorMsg += `, extraData: ${bytesToHex( - extraData + extraData, )} (cannot exceed 32 bytes length, received ${extraData.length} bytes)` error = true } @@ -547,14 +547,14 @@ export class BlockHeader { if (gasLimit >= maxGasLimit) { const msg = this._errorMsg( - `gas limit increased too much. Gas limit: ${gasLimit}, max gas limit: ${maxGasLimit}` + `gas limit increased too much. Gas limit: ${gasLimit}, max gas limit: ${maxGasLimit}`, ) throw new Error(msg) } if (gasLimit <= minGasLimit) { const msg = this._errorMsg( - `gas limit decreased too much. Gas limit: ${gasLimit}, min gas limit: ${minGasLimit}` + `gas limit decreased too much. Gas limit: ${gasLimit}, min gas limit: ${minGasLimit}`, ) throw new Error(msg) } @@ -562,8 +562,8 @@ export class BlockHeader { if (gasLimit < this.common.param('minGasLimit')) { const msg = this._errorMsg( `gas limit decreased below minimum gas limit. Gas limit: ${gasLimit}, minimum gas limit: ${this.common.param( - 'minGasLimit' - )}` + 'minGasLimit', + )}`, ) throw new Error(msg) } @@ -575,7 +575,7 @@ export class BlockHeader { public calcNextBaseFee(): bigint { if (!this.common.isActivatedEIP(1559)) { const msg = this._errorMsg( - 'calcNextBaseFee() can only be called with EIP1559 being activated' + 'calcNextBaseFee() can only be called with EIP1559 being activated', ) throw new Error(msg) } @@ -625,7 +625,7 @@ export class BlockHeader { return fakeExponential( this.common.param('minBlobGas'), excessBlobGas, - this.common.param('blobGasPriceUpdateFraction') + this.common.param('blobGasPriceUpdateFraction'), ) } @@ -740,7 +740,7 @@ export class BlockHeader { protected _requireClique(name: string) { if (this.common.consensusAlgorithm() !== ConsensusAlgorithm.Clique) { const msg = this._errorMsg( - `BlockHeader.${name}() call only supported for clique PoA networks` + `BlockHeader.${name}() call only supported for clique PoA networks`, ) throw new Error(msg) } @@ -758,7 +758,7 @@ export class BlockHeader { } if (this.common.consensusAlgorithm() !== ConsensusAlgorithm.Ethash) { const msg = this._errorMsg( - 'difficulty calculation currently only supports the ethash algorithm' + 'difficulty calculation currently only supports the ethash algorithm', ) throw new Error(msg) } @@ -873,7 +873,7 @@ export class BlockHeader { const extraDataWithoutSeal = this.extraData.subarray( 0, - this.extraData.length - CLIQUE_EXTRA_SEAL + this.extraData.length - CLIQUE_EXTRA_SEAL, ) const extraData = concatBytes(extraDataWithoutSeal, signatureB) return extraData @@ -1004,8 +1004,8 @@ export class BlockHeader { if (drift <= DAO_ForceExtraDataRange && !equalsBytes(this.extraData, DAO_ExtraData)) { const msg = this._errorMsg( `extraData should be 'dao-hard-fork', got ${bytesToUtf8(this.extraData)} (hex: ${bytesToHex( - this.extraData - )})` + this.extraData, + )})`, ) throw new Error(msg) } diff --git a/packages/block/src/helpers.ts b/packages/block/src/helpers.ts index 145d051bb7..87d80e7883 100644 --- a/packages/block/src/helpers.ts +++ b/packages/block/src/helpers.ts @@ -51,12 +51,12 @@ export function valuesArrayToHeaderData(values: BlockHeaderBytes): HeaderData { if (values.length > 21) { throw new Error( - `invalid header. More values than expected were received. Max: 20, got: ${values.length}` + `invalid header. More values than expected were received. Max: 20, got: ${values.length}`, ) } if (values.length < 15) { throw new Error( - `invalid header. Less values than expected were received. Min: 15, got: ${values.length}` + `invalid header. Less values than expected were received. Min: 15, got: ${values.length}`, ) } diff --git a/packages/block/src/types.ts b/packages/block/src/types.ts index e1fa075796..5935fc6c97 100644 --- a/packages/block/src/types.ts +++ b/packages/block/src/types.ts @@ -139,7 +139,7 @@ export type BlockBytes = UncleHeadersBytes, WithdrawalsBytes, RequestsBytes, - ExecutionWitnessBytes + ExecutionWitnessBytes, ] /** @@ -150,7 +150,7 @@ export type BlockBodyBytes = [ TransactionsBytes, UncleHeadersBytes, WithdrawalsBytes?, - RequestBytes? + RequestBytes?, ] /** * TransactionsBytes can be an array of serialized txs for Typed Transactions or an array of Uint8Array Arrays for legacy transactions. diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index 9cf52e6f24..f58ee611c4 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -43,7 +43,7 @@ describe('[Block]: block functions', () => { block = createBlockFromBlockData({}, { freeze: false }) assert.ok( !Object.isFrozen(block), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) const rlpBlock = block.serialize() @@ -53,7 +53,7 @@ describe('[Block]: block functions', () => { block = createBlockFromRLPSerializedBlock(rlpBlock, { freeze: false }) assert.ok( !Object.isFrozen(block), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) const zero = new Uint8Array(0) @@ -79,7 +79,7 @@ describe('[Block]: block functions', () => { block = createBlockFromValuesArray(valuesArray, { common, freeze: false }) assert.ok( !Object.isFrozen(block), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) }) @@ -98,7 +98,7 @@ describe('[Block]: block functions', () => { extraData: new Uint8Array(97), }, }, - { common, setHardfork: true } + { common, setHardfork: true }, ) assert.equal(block.common.hardfork(), Hardfork.Berlin, 'should use setHardfork option') @@ -108,12 +108,12 @@ describe('[Block]: block functions', () => { number: 20, // Future block }, }, - { common, setHardfork: 5001 } + { common, setHardfork: 5001 }, ) assert.equal( block.common.hardfork(), Hardfork.Paris, - 'should use setHardfork option (td > threshold)' + 'should use setHardfork option (td > threshold)', ) block = createBlockFromBlockData( @@ -123,12 +123,12 @@ describe('[Block]: block functions', () => { extraData: new Uint8Array(97), }, }, - { common, setHardfork: 3000 } + { common, setHardfork: 3000 }, ) assert.equal( block.common.hardfork(), Hardfork.Berlin, - 'should work with setHardfork option (td < threshold)' + 'should work with setHardfork option (td < threshold)', ) }) @@ -150,7 +150,7 @@ describe('[Block]: block functions', () => { const common = new Common({ chain: Chain.Mainnet }) const uncleBlock = createBlockFromBlockData( { header: { extraData: new Uint8Array(117) } }, - { common } + { common }, ) assert.throws(function () { createBlockFromBlockData({ uncleHeaders: [uncleBlock.header] }, { common }) @@ -233,7 +233,7 @@ describe('[Block]: block functions', () => { const result = block.getTransactionsValidationErrors() assert.ok( result[0].includes('tx unable to pay base fee (non EIP-1559 tx)'), - 'should throw when legacy tx is unable to pay base fee' + 'should throw when legacy tx is unable to pay base fee', ) }) @@ -293,7 +293,7 @@ describe('[Block]: block functions', () => { uncleHash: KECCAK256_RLP_ARRAY, }, }, - { common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) } + { common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) }, ) await checkThrowsAsync(block.validateData(false, false), 'invalid withdrawals trie') @@ -304,7 +304,7 @@ describe('[Block]: block functions', () => { uncleHash: zeroRoot, }, }, - { common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) } + { common: new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Chainstart }) }, ) await checkThrowsAsync(block.validateData(false, false), 'invalid uncle hash') @@ -315,7 +315,7 @@ describe('[Block]: block functions', () => { block = createBlockFromBlockData({ executionWitness: null }, { common }) await checkThrowsAsync( block.validateData(false, false), - 'Invalid block: ethereumjs stateless client needs executionWitness' + 'Invalid block: ethereumjs stateless client needs executionWitness', ) }) @@ -361,7 +361,7 @@ describe('[Block]: block functions', () => { }, undefined, undefined, - 'input must be array' + 'input must be array', ) assert.throws( () => { @@ -369,7 +369,7 @@ describe('[Block]: block functions', () => { }, undefined, undefined, - 'input length must be 3 or less' + 'input length must be 3 or less', ) }) @@ -379,7 +379,7 @@ describe('[Block]: block functions', () => { toBytes(testDataPreLondon2.blocks[2].rlp as PrefixedHexString), { common, - } + }, ) const createBlockFromRaw = createBlockFromValuesArray(block.raw(), { common }) assert.ok(equalsBytes(block.hash(), createBlockFromRaw.hash())) @@ -391,14 +391,14 @@ describe('[Block]: block functions', () => { toBytes(testDataPreLondon2.blocks[2].rlp as PrefixedHexString), { common, - } + }, ) assert.equal(typeof block.toJSON(), 'object') }) it('DAO hardfork', () => { const blockData = RLP.decode( - testDataPreLondon2.blocks[0].rlp as PrefixedHexString + testDataPreLondon2.blocks[0].rlp as PrefixedHexString, ) as NestedUint8Array // Set block number from test block to mainnet DAO fork block 1920000 blockData[0][8] = hexToBytes('0x1D4C00') @@ -410,7 +410,7 @@ describe('[Block]: block functions', () => { }, /extraData should be 'dao-hard-fork/, undefined, - 'should throw on DAO HF block with wrong extra data' + 'should throw on DAO HF block with wrong extra data', ) // eslint-disable-line // Set extraData to dao-hard-fork @@ -435,14 +435,14 @@ describe('[Block]: block functions', () => { { header: nextBlockHeaderData, }, - { common } + { common }, ) // test if difficulty defaults to 0 assert.equal( blockWithoutDifficultyCalculation.header.difficulty, BigInt(0), - 'header difficulty should default to 0' + 'header difficulty should default to 0', ) // test if we set difficulty if we have a "difficulty header" in options; also verify this is equal to reported canonical difficulty. @@ -453,17 +453,17 @@ describe('[Block]: block functions', () => { { common, calcDifficultyFromHeader: genesis.header, - } + }, ) assert.ok( blockWithDifficultyCalculation.header.difficulty > BigInt(0), - 'header difficulty should be set if difficulty header is given' + 'header difficulty should be set if difficulty header is given', ) assert.ok( blockWithDifficultyCalculation.header.ethashCanonicalDifficulty(genesis.header) === blockWithDifficultyCalculation.header.difficulty, - 'header difficulty is canonical difficulty if difficulty header is given' + 'header difficulty is canonical difficulty if difficulty header is given', ) // test if we can provide a block which is too far ahead to still calculate difficulty @@ -479,12 +479,12 @@ describe('[Block]: block functions', () => { { common, calcDifficultyFromHeader: genesis.header, - } + }, ) assert.ok( block_farAhead.header.difficulty > BigInt(0), - 'should allow me to provide a bogus next block to calculate difficulty on when providing a difficulty header' + 'should allow me to provide a bogus next block to calculate difficulty on when providing a difficulty header', ) }) diff --git a/packages/block/test/clique.spec.ts b/packages/block/test/clique.spec.ts index bd5803ee0b..2c000d2bb3 100644 --- a/packages/block/test/clique.spec.ts +++ b/packages/block/test/clique.spec.ts @@ -15,29 +15,29 @@ describe('[Header]: Clique PoA Functionality', () => { }, undefined, undefined, - 'cliqueIsEpochTransition() -> should throw on PoW networks' + 'cliqueIsEpochTransition() -> should throw on PoW networks', ) header = BlockHeader.fromHeaderData({ extraData: new Uint8Array(97) }, { common }) assert.ok( header.cliqueIsEpochTransition(), - 'cliqueIsEpochTransition() -> should indicate an epoch transition for the genesis block' + 'cliqueIsEpochTransition() -> should indicate an epoch transition for the genesis block', ) header = BlockHeader.fromHeaderData({ number: 1, extraData: new Uint8Array(97) }, { common }) assert.notOk( header.cliqueIsEpochTransition(), - 'cliqueIsEpochTransition() -> should correctly identify a non-epoch block' + 'cliqueIsEpochTransition() -> should correctly identify a non-epoch block', ) assert.deepEqual( header.cliqueExtraVanity(), new Uint8Array(32), - 'cliqueExtraVanity() -> should return correct extra vanity value' + 'cliqueExtraVanity() -> should return correct extra vanity value', ) assert.deepEqual( header.cliqueExtraSeal(), new Uint8Array(65), - 'cliqueExtraSeal() -> should return correct extra seal value' + 'cliqueExtraSeal() -> should return correct extra seal value', ) assert.throws( () => { @@ -45,26 +45,26 @@ describe('[Header]: Clique PoA Functionality', () => { }, undefined, undefined, - 'cliqueEpochTransitionSigners() -> should throw on non-epch block' + 'cliqueEpochTransitionSigners() -> should throw on non-epch block', ) header = BlockHeader.fromHeaderData( { number: 60000, extraData: new Uint8Array(137) }, - { common } + { common }, ) assert.ok( header.cliqueIsEpochTransition(), - 'cliqueIsEpochTransition() -> should correctly identify an epoch block' + 'cliqueIsEpochTransition() -> should correctly identify an epoch block', ) assert.deepEqual( header.cliqueExtraVanity(), new Uint8Array(32), - 'cliqueExtraVanity() -> should return correct extra vanity value' + 'cliqueExtraVanity() -> should return correct extra vanity value', ) assert.deepEqual( header.cliqueExtraSeal(), new Uint8Array(65), - 'cliqueExtraSeal() -> should return correct extra seal value' + 'cliqueExtraSeal() -> should return correct extra seal value', ) const msg = 'cliqueEpochTransitionSigners() -> should return the correct epoch transition signer list on epoch block' @@ -81,7 +81,7 @@ describe('[Header]: Clique PoA Functionality', () => { address: new Address(hexToBytes('0x0b90087d864e82a284dca15923f3776de6bb016f')), privateKey: hexToBytes('0x64bf9cc30328b0e42387b3c82c614e6386259136235e20c1357bd11cdee86993'), publicKey: hexToBytes( - '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195' + '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195', ), } @@ -90,7 +90,7 @@ describe('[Header]: Clique PoA Functionality', () => { let header = BlockHeader.fromHeaderData( { number: 1, extraData: new Uint8Array(97) }, - { common, freeze: false, cliqueSigner } + { common, freeze: false, cliqueSigner }, ) assert.equal(header.extraData.length, 97) @@ -100,7 +100,7 @@ describe('[Header]: Clique PoA Functionality', () => { header = BlockHeader.fromHeaderData({ extraData: new Uint8Array(97) }, { common }) assert.ok( header.cliqueSigner().equals(Address.zero()), - 'should return zero address on default block' + 'should return zero address on default block', ) }) }) diff --git a/packages/block/test/difficulty.spec.ts b/packages/block/test/difficulty.spec.ts index 945d69fc03..0fe8987844 100644 --- a/packages/block/test/difficulty.spec.ts +++ b/packages/block/test/difficulty.spec.ts @@ -30,7 +30,7 @@ const hardforkTestData: TestData = { muirGlacier: Object.assign( difficultyEIP2384.difficultyEIP2384.Berlin, difficultyEIP2384_random.difficultyEIP2384_random.Berlin, - difficultyEIP2384_random_to20M.difficultyEIP2384_random_to20M.Berlin + difficultyEIP2384_random_to20M.difficultyEIP2384_random_to20M.Berlin, ), arrowGlacier: difficultyArrowGlacier.difficultyArrowGlacier.ArrowGlacier, grayGlacier: difficultyGrayGlacier.difficultyGrayGlacier.GrayGlacier, @@ -65,7 +65,7 @@ describe('[Header]: difficulty tests', () => { uncleHash, }, }, - blockOpts + blockOpts, ) const block = createBlockFromBlockData( @@ -76,7 +76,7 @@ describe('[Header]: difficulty tests', () => { number: test.currentBlockNumber, }, }, - blockOpts + blockOpts, ) runDifficultyTests(test, parentBlock, block, `fork determination by hardfork (${hardfork})`) @@ -101,7 +101,7 @@ describe('[Header]: difficulty tests', () => { uncleHash, }, }, - blockOpts + blockOpts, ) const block = createBlockFromBlockData( @@ -112,14 +112,14 @@ describe('[Header]: difficulty tests', () => { number: test.currentBlockNumber, }, }, - blockOpts + blockOpts, ) runDifficultyTests( test, parentBlock, block, - `fork determination by block number (${test.currentBlockNumber})` + `fork determination by block number (${test.currentBlockNumber})`, ) } } diff --git a/packages/block/test/eip1559block.spec.ts b/packages/block/test/eip1559block.spec.ts index 878a5907f5..0bf4b8bed5 100644 --- a/packages/block/test/eip1559block.spec.ts +++ b/packages/block/test/eip1559block.spec.ts @@ -45,12 +45,12 @@ describe('EIP1559 tests', () => { }, { common, - } + }, ) }, undefined, undefined, - 'should throw when setting baseFeePerGas with EIP1559 not being activated' + 'should throw when setting baseFeePerGas with EIP1559 not being activated', ) }) @@ -68,14 +68,14 @@ describe('EIP1559 tests', () => { calcDifficultyFromHeader: genesis.header, common, freeze: false, - } + }, ) assert.fail('should throw when baseFeePerGas is not set to initial base fee') } catch (e: any) { const expectedError = 'Initial EIP1559 block does not have initial base fee' assert.ok( e.message.includes(expectedError), - 'should throw if base fee is not set to initial value' + 'should throw if base fee is not set to initial value', ) } @@ -91,7 +91,7 @@ describe('EIP1559 tests', () => { calcDifficultyFromHeader: genesis.header, common, freeze: false, - } + }, ) ;(header as any).baseFeePerGas = undefined await (header as any)._genericFormatValidation() @@ -99,7 +99,7 @@ describe('EIP1559 tests', () => { const expectedError = 'EIP1559 block has no base fee field' assert.ok( e.message.includes(expectedError), - 'should throw with no base fee field when EIP1559 is activated' + 'should throw with no base fee field when EIP1559 is activated', ) } }) @@ -118,7 +118,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.ok(true, 'Valid initial EIP1559 header should be valid') @@ -137,7 +137,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.fail('should throw') } catch (e: any) { @@ -159,7 +159,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) createBlockFromBlockData( { @@ -174,7 +174,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: block1.header, common, - } + }, ) assert.ok(true, 'should correctly validate subsequent EIP-1559 blocks') }) @@ -195,7 +195,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.fail('should throw') } catch (e: any) { @@ -216,7 +216,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.ok(true, 'should not throw when elasticity is exactly matched') @@ -235,7 +235,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) it('Header -> validate() -> gasLimit -> success cases', async () => { @@ -251,7 +251,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.ok(true, 'should not throw if gas limit is between bounds (HF transition block)') @@ -267,7 +267,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) assert.ok(true, 'should not throw if gas limit is between bounds (HF transition block)') @@ -284,7 +284,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: block1.header, common, - } + }, ) assert.ok(true, 'should not throw if gas limit is between bounds (post-HF transition block)') @@ -300,7 +300,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: block1.header, common, - } + }, ) assert.ok(true, 'should not throw if gas limit is between bounds (post-HF transition block)') @@ -319,7 +319,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) try { header.validateGasLimit(genesis.header) @@ -327,7 +327,7 @@ describe('EIP1559 tests', () => { } catch (e: any) { assert.ok( e.message.includes('gas limit increased too much'), - 'should throw if gas limit is increased too much (HF transition block)' + 'should throw if gas limit is increased too much (HF transition block)', ) } @@ -343,7 +343,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: block1.header, common, - } + }, ) try { header.validateGasLimit(block1.header) @@ -351,7 +351,7 @@ describe('EIP1559 tests', () => { } catch (e: any) { assert.ok( e.message.includes('gas limit increased too much'), - 'should throw if gas limit is increased too much (post-HF transition block)' + 'should throw if gas limit is increased too much (post-HF transition block)', ) } }) @@ -369,7 +369,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: genesis.header, common, - } + }, ) try { header.validateGasLimit(genesis.header) @@ -377,7 +377,7 @@ describe('EIP1559 tests', () => { } catch (e: any) { assert.ok( e.message.includes('gas limit decreased too much'), - 'should throw if gas limit is decreased too much (HF transition block)' + 'should throw if gas limit is decreased too much (HF transition block)', ) } @@ -393,7 +393,7 @@ describe('EIP1559 tests', () => { { calcDifficultyFromHeader: block1.header, common, - } + }, ) try { header.validateGasLimit(block1.header) @@ -401,7 +401,7 @@ describe('EIP1559 tests', () => { } catch (e: any) { assert.ok( e.message.includes('gas limit decreased too much'), - 'should throw if gas limit is decreased too much (post-HF transition block)' + 'should throw if gas limit is decreased too much (post-HF transition block)', ) } }) @@ -412,7 +412,7 @@ describe('EIP1559 tests', () => { maxFeePerGas: BigInt(0), maxPriorityFeePerGas: BigInt(0), }, - { common } + { common }, ).sign(hexToBytes(`0x${'46'.repeat(32)}`)) const block = createBlockFromBlockData( { @@ -438,13 +438,13 @@ describe('EIP1559 tests', () => { { common, calcDifficultyFromHeader: genesis.header, - } + }, ) const errs = block.getTransactionsValidationErrors() assert.ok( errs[0].includes('unable to pay base fee'), - 'should throw if transaction is unable to pay base fee' + 'should throw if transaction is unable to pay base fee', ) }) @@ -457,7 +457,7 @@ describe('EIP1559 tests', () => { gasUsed: BigInt(item.parentGasUsed), gasLimit: BigInt(item.parentTargetGasUsed) * BigInt(2), }, - { common } + { common }, ).calcNextBaseFee() const expected = BigInt(item.expectedBaseFee) assert.equal(expected, result, 'base fee correct') @@ -475,7 +475,7 @@ describe('EIP1559 tests', () => { }, { common, - } + }, ) assert.equal(header.toJSON().baseFeePerGas, '0x5') }) diff --git a/packages/block/test/eip4788block.spec.ts b/packages/block/test/eip4788block.spec.ts index 7f294c832b..7b7a15f00a 100644 --- a/packages/block/test/eip4788block.spec.ts +++ b/packages/block/test/eip4788block.spec.ts @@ -18,12 +18,12 @@ describe('EIP4788 header tests', () => { }, { common: earlyCommon, - } + }, ) }, 'A parentBeaconBlockRoot for a header can only be provided with EIP4788 being activated', undefined, - 'should throw when setting parentBeaconBlockRoot with EIP4788 not being activated' + 'should throw when setting parentBeaconBlockRoot with EIP4788 not being activated', ) assert.throws( @@ -34,12 +34,12 @@ describe('EIP4788 header tests', () => { }, { common: earlyCommon, - } + }, ) }, 'blob gas used can only be provided with EIP4844 activated', undefined, - 'should throw when setting blobGasUsed with EIP4844 not being activated' + 'should throw when setting blobGasUsed with EIP4844 not being activated', ) assert.doesNotThrow(() => { BlockHeader.fromHeaderData( @@ -51,7 +51,7 @@ describe('EIP4788 header tests', () => { { common, skipConsensusFormatValidation: true, - } + }, ) }, 'correctly instantiates an EIP4788 block header') @@ -59,12 +59,12 @@ describe('EIP4788 header tests', () => { { header: BlockHeader.fromHeaderData({}, { common }), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) assert.equal( block.toJSON().header?.parentBeaconBlockRoot, bytesToHex(zeros(32)), - 'JSON output includes excessBlobGas' + 'JSON output includes excessBlobGas', ) }) }) diff --git a/packages/block/test/eip4844block.spec.ts b/packages/block/test/eip4844block.spec.ts index c3c316218e..de2a01234a 100644 --- a/packages/block/test/eip4844block.spec.ts +++ b/packages/block/test/eip4844block.spec.ts @@ -42,12 +42,12 @@ describe('EIP4844 header tests', () => { }, { common: earlyCommon, - } + }, ) }, 'excess blob gas can only be provided with EIP4844 activated', undefined, - 'should throw when setting excessBlobGas with EIP4844 not being activated' + 'should throw when setting excessBlobGas with EIP4844 not being activated', ) assert.throws( @@ -58,22 +58,22 @@ describe('EIP4844 header tests', () => { }, { common: earlyCommon, - } + }, ) }, 'blob gas used can only be provided with EIP4844 activated', undefined, - 'should throw when setting blobGasUsed with EIP4844 not being activated' + 'should throw when setting blobGasUsed with EIP4844 not being activated', ) const excessBlobGas = BlockHeader.fromHeaderData( {}, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ).excessBlobGas assert.equal( excessBlobGas, 0n, - 'instantiates block with reasonable default excess blob gas value when not provided' + 'instantiates block with reasonable default excess blob gas value when not provided', ) assert.doesNotThrow(() => { BlockHeader.fromHeaderData( @@ -83,7 +83,7 @@ describe('EIP4844 header tests', () => { { common, skipConsensusFormatValidation: true, - } + }, ) }, 'correctly instantiates an EIP4844 block header') @@ -91,7 +91,7 @@ describe('EIP4844 header tests', () => { { header: BlockHeader.fromHeaderData({}, { common, skipConsensusFormatValidation: true }), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) assert.equal(block.toJSON().header?.excessBlobGas, '0x0', 'JSON output includes excessBlobGas') }) @@ -116,19 +116,19 @@ describe('blob gas tests', () => { assert.equal( excessBlobGas, 0n, - 'excess blob gas where 4844 is not active on header should be 0' + 'excess blob gas where 4844 is not active on header should be 0', ) assert.throws( () => preShardingHeader.calcDataFee(1), 'header must have excessBlobGas field', undefined, - 'calcDataFee throws when header has no excessBlobGas field' + 'calcDataFee throws when header has no excessBlobGas field', ) const lowGasHeader = BlockHeader.fromHeaderData( { number: 1, excessBlobGas: 5000 }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) excessBlobGas = lowGasHeader.calcNextExcessBlobGas() @@ -137,7 +137,7 @@ describe('blob gas tests', () => { assert.equal(blobGasPrice, 1n, 'blob gas price should be 1n when low or no excess blob gas') const highGasHeader = BlockHeader.fromHeaderData( { number: 1, excessBlobGas: 6291456, blobGasUsed: BigInt(6) * blobGasPerBlob }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) excessBlobGas = highGasHeader.calcNextExcessBlobGas() blobGasPrice = highGasHeader.getBlobGasPrice() @@ -180,7 +180,7 @@ describe('transaction validation tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ).sign(randomBytes(32)) const tx2 = create4844BlobTx( { @@ -191,12 +191,12 @@ describe('transaction validation tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ).sign(randomBytes(32)) const parentHeader = BlockHeader.fromHeaderData( { number: 1n, excessBlobGas: 4194304, blobGasUsed: 0 }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const excessBlobGas = parentHeader.calcNextExcessBlobGas() @@ -211,11 +211,11 @@ describe('transaction validation tests', () => { excessBlobGas, blobGasUsed: BigInt(blobs) * blobGasPerBlob, }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const block = createBlockFromBlockData( { header: blockHeader, transactions }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) return block } @@ -228,7 +228,7 @@ describe('transaction validation tests', () => { assert.doesNotThrow( () => blockWithValidTx.validateBlobTransactions(parentHeader), - 'does not throw when all tx maxFeePerBlobGas are >= to block blob gas fee' + 'does not throw when all tx maxFeePerBlobGas are >= to block blob gas fee', ) const blockJson = blockWithValidTx.toJSON() blockJson.header!.blobGasUsed = '0x0' @@ -237,26 +237,26 @@ describe('transaction validation tests', () => { () => blockWithInvalidHeader.validateBlobTransactions(parentHeader), 'block blobGasUsed mismatch', undefined, - 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee' + 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee', ) assert.throws( () => blockWithInvalidTx.validateBlobTransactions(parentHeader), 'than block blob gas price', undefined, - 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee' + 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee', ) assert.throws( () => blockWithInvalidTx.validateBlobTransactions(parentHeader), 'than block blob gas price', undefined, - 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee' + 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee', ) assert.throws( () => blockWithTooManyBlobs.validateBlobTransactions(parentHeader), 'exceed maximum blob gas per block', undefined, - 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee' + 'throws with correct error message when tx maxFeePerBlobGas less than block blob gas fee', ) assert.ok( @@ -264,7 +264,7 @@ describe('transaction validation tests', () => { .getTransactionsValidationErrors() .join(' ') .includes('exceed maximum blob gas per block'), - 'tx erros includes correct error message when too many blobs in a block' + 'tx erros includes correct error message when too many blobs in a block', ) }) }) @@ -292,7 +292,7 @@ describe('fake exponential', () => { assert.equal( fakeExponential(BigInt(input[0]), BigInt(input[1]), BigInt(input[2])), BigInt(input[3]), - 'fake exponential produced expected output' + 'fake exponential produced expected output', ) } }) diff --git a/packages/block/test/eip4895block.spec.ts b/packages/block/test/eip4895block.spec.ts index 2159b51bbc..fec9262db0 100644 --- a/packages/block/test/eip4895block.spec.ts +++ b/packages/block/test/eip4895block.spec.ts @@ -41,14 +41,14 @@ describe('EIP4895 tests', () => { // get withdwalsArray const gethBlockBytesArray = RLP.decode(hexToBytes(`0x${gethWithdrawals8BlockRlp}`)) const withdrawals = (gethBlockBytesArray[3] as WithdrawalBytes[]).map((wa) => - Withdrawal.fromValuesArray(wa) + Withdrawal.fromValuesArray(wa), ) assert.equal(withdrawals.length, 8, '8 withdrawals should have been found') const gethWitdrawalsRoot = (gethBlockBytesArray[0] as Uint8Array[])[16] as Uint8Array assert.deepEqual( await genWithdrawalsTrieRoot(withdrawals), gethWitdrawalsRoot, - 'withdrawalsRoot should be valid' + 'withdrawalsRoot should be valid', ) }) @@ -62,19 +62,19 @@ describe('EIP4895 tests', () => { }, { common: earlyCommon, - } + }, ) }, undefined, undefined, - 'should throw when setting withdrawalsRoot with EIP4895 not being activated' + 'should throw when setting withdrawalsRoot with EIP4895 not being activated', ) assert.doesNotThrow(() => { BlockHeader.fromHeaderData( {}, { common, - } + }, ) }, 'should not throw when withdrawalsRoot is undefined with EIP4895 being activated') assert.doesNotThrow(() => { @@ -84,7 +84,7 @@ describe('EIP4895 tests', () => { }, { common, - } + }, ) }, 'correctly instantiates an EIP4895 block header') }) @@ -98,19 +98,19 @@ describe('EIP4895 tests', () => { }, { common: earlyCommon, - } + }, ) }, undefined, undefined, - 'should throw when setting withdrawals with EIP4895 not being activated' + 'should throw when setting withdrawals with EIP4895 not being activated', ) assert.doesNotThrow(() => { createBlockFromBlockData( {}, { common, - } + }, ) }, 'should not throw when withdrawals is undefined with EIP4895 being activated') assert.doesNotThrow(() => { @@ -123,7 +123,7 @@ describe('EIP4895 tests', () => { }, { common, - } + }, ) }) const block = createBlockFromBlockData( @@ -135,17 +135,17 @@ describe('EIP4895 tests', () => { }, { common, - } + }, ) assert.notOk( await block.withdrawalsTrieIsValid(), - 'should invalidate the empty withdrawals root' + 'should invalidate the empty withdrawals root', ) const validHeader = BlockHeader.fromHeaderData( { withdrawalsRoot: KECCAK256_RLP, }, - { common } + { common }, ) const validBlock = createBlockFromBlockData( { @@ -154,7 +154,7 @@ describe('EIP4895 tests', () => { }, { common, - } + }, ) assert.ok(await validBlock.withdrawalsTrieIsValid(), 'should validate empty withdrawals root') @@ -169,18 +169,18 @@ describe('EIP4895 tests', () => { { header: { withdrawalsRoot: hexToBytes( - '0x897ca49edcb278aecab2688bcc2b7b7ee43524cc489672534fee332a172f1718' + '0x897ca49edcb278aecab2688bcc2b7b7ee43524cc489672534fee332a172f1718', ), }, withdrawals: [withdrawal], }, { common, - } + }, ) assert.ok( await validBlockWithWithdrawal.withdrawalsTrieIsValid(), - 'should validate withdrawals root' + 'should validate withdrawals root', ) const withdrawal2 = { @@ -194,18 +194,18 @@ describe('EIP4895 tests', () => { { header: { withdrawalsRoot: hexToBytes( - '0x3b514862c42008079d461392e29d5b6775dd5ed370a6c4441ccb8ab742bf2436' + '0x3b514862c42008079d461392e29d5b6775dd5ed370a6c4441ccb8ab742bf2436', ), }, withdrawals: [withdrawal, withdrawal2], }, { common, - } + }, ) assert.ok( await validBlockWithWithdrawal2.withdrawalsTrieIsValid(), - 'should validate withdrawals root' + 'should validate withdrawals root', ) assert.doesNotThrow(() => { validBlockWithWithdrawal.hash() @@ -229,7 +229,7 @@ describe('EIP4895 tests', () => { }, undefined, undefined, - 'should provide withdrawals array when 4895 is active' + 'should provide withdrawals array when 4895 is active', ) }) @@ -239,7 +239,7 @@ describe('EIP4895 tests', () => { block['cache'].withdrawalsTrieRoot = randomBytes(32) assert.ok( await block.withdrawalsTrieIsValid(), - 'correctly executed code path where withdrawals length is 0' + 'correctly executed code path where withdrawals length is 0', ) }) }) diff --git a/packages/block/test/eip7685block.spec.ts b/packages/block/test/eip7685block.spec.ts index f51f129bfd..251d172c8a 100644 --- a/packages/block/test/eip7685block.spec.ts +++ b/packages/block/test/eip7685block.spec.ts @@ -59,7 +59,7 @@ describe('7685 tests', () => { requests: [request], header: { requestsRoot }, }, - { common } + { common }, ) assert.equal(block.requests?.length, 1) assert.deepEqual(block.header.requestsRoot, requestsRoot) @@ -71,7 +71,7 @@ describe('7685 tests', () => { requests: [request], header: { requestsRoot: randomBytes(32) }, }, - { common } + { common }, ) assert.equal(await block.requestsTrieIsValid(), false) @@ -90,7 +90,7 @@ describe('7685 tests', () => { requests, header: { requestsRoot }, }, - { common } + { common }, ) assert.ok(await block.requestsTrieIsValid()) @@ -102,8 +102,8 @@ describe('7685 tests', () => { requests: [request1, request3, request2], header: { requestsRoot }, }, - { common } - ) + { common }, + ), ).rejects.toThrow('ascending order') }) }) @@ -114,7 +114,7 @@ describe('fromValuesArray tests', () => { [BlockHeader.fromHeaderData({}, { common }).raw(), [], [], [], []], { common, - } + }, ) assert.deepEqual(block.header.requestsRoot, KECCAK256_RLP) }) @@ -136,7 +136,7 @@ describe('fromValuesArray tests', () => { ], { common, - } + }, ) assert.deepEqual(block.header.requestsRoot, requestsRoot) assert.equal(block.requests?.length, 3) @@ -162,7 +162,7 @@ describe('fromRPC tests', () => { ], { common, - } + }, ) const jsonBlock = block.toJSON() const rpcBlock: any = { ...jsonBlock.header, requests: jsonBlock.requests } diff --git a/packages/block/test/from-beacon-payload.spec.ts b/packages/block/test/from-beacon-payload.spec.ts index 519c649adc..778a5c816b 100644 --- a/packages/block/test/from-beacon-payload.spec.ts +++ b/packages/block/test/from-beacon-payload.spec.ts @@ -37,7 +37,7 @@ describe('[fromExecutionPayloadJson]: 4844 devnet 5', () => { }) const parentHeader = BlockHeader.fromHeaderData( { excessBlobGas: BigInt(0), blobGasUsed: block.header.excessBlobGas! + BigInt(393216) }, - { common } + { common }, ) block.validateBlobTransactions(parentHeader) assert.ok(true, `successfully constructed block=${block.header.number}`) @@ -55,7 +55,7 @@ describe('[fromExecutionPayloadJson]: 4844 devnet 5', () => { ...payload87335, block_hash: payload87475.block_hash, } as BeaconPayloadJson, - { common } + { common }, ) assert.fail(`should have failed constructing the block`) } catch (e) { @@ -72,7 +72,7 @@ describe('[fromExecutionPayloadJson]: 4844 devnet 5', () => { ...payload87475, block_hash: '0x573714bdd0ca5e47bc32008751c4fc74237f8cb354fbc1475c1d0ece38236ea4', } as BeaconPayloadJson, - { common } + { common }, ) const parentHeader = BlockHeader.fromHeaderData({ excessBlobGas: BigInt(0) }, { common }) block.validateBlobTransactions(parentHeader) @@ -102,7 +102,7 @@ describe('[fromExecutionPayloadJson]: kaustinen', () => { assert.deepEqual( block.executionWitness, payloadKaustinen.execution_witness as VerkleExecutionWitness, - 'execution witness should match' + 'execution witness should match', ) }) }) diff --git a/packages/block/test/from-rpc.spec.ts b/packages/block/test/from-rpc.spec.ts index 23c255fbf2..1aecba0621 100644 --- a/packages/block/test/from-rpc.spec.ts +++ b/packages/block/test/from-rpc.spec.ts @@ -48,11 +48,11 @@ describe('[fromRPC]:', () => { const createBlockFromTransactionValueAsInteger = createBlockFromRpc( blockDataTransactionValueAsInteger as JsonRpcBlock, undefined, - { common } + { common }, ) assert.equal( createBlockFromTransactionValueAsInteger.transactions[0].value.toString(), - valueAsIntegerString + valueAsIntegerString, ) }) @@ -64,13 +64,13 @@ describe('[fromRPC]:', () => { const createBlockFromTransactionGasPriceAsInteger = createBlockFromRpc( blockDataTransactionGasPriceAsInteger as JsonRpcBlock, undefined, - { common } + { common }, ) assert.equal( ( createBlockFromTransactionGasPriceAsInteger.transactions[0] as LegacyTransaction ).gasPrice.toString(), - gasPriceAsIntegerString + gasPriceAsIntegerString, ) }) @@ -81,11 +81,11 @@ describe('[fromRPC]:', () => { undefined, { common, - } + }, ) assert.equal( blockDifficultyAsInteger.header.difficulty.toString(), - blockDataDifficultyAsInteger.difficulty + blockDataDifficultyAsInteger.difficulty, ) }) @@ -94,7 +94,7 @@ describe('[fromRPC]:', () => { const block = createBlockFromRpc(testDataFromRpcGoerliLondon as JsonRpcBlock, [], { common }) assert.equal( `0x${block.header.baseFeePerGas?.toString(16)}`, - testDataFromRpcGoerliLondon.baseFeePerGas + testDataFromRpcGoerliLondon.baseFeePerGas, ) assert.equal(bytesToHex(block.hash()), testDataFromRpcGoerliLondon.hash) }) @@ -137,13 +137,13 @@ describe('[fromRPC] - Alchemy/Infura API block responses', () => { assert.equal( bytesToHex(block.hash()), infura2000004woTxs.hash, - 'created premerge block w/o txns' + 'created premerge block w/o txns', ) block = createBlockFromRpc(infura2000004wTxs as JsonRpcBlock, [], { common, setHardfork: true }) assert.equal( bytesToHex(block.hash()), infura2000004wTxs.hash, - 'created premerge block with txns' + 'created premerge block with txns', ) block = createBlockFromRpc(infura15571241woTxs as JsonRpcBlock, [], { common, @@ -152,7 +152,7 @@ describe('[fromRPC] - Alchemy/Infura API block responses', () => { assert.equal( bytesToHex(block.hash()), infura15571241woTxs.hash, - 'created post merge block without txns' + 'created post merge block without txns', ) block = createBlockFromRpc(infura15571241wTxs as JsonRpcBlock, [], { @@ -162,7 +162,7 @@ describe('[fromRPC] - Alchemy/Infura API block responses', () => { assert.equal( bytesToHex(block.hash()), infura15571241wTxs.hash, - 'created post merge block with txns' + 'created post merge block with txns', ) }) @@ -212,7 +212,7 @@ describe('[fromJsonRpcProvider]', () => { assert.equal( bytesToHex(block.hash()), blockHash, - 'assembled a block from blockdata from a provider' + 'assembled a block from blockdata from a provider', ) try { await createBlockFromJsonRpcProvider(provider, bytesToHex(randomBytes(32)), {}) @@ -220,7 +220,7 @@ describe('[fromJsonRpcProvider]', () => { } catch (err: any) { assert.ok( err.message.includes('No block data returned from provider'), - 'returned correct error message' + 'returned correct error message', ) } global.fetch = realFetch diff --git a/packages/block/test/header.spec.ts b/packages/block/test/header.spec.ts index 4d4cafc066..92d4d11c75 100644 --- a/packages/block/test/header.spec.ts +++ b/packages/block/test/header.spec.ts @@ -57,14 +57,14 @@ describe('[Block]: Header functions', () => { assert.equal( header.common.hardfork(), 'chainstart', - 'should initialize with correct HF provided' + 'should initialize with correct HF provided', ) common.setHardfork(Hardfork.Byzantium) assert.equal( header.common.hardfork(), 'chainstart', - 'should stay on correct HF if outer common HF changes' + 'should stay on correct HF if outer common HF changes', ) header = BlockHeader.fromHeaderData({}, { common }) @@ -78,7 +78,7 @@ describe('[Block]: Header functions', () => { header = BlockHeader.fromHeaderData({}, { freeze: false }) assert.ok( !Object.isFrozen(header), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) }) @@ -98,7 +98,7 @@ describe('[Block]: Header functions', () => { }) assert.ok( !Object.isFrozen(header), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) assert.throws( @@ -110,19 +110,19 @@ describe('[Block]: Header functions', () => { }), 'A base fee', undefined, - 'throws when RLP serialized block with no base fee on default hardfork (london) and setHardfork left undefined' + 'throws when RLP serialized block with no base fee on default hardfork (london) and setHardfork left undefined', ) header = BlockHeader.fromRLPSerializedHeader( hexToBytes( - '0xf90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000850400000000808213888080a011bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82faa00000000000000000000000000000000000000000000000000000000000000000880000000000000042' + '0xf90214a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000850400000000808213888080a011bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82faa00000000000000000000000000000000000000000000000000000000000000000880000000000000042', ), - { common, setHardfork: false } + { common, setHardfork: false }, ) assert.equal( bytesToHex(header.hash()), '0xf0f936910ebf101b7b168bbe08e3f166ce1e75e16f513dd5a97af02fbe7de7c0', - 'genesis block should produce incorrect hash since default hardfork is london' + 'genesis block should produce incorrect hash since default hardfork is london', ) }) @@ -158,7 +158,7 @@ describe('[Block]: Header functions', () => { header = BlockHeader.fromValuesArray(headerArray, { common, freeze: false }) assert.ok( !Object.isFrozen(header), - 'block should not be frozen when freeze deactivated in options' + 'block should not be frozen when freeze deactivated in options', ) }) @@ -269,9 +269,9 @@ describe('[Block]: Header functions', () => { } catch (error: any) { assert.ok( (error.message as string).includes( - 'extraData must be 97 bytes on non-epoch transition blocks, received 32 bytes' + 'extraData must be 97 bytes on non-epoch transition blocks, received 32 bytes', ), - testCase + testCase, ) } @@ -281,7 +281,7 @@ describe('[Block]: Header functions', () => { new Uint8Array(32), new Uint8Array(65), new Uint8Array(20), - new Uint8Array(21) + new Uint8Array(21), ) const epoch = BigInt((common.consensusConfig() as CliqueConfig).epoch) try { @@ -290,9 +290,9 @@ describe('[Block]: Header functions', () => { } catch (error: any) { assert.ok( (error.message as string).includes( - 'invalid signer list length in extraData, received signer length of 41 (not divisible by 20)' + 'invalid signer list length in extraData, received signer length of 41 (not divisible by 20)', ), - testCase + testCase, ) } }) @@ -305,7 +305,7 @@ describe('[Block]: Header functions', () => { BlockHeader.fromHeaderData({ extraData }, { common, skipConsensusFormatValidation: true }) assert.ok( true, - 'should instantiate header with invalid extraData when skipConsensusFormatValidation === true' + 'should instantiate header with invalid extraData when skipConsensusFormatValidation === true', ) } catch (error: any) { assert.fail('should not throw') @@ -319,26 +319,26 @@ describe('[Block]: Header functions', () => { () => BlockHeader.fromHeaderData({ parentHash: badHash }), 'parentHash must be 32 bytes', undefined, - 'throws on invalid parent hash length' + 'throws on invalid parent hash length', ) assert.throws( () => BlockHeader.fromHeaderData({ stateRoot: badHash }), 'stateRoot must be 32 bytes', undefined, - 'throws on invalid state root hash length' + 'throws on invalid state root hash length', ) assert.throws( () => BlockHeader.fromHeaderData({ transactionsTrie: badHash }), 'transactionsTrie must be 32 bytes', undefined, - 'throws on invalid transactionsTrie root hash length' + 'throws on invalid transactionsTrie root hash length', ) assert.throws( () => BlockHeader.fromHeaderData({ nonce: new Uint8Array(5) }), 'nonce must be 8 bytes', undefined, - 'contains nonce length error message' + 'contains nonce length error message', ) }) /* @@ -460,12 +460,12 @@ describe('[Block]: Header functions', () => { for (const key of Object.keys(bcBlockGasLimitTestData)) { const genesisRlp = hexToBytes( bcBlockGasLimitTestData[key as keyof typeof bcBlockGasLimitTestData] - .genesisRLP as PrefixedHexString + .genesisRLP as PrefixedHexString, ) const parentBlock = createBlockFromRLPSerializedBlock(genesisRlp, { common }) const blockRlp = hexToBytes( bcBlockGasLimitTestData[key as keyof typeof bcBlockGasLimitTestData].blocks[0] - .rlp as PrefixedHexString + .rlp as PrefixedHexString, ) const block = createBlockFromRLPSerializedBlock(blockRlp, { common }) assert.doesNotThrow(() => block.validateGasLimit(parentBlock)) @@ -486,7 +486,7 @@ describe('[Block]: Header functions', () => { assert.equal( bytesToHex(header.hash()), '0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6', - 'correct PoW hash (mainnet block 1)' + 'correct PoW hash (mainnet block 1)', ) common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Chainstart }) @@ -494,7 +494,7 @@ describe('[Block]: Header functions', () => { assert.equal( bytesToHex(header.hash()), '0x8f5bab218b6bb34476f51ca588e9f4553a3a7ce5e13a66c660a5283e97e9a85a', - 'correct PoA clique hash (goerli block 1)' + 'correct PoA clique hash (goerli block 1)', ) }) @@ -506,7 +506,7 @@ describe('[Block]: Header functions', () => { assert.deepEqual( header.withdrawalsRoot, KECCAK256_RLP, - 'withdrawalsRoot should be set to KECCAK256_RLP' + 'withdrawalsRoot should be set to KECCAK256_RLP', ) }) }) diff --git a/packages/block/test/mergeBlock.spec.ts b/packages/block/test/mergeBlock.spec.ts index f9275d225a..3a0ac43597 100644 --- a/packages/block/test/mergeBlock.spec.ts +++ b/packages/block/test/mergeBlock.spec.ts @@ -110,7 +110,7 @@ describe('[Header]: Casper PoS / The Merge Functionality', () => { undefined, { common, - } + }, ) assert.fail('should have thrown') } catch (e: any) { @@ -123,7 +123,7 @@ describe('[Header]: Casper PoS / The Merge Functionality', () => { let block = createBlockFromBlockData({ header: { mixHash } }, { common }) assert.ok( equalsBytes(block.header.prevRandao, mixHash), - 'prevRandao should return mixHash value' + 'prevRandao should return mixHash value', ) const commonLondon = common.copy() diff --git a/packages/block/test/util.ts b/packages/block/test/util.ts index 1383be87a0..c6d39e9847 100644 --- a/packages/block/test/util.ts +++ b/packages/block/test/util.ts @@ -17,7 +17,7 @@ function createBlock( parentBlock: Block, extraData: string, uncles?: BlockHeader[], - common?: Common + common?: Common, ): Block { uncles = uncles ?? [] common = common ?? new Common({ chain: Chain.Mainnet }) @@ -53,7 +53,7 @@ function createBlock( { common, calcDifficultyFromHeader: parentBlock.header, - } + }, ) } diff --git a/packages/block/tsconfig.lint.json b/packages/block/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/block/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/blockchain/.eslintrc.cjs b/packages/blockchain/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/blockchain/.eslintrc.cjs +++ b/packages/blockchain/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/blockchain/examples/clique.ts b/packages/blockchain/examples/clique.ts index 92a822a03f..4933f25081 100644 --- a/packages/blockchain/examples/clique.ts +++ b/packages/blockchain/examples/clique.ts @@ -1,6 +1,8 @@ -import { createBlockchain, CliqueConsensus, ConsensusDict } from '@ethereumjs/blockchain' +import { CliqueConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' +import type { ConsensusDict } from '@ethereumjs/blockchain' + const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.London }) const consensusDict: ConsensusDict = {} diff --git a/packages/blockchain/examples/gethGenesis.ts b/packages/blockchain/examples/gethGenesis.ts index 97b7df1db4..b435181136 100644 --- a/packages/blockchain/examples/gethGenesis.ts +++ b/packages/blockchain/examples/gethGenesis.ts @@ -1,6 +1,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' -import { Common, createCommonFromGethGenesis, parseGethGenesis } from '@ethereumjs/common' +import { createCommonFromGethGenesis } from '@ethereumjs/common' import { bytesToHex, parseGethGenesisState } from '@ethereumjs/util' + import gethGenesisJson from './genesisData/post-merge.json' const main = async () => { @@ -14,8 +15,8 @@ const main = async () => { const genesisBlockHash = blockchain.genesisBlock.hash() common.setForkHashes(genesisBlockHash) console.log( - `Genesis hash from geth genesis parameters - ${bytesToHex(blockchain.genesisBlock.hash())}` + `Genesis hash from geth genesis parameters - ${bytesToHex(blockchain.genesisBlock.hash())}`, ) } -main() +void main() diff --git a/packages/blockchain/examples/simple.ts b/packages/blockchain/examples/simple.ts index 38c4024bee..cd45156323 100644 --- a/packages/blockchain/examples/simple.ts +++ b/packages/blockchain/examples/simple.ts @@ -1,4 +1,4 @@ -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Common, Hardfork } from '@ethereumjs/common' import { bytesToHex } from '@ethereumjs/util' @@ -21,7 +21,7 @@ const main = async () => { difficulty: blockchain.genesisBlock.header.difficulty + 1n, }, }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block2 = createBlockFromBlockData( { @@ -31,7 +31,7 @@ const main = async () => { difficulty: block.header.difficulty + 1n, }, }, - { common, setHardfork: true } + { common, setHardfork: true }, ) // See @ethereumjs/block for more details on how to create a block await blockchain.putBlock(block) @@ -47,4 +47,4 @@ const main = async () => { // Block 1: 0xa1a061528d74ba81f560e1ebc4f29d6b58171fc13b72b876cdffe6e43b01bdc5 // Block 2: 0x5583be91cf9fb14f5dbeb03ad56e8cef19d1728f267c35a25ba5a355a528f602 } -main() +void main() diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index 8e81b04404..a9a45d740e 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -141,7 +141,7 @@ export class Blockchain implements BlockchainInterface { private _consensusCheck() { if (this._validateConsensus && this.consensus === undefined) { throw new Error( - `Consensus object for ${this.common.consensusAlgorithm()} must be passed (see consensusDict option) if consensus validation is activated` + `Consensus object for ${this.common.consensusAlgorithm()} must be passed (see consensusDict option) if consensus validation is activated`, ) } } @@ -168,7 +168,7 @@ export class Blockchain implements BlockchainInterface { shallowCopy(): Blockchain { const copiedBlockchain = Object.create( Object.getPrototypeOf(this), - Object.getOwnPropertyDescriptors(this) + Object.getOwnPropertyDescriptors(this), ) copiedBlockchain.common = this.common.copy() return copiedBlockchain @@ -366,7 +366,7 @@ export class Blockchain implements BlockchainInterface { return } throw new Error( - 'Cannot put a different genesis block than current blockchain genesis: create a new Blockchain' + 'Cannot put a different genesis block than current blockchain genesis: create a new Blockchain', ) } @@ -379,7 +379,7 @@ export class Blockchain implements BlockchainInterface { if (block.common.chainId() !== this.common.chainId()) { throw new Error( - `Chain mismatch while trying to put block or header. Chain ID of block: ${block.common.chainId}, chain ID of blockchain : ${this.common.chainId}` + `Chain mismatch while trying to put block or header. Chain ID of block: ${block.common.chainId}, chain ID of blockchain : ${this.common.chainId}`, ) } @@ -515,7 +515,7 @@ export class Blockchain implements BlockchainInterface { if (!(dif < BIGINT_8 && dif > BIGINT_1)) { throw new Error( - `uncle block has a parent that is too old or too young ${header.errorStr()}` + `uncle block has a parent that is too old or too young ${header.errorStr()}`, ) } } @@ -637,7 +637,7 @@ export class Blockchain implements BlockchainInterface { if (!canonicalChainHashes[parentHash]) { throw new Error( - `The parent hash of the uncle header is not part of the canonical chain ${block.errorStr()}` + `The parent hash of the uncle header is not part of the canonical chain ${block.errorStr()}`, ) } @@ -712,7 +712,7 @@ export class Blockchain implements BlockchainInterface { blockId: Uint8Array | bigint | number, maxBlocks: number, skip: number, - reverse: boolean + reverse: boolean, ): Promise { return this.runWithLock(async () => { const blocks: Block[] = [] @@ -853,7 +853,7 @@ export class Blockchain implements BlockchainInterface { blockHash: Uint8Array, blockNumber: bigint, headHash: Uint8Array | null, - ops: DBOp[] + ops: DBOp[], ) { // delete header, body, hash to number mapping and td ops.push(DBOp.del(DBTarget.Header, { blockHash, blockNumber })) @@ -901,7 +901,7 @@ export class Blockchain implements BlockchainInterface { name: string, onBlock: OnBlock, maxBlocks?: number, - releaseLockOnCallback?: boolean + releaseLockOnCallback?: boolean, ): Promise { return this.runWithLock(async (): Promise => { let headHash = this._heads[name] ?? this.genesisBlock.hash() @@ -943,7 +943,7 @@ export class Blockchain implements BlockchainInterface { await this._lock.acquire() // If lock was released check if reorg occured const nextBlockMayBeReorged = await this.getBlock(nextBlockNumber).catch( - (_e) => null + (_e) => null, ) reorgWhileOnBlock = nextBlockMayBeReorged ? !equalsBytes(nextBlockMayBeReorged.hash(), nextBlock.hash()) @@ -1041,7 +1041,7 @@ export class Blockchain implements BlockchainInterface { private async _deleteCanonicalChainReferences( blockNumber: bigint, headHash: Uint8Array, - ops: DBOp[] + ops: DBOp[], ) { try { let hash: Uint8Array | false @@ -1177,7 +1177,7 @@ export class Blockchain implements BlockchainInterface { // LevelDB doesn't handle Uint8Arrays properly when they are part // of a JSON object being stored as a value in the DB const hexHeads = Object.fromEntries( - Object.entries(this._heads).map((entry) => [entry[0], bytesToUnprefixedHex(entry[1])]) + Object.entries(this._heads).map((entry) => [entry[0], bytesToUnprefixedHex(entry[1])]), ) return [ DBOp.set(DBTarget.Heads, hexHeads), @@ -1212,7 +1212,7 @@ export class Blockchain implements BlockchainInterface { async checkAndTransitionHardForkByNumber( number: BigIntLike, td?: BigIntLike, - timestamp?: BigIntLike + timestamp?: BigIntLike, ): Promise { this.common.setHardforkBy({ blockNumber: number, @@ -1284,7 +1284,7 @@ export class Blockchain implements BlockchainInterface { } return createBlockFromBlockData( { header, withdrawals: common.isActivatedEIP(4895) ? [] : undefined }, - { common } + { common }, ) } } diff --git a/packages/blockchain/src/consensus/clique.ts b/packages/blockchain/src/consensus/clique.ts index 9f59a7a95b..8d8a163142 100644 --- a/packages/blockchain/src/consensus/clique.ts +++ b/packages/blockchain/src/consensus/clique.ts @@ -42,7 +42,7 @@ type CliqueLatestSignerStates = CliqueSignerState[] // Clique Vote type CliqueVote = [ blockNumber: bigint, - vote: [signer: Address, beneficiary: Address, cliqueNonce: Uint8Array] + vote: [signer: Address, beneficiary: Address, cliqueNonce: Uint8Array], ] type CliqueLatestVotes = CliqueVote[] @@ -154,7 +154,7 @@ export class CliqueConsensus implements Consensus { for (const [i, cSigner] of checkpointSigners.entries()) { if (activeSigners[i]?.equals(cSigner) !== true) { throw new Error( - `checkpoint signer not found in active signers list at index ${i}: ${cSigner}` + `checkpoint signer not found in active signers list at index ${i}: ${cSigner}`, ) } } @@ -178,7 +178,7 @@ export class CliqueConsensus implements Consensus { throw new Error(`${msg} ${header.errorStr()}`) } const signerIndex = signers.findIndex((address: Address) => - address.equals(header.cliqueSigner()) + address.equals(header.cliqueSigner()), ) const inTurn = header.number % BigInt(signers.length) === BigInt(signerIndex) if ( @@ -336,7 +336,7 @@ export class CliqueConsensus implements Consensus { }) // Discard votes for added signer this._cliqueLatestVotes = this._cliqueLatestVotes.filter( - (vote) => !vote[1][1].equals(beneficiary) + (vote) => !vote[1][1].equals(beneficiary), ) debug(`[Block ${header.number}] Clique majority consensus (AUTH ${beneficiary})`) } @@ -370,7 +370,7 @@ export class CliqueConsensus implements Consensus { activeSigners = activeSigners.filter((signer) => !signer.equals(beneficiary)) this._cliqueLatestVotes = this._cliqueLatestVotes.filter( // Discard votes from removed signer and for removed signer - (vote) => !vote[1][0].equals(beneficiary) && !vote[1][1].equals(beneficiary) + (vote) => !vote[1][0].equals(beneficiary) && !vote[1][1].equals(beneficiary), ) debug(`[Block ${header.number}] Clique majority consensus (DROP ${beneficiary})`) } @@ -381,17 +381,17 @@ export class CliqueConsensus implements Consensus { debug( `[Block ${header.number}] New clique vote: ${signer} -> ${beneficiary} ${ equalsBytes(nonce, CLIQUE_NONCE_AUTH) ? 'AUTH' : 'DROP' - }` + }`, ) } if (consensus) { if (round === 1) { debug( - `[Block ${header.number}] Clique majority consensus on existing votes -> update signer states` + `[Block ${header.number}] Clique majority consensus on existing votes -> update signer states`, ) } else { debug( - `[Block ${header.number}] Clique majority consensus on new vote -> update signer states` + `[Block ${header.number}] Clique majority consensus on new vote -> update signer states`, ) } const newSignerState: CliqueSignerState = [header.number, activeSigners] @@ -483,7 +483,7 @@ export class CliqueConsensus implements Consensus { // remove blockNumber from clique snapshots // (latest signer states, latest votes, latest block signers) this._cliqueLatestSignerStates = this._cliqueLatestSignerStates.filter( - (s) => s[0] <= blockNumber + (s) => s[0] <= blockNumber, ) await this.cliqueUpdateSignerStates() @@ -491,7 +491,7 @@ export class CliqueConsensus implements Consensus { await this.cliqueUpdateVotes() this._cliqueLatestBlockSigners = this._cliqueLatestBlockSigners.filter( - (s) => s[0] <= blockNumber + (s) => s[0] <= blockNumber, ) await this.cliqueUpdateLatestBlockSigners() } @@ -518,7 +518,7 @@ export class CliqueConsensus implements Consensus { if (length > limit) { this._cliqueLatestBlockSigners = this._cliqueLatestBlockSigners.slice( length - limit, - length + length, ) } } @@ -555,7 +555,7 @@ export class CliqueConsensus implements Consensus { if (signerVotes === undefined) return [] const votes = RLP.decode(signerVotes as Uint8Array) as [ Uint8Array, - [Uint8Array, Uint8Array, Uint8Array] + [Uint8Array, Uint8Array, Uint8Array], ] return votes.map((vote) => { const blockNum = bytesToBigInt(vote[0] as Uint8Array) diff --git a/packages/blockchain/src/constructors.ts b/packages/blockchain/src/constructors.ts index 75c3cc2925..8be3ba2426 100644 --- a/packages/blockchain/src/constructors.ts +++ b/packages/blockchain/src/constructors.ts @@ -26,7 +26,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { } else { stateRoot = await getGenesisStateRoot( Number(blockchain.common.chainId()) as Chain, - blockchain.common + blockchain.common, ) } } @@ -42,7 +42,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { // DB is indeed the Genesis block generated or assigned. if (dbGenesisBlock !== undefined && !equalsBytes(genesisBlock.hash(), dbGenesisBlock.hash())) { throw new Error( - 'The genesis block in the DB has a different hash than the provided genesis block.' + 'The genesis block in the DB has a different hash than the provided genesis block.', ) } @@ -82,7 +82,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { await blockchain.checkAndTransitionHardForkByNumber( latestHeader.number, td, - latestHeader.timestamp + latestHeader.timestamp, ) } @@ -98,7 +98,7 @@ export async function createBlockchain(opts: BlockchainOptions = {}) { */ export async function createBlockchainFromBlocksData( blocksData: BlockData[], - opts: BlockchainOptions = {} + opts: BlockchainOptions = {}, ) { const blockchain = await createBlockchain(opts) for (const blockData of blocksData) { diff --git a/packages/blockchain/src/db/helpers.ts b/packages/blockchain/src/db/helpers.ts index 141f9e7ce3..29685634d2 100644 --- a/packages/blockchain/src/db/helpers.ts +++ b/packages/blockchain/src/db/helpers.ts @@ -38,7 +38,7 @@ function DBSetBlockOrHeader(blockBody: Block | BlockHeader): DBOp[] { DBOp.set(DBTarget.Header, headerValue, { blockNumber, blockHash, - }) + }), ) const isGenesis = header.number === BIGINT_0 @@ -49,7 +49,7 @@ function DBSetBlockOrHeader(blockBody: Block | BlockHeader): DBOp[] { DBOp.set(DBTarget.Body, bodyValue, { blockNumber, blockHash, - }) + }), ) } @@ -73,7 +73,7 @@ function DBSaveLookups(blockHash: Uint8Array, blockNumber: bigint, skipNumIndex? ops.push( DBOp.set(DBTarget.HashToNumber, blockNumber8Bytes, { blockHash, - }) + }), ) return ops } diff --git a/packages/blockchain/src/db/manager.ts b/packages/blockchain/src/db/manager.ts index c66310ea5b..d983fc5fc0 100644 --- a/packages/blockchain/src/db/manager.ts +++ b/packages/blockchain/src/db/manager.ts @@ -249,8 +249,8 @@ export class DBManager { op.baseDBOp.type !== undefined ? op.baseDBOp.type : op.baseDBOp.value !== undefined - ? 'put' - : 'del' + ? 'put' + : 'del' const convertedOp = { key: op.baseDBOp.key, value: op.baseDBOp.value, diff --git a/packages/blockchain/src/db/operation.ts b/packages/blockchain/src/db/operation.ts index f1b66a7b28..a861b9605f 100644 --- a/packages/blockchain/src/db/operation.ts +++ b/packages/blockchain/src/db/operation.ts @@ -114,7 +114,7 @@ export class DBOp { public static set( operationTarget: DBTarget, value: Uint8Array | object, - key?: DatabaseKey + key?: DatabaseKey, ): DBOp { const dbOperation = new DBOp(operationTarget, key) dbOperation.baseDBOp.value = value diff --git a/packages/blockchain/src/helpers.ts b/packages/blockchain/src/helpers.ts index 2d4d6c3046..f654b314a7 100644 --- a/packages/blockchain/src/helpers.ts +++ b/packages/blockchain/src/helpers.ts @@ -19,7 +19,7 @@ import type { GenesisState } from '@ethereumjs/util' */ export async function genGenesisStateRoot( genesisState: GenesisState, - common: Common + common: Common, ): Promise { const genCommon = common.copy() genCommon.setHardforkBy({ diff --git a/packages/blockchain/src/types.ts b/packages/blockchain/src/types.ts index 10599b6964..c46debba28 100644 --- a/packages/blockchain/src/types.ts +++ b/packages/blockchain/src/types.ts @@ -44,7 +44,7 @@ export interface BlockchainInterface { name: string, onBlock: OnBlock, maxBlocks?: number, - releaseLockOnCallback?: boolean + releaseLockOnCallback?: boolean, ): Promise /** @@ -243,7 +243,7 @@ export interface Consensus { newBlock( block: Block, commonAncestor?: BlockHeader, - ancientHeaders?: BlockHeader[] + ancientHeaders?: BlockHeader[], ): Promise } diff --git a/packages/blockchain/test/blockValidation.spec.ts b/packages/blockchain/test/blockValidation.spec.ts index a2ea9d0717..85736948eb 100644 --- a/packages/blockchain/test/blockValidation.spec.ts +++ b/packages/blockchain/test/blockValidation.spec.ts @@ -35,7 +35,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (e: any) { assert.ok( e.message.includes('uncle is already included'), - 'block throws if uncle is already included' + 'block throws if uncle is already included', ) } }) @@ -62,7 +62,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (err: any) { assert.ok( err.message.includes('not found in DB'), - 'block throws if uncle parent hash is not part of the canonical chain' + 'block throws if uncle parent hash is not part of the canonical chain', ) } }) @@ -86,7 +86,7 @@ describe('[Blockchain]: Block validation tests', () => { lastBlock, 'too-old-uncle', [uncleBlock.header], - common + common, ) try { @@ -95,7 +95,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (e: any) { assert.ok( e.message.includes('uncle block has a parent that is too old'), - 'block throws uncle is too old' + 'block throws uncle is too old', ) } }) @@ -117,7 +117,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (e: any) { assert.ok( e.message.includes('uncle block has a parent that is too old or too young'), - 'block throws uncle is too young' + 'block throws uncle is too young', ) } }) @@ -139,7 +139,7 @@ describe('[Blockchain]: Block validation tests', () => { gasLimit: BigInt(5000), }, }, - { common } + { common }, ) const block1 = createBlock(genesis, 'block1', [], common) @@ -153,7 +153,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (e: any) { assert.ok( e.message.includes('invalid difficulty block header number=1 '), - 'block throws when uncle header is invalid' + 'block throws when uncle header is invalid', ) } }) @@ -176,7 +176,7 @@ describe('[Blockchain]: Block validation tests', () => { } catch (e: any) { assert.ok( e.message.includes('The uncle is a canonical block'), - 'block throws if an uncle is a canonical block' + 'block throws if an uncle is a canonical block', ) } }) @@ -198,7 +198,7 @@ describe('[Blockchain]: Block validation tests', () => { assert.deepEqual( (await blockchain.getCanonicalHeadHeader()).uncleHash, block2.header.uncleHash, - 'uncle blocks validated successfully' + 'uncle blocks validated successfully', ) }) @@ -236,7 +236,7 @@ describe('[Blockchain]: Block validation tests', () => { calcDifficultyFromHeader: genesis.header, common, freeze: false, - } + }, ) const block = createBlockFromBlockData({ header }, { common }) @@ -253,7 +253,7 @@ describe('[Blockchain]: Block validation tests', () => { { calcDifficultyFromHeader: block.header, common, - } + }, ) const block2 = createBlockFromBlockData({ header }, { common }) await blockchain.putBlock(block2) @@ -261,7 +261,7 @@ describe('[Blockchain]: Block validation tests', () => { const expectedError = 'Invalid block: base fee not correct' assert.ok( (e.message as string).includes(expectedError), - 'should throw when base fee is not correct' + 'should throw when base fee is not correct', ) } }) @@ -319,7 +319,7 @@ describe('[Blockchain]: Block validation tests', () => { gasLimit: BigInt(5000), }, }, - { common } + { common }, ) await blockchain.putBlock(rootBlock) @@ -332,7 +332,7 @@ describe('[Blockchain]: Block validation tests', () => { assert.deepEqual( (await blockchain.getCanonicalHeadHeader()).uncleHash, preForkBlock.header.uncleHash, - 'able to put pre-london block in chain with pre-london uncles' + 'able to put pre-london block in chain with pre-london uncles', ) common.setHardfork(Hardfork.London) const forkBlock = createBlock(preForkBlock, 'forkBlock', [], common) @@ -357,13 +357,13 @@ describe('[Blockchain]: Block validation tests', () => { { common, setHardfork: false, - } + }, ) assert.deepEqual( forkBlock_ValidCommon.uncleHeaders[0].hash(), uncleHeader.hash(), - 'successfully validated a pre-london uncle on a london block' + 'successfully validated a pre-london uncle on a london block', ) assert.equal(common.hardfork(), Hardfork.London, 'validation did not change common hardfork') @@ -377,9 +377,9 @@ describe('[Blockchain]: Block validation tests', () => { { common, setHardfork: false, - } + }, ), - 'should create block even with pre-London uncle and common evaluated with london since uncle is given default base fee' + 'should create block even with pre-London uncle and common evaluated with london since uncle is given default base fee', ) assert.equal(common.hardfork(), Hardfork.London, 'validation did not change common hardfork') }) @@ -405,7 +405,7 @@ describe('EIP 7685: requests field validation tests', () => { gasLimit: 5000, }, }, - { common } + { common }, ) await expect(async () => blockchain.putBlock(block)).rejects.toThrow('invalid requestsRoot') @@ -422,10 +422,10 @@ describe('EIP 7685: requests field validation tests', () => { }, requests: [{ type: 0x1, bytes: randomBytes(12), serialize: () => randomBytes(32) } as any], }, - { common } + { common }, ) await expect(async () => blockchain.putBlock(blockWithRequest)).rejects.toThrow( - 'invalid requestsRoot' + 'invalid requestsRoot', ) }) }) diff --git a/packages/blockchain/test/clique.spec.ts b/packages/blockchain/test/clique.spec.ts index 2b05a42cb3..544f6bf093 100644 --- a/packages/blockchain/test/clique.spec.ts +++ b/packages/blockchain/test/clique.spec.ts @@ -31,7 +31,7 @@ const A: Signer = { address: new Address(hexToBytes('0x0b90087d864e82a284dca15923f3776de6bb016f')), privateKey: hexToBytes('0x64bf9cc30328b0e42387b3c82c614e6386259136235e20c1357bd11cdee86993'), publicKey: hexToBytes( - '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195' + '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195', ), } @@ -39,7 +39,7 @@ const B: Signer = { address: new Address(hexToBytes('0x6f62d8382bf2587361db73ceca28be91b2acb6df')), privateKey: hexToBytes('0x2a6e9ad5a6a8e4f17149b8bc7128bf090566a11dbd63c30e5a0ee9f161309cd6'), publicKey: hexToBytes( - '0xca0a55f6e81cb897aee6a1c390aa83435c41048faa0564b226cfc9f3df48b73e846377fb0fd606df073addc7bd851f22547afbbdd5c3b028c91399df802083a2' + '0xca0a55f6e81cb897aee6a1c390aa83435c41048faa0564b226cfc9f3df48b73e846377fb0fd606df073addc7bd851f22547afbbdd5c3b028c91399df802083a2', ), } @@ -47,7 +47,7 @@ const C: Signer = { address: new Address(hexToBytes('0x83c30730d1972baa09765a1ac72a43db27fedce5')), privateKey: hexToBytes('0xf216ddcf276079043c52b5dd144aa073e6b272ad4bfeaf4fbbc044aa478d1927'), publicKey: hexToBytes( - '0x555b19a5cbe6dd082a4a1e1e0520dd52a82ba24fd5598ea31f0f31666c40905ed319314c5fb06d887b760229e1c0e616294e7b1cb5dfefb71507c9112132ce56' + '0x555b19a5cbe6dd082a4a1e1e0520dd52a82ba24fd5598ea31f0f31666c40905ed319314c5fb06d887b760229e1c0e616294e7b1cb5dfefb71507c9112132ce56', ), } @@ -55,7 +55,7 @@ const D: Signer = { address: new Address(hexToBytes('0x8458f408106c4875c96679f3f556a511beabe138')), privateKey: hexToBytes('0x159e95d07a6c64ddbafa6036cdb7b8114e6e8cdc449ca4b0468a6d0c955f991b'), publicKey: hexToBytes( - '0xf02724341e2df54cf53515f079b1354fa8d437e79c5b091b8d8cc7cbcca00fd8ad854cb3b3a85b06c44ecb7269404a67be88b561f2224c94d133e5fc21be915c' + '0xf02724341e2df54cf53515f079b1354fa8d437e79c5b091b8d8cc7cbcca00fd8ad854cb3b3a85b06c44ecb7269404a67be88b561f2224c94d133e5fc21be915c', ), } @@ -63,7 +63,7 @@ const E: Signer = { address: new Address(hexToBytes('0xab80a948c661aa32d09952d2a6c4ad77a4c947be')), privateKey: hexToBytes('0x48ec5a6c4a7fc67b10a9d4c8a8f594a81ae42e41ed061fa5218d96abb6012344'), publicKey: hexToBytes( - '0xadefb82b9f54e80aa3532263e4478739de16fcca6828f4ae842f8a07941c347fa59d2da1300569237009f0f122dc1fd6abb0db8fcb534280aa94948a5cc95f94' + '0xadefb82b9f54e80aa3532263e4478739de16fcca6828f4ae842f8a07941c347fa59d2da1300569237009f0f122dc1fd6abb0db8fcb534280aa94948a5cc95f94', ), } @@ -71,7 +71,7 @@ const F: Signer = { address: new Address(hexToBytes('0xdc7bc81ddf67d037d7439f8e6ff12f3d2a100f71')), privateKey: hexToBytes('0x86b0ff7b6cf70786f29f297c57562905ab0b6c32d69e177a46491e56da9e486e'), publicKey: hexToBytes( - '0xd3e3d2b722e325bfc085ff5638a112b4e7e88ff13f92fc7f6cfc14b5a25e8d1545a2f27d8537b96e8919949d5f8c139ae7fc81aea7cf7fe5d43d7faaa038e35b' + '0xd3e3d2b722e325bfc085ff5638a112b4e7e88ff13f92fc7f6cfc14b5a25e8d1545a2f27d8537b96e8919949d5f8c139ae7fc81aea7cf7fe5d43d7faaa038e35b', ), } @@ -82,11 +82,11 @@ const initWithSigners = async (signers: Signer[], common?: Common) => { const extraData = concatBytes( new Uint8Array(32), ...signers.map((s) => s.address.toBytes()), - new Uint8Array(65) + new Uint8Array(65), ) const genesisBlock = createBlockFromBlockData( { header: { gasLimit: GAS_LIMIT, extraData } }, - { common } + { common }, ) blocks.push(genesisBlock) @@ -109,7 +109,7 @@ function getBlock( signer: Signer, beneficiary?: [Signer, boolean], checkpointSigners?: Signer[], - common?: Common + common?: Common, ) { common = common ?? COMMON const number = lastBlock.header.number + BigInt(1) @@ -126,7 +126,7 @@ function getBlock( extraData = concatBytes( new Uint8Array(32), ...checkpointSigners.map((s) => s.address.toBytes()), - new Uint8Array(65) + new Uint8Array(65), ) } @@ -162,7 +162,7 @@ const addNextBlockReorg = async ( signer: Signer, beneficiary?: [Signer, boolean], checkpointSigners?: Signer[], - common?: Common + common?: Common, ) => { const block = getBlock(blockchain, forkBlock, signer, beneficiary, checkpointSigners, common) await blockchain.putBlock(block) @@ -176,7 +176,7 @@ const addNextBlock = async ( signer: Signer, beneficiary?: [Signer, boolean], checkpointSigners?: Signer[], - common?: Common + common?: Common, ) => { const block = getBlock( blockchain, @@ -184,7 +184,7 @@ const addNextBlock = async ( signer, beneficiary, checkpointSigners, - common + common, ) await blockchain.putBlock(block) blocks.push(block) @@ -204,7 +204,7 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners(head.header.number + BigInt(1)), head.header.cliqueEpochTransitionSigners(), - 'correct genesis signers' + 'correct genesis signers', ) }) @@ -219,11 +219,11 @@ describe('Clique: Initialization', () => { new Uint8Array(32), A.address.toBytes(), unauthorizedSigner.toBytes(), - new Uint8Array(65) + new Uint8Array(65), ) const block = createBlockFromBlockData( { header: { number, extraData } }, - { common: COMMON, cliqueSigner: A.privateKey } + { common: COMMON, cliqueSigner: A.privateKey }, ) try { await blockchain.putBlock(block) @@ -231,7 +231,7 @@ describe('Clique: Initialization', () => { } catch (error: any) { assert.ok( error.message.includes('checkpoint signer not found in active signers list'), - 'correct error' + 'correct error', ) } }) @@ -253,7 +253,7 @@ describe('Clique: Initialization', () => { timestamp: parentHeader.timestamp + BigInt(10000), }, }, - { common: COMMON } + { common: COMMON }, ) try { @@ -262,7 +262,7 @@ describe('Clique: Initialization', () => { } catch (error: any) { assert.ok( error.message.includes('difficulty for clique block must be INTURN (2) or NOTURN (1)'), - 'correct error' + 'correct error', ) } @@ -278,7 +278,7 @@ describe('Clique: Initialization', () => { timestamp: parentHeader.timestamp + BigInt(10000), }, }, - { common: COMMON, cliqueSigner } + { common: COMMON, cliqueSigner }, ) try { @@ -307,9 +307,9 @@ describe('Clique: Initialization', () => { assert.equal(block.header.number, BigInt(1)) assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - block.header.number + BigInt(1) + block.header.number + BigInt(1), ), - [A.address] + [A.address], ) }) @@ -320,10 +320,10 @@ describe('Clique: Initialization', () => { await addNextBlock(blockchain, blocks, A, [C, true]) assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address], - 'only accept first, second needs 2 votes' + 'only accept first, second needs 2 votes', ) }) @@ -339,10 +339,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address, C.address, D.address], - 'only accept first two, third needs 3 votes already' + 'only accept first two, third needs 3 votes already', ) }) @@ -368,10 +368,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [], - 'weird, but one less cornercase by explicitly allowing this' + 'weird, but one less cornercase by explicitly allowing this', ) }) @@ -381,10 +381,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address], - 'not fulfilled' + 'not fulfilled', ) }) @@ -395,10 +395,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address], - 'fulfilled' + 'fulfilled', ) }) @@ -409,9 +409,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -422,9 +422,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address, C.address, D.address] + [A.address, B.address, C.address, D.address], ) }) @@ -436,9 +436,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address, C.address] + [A.address, B.address, C.address], ) }) @@ -452,9 +452,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -471,9 +471,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address, C.address, D.address] + [A.address, B.address, C.address, D.address], ) }) @@ -487,9 +487,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -509,9 +509,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -524,10 +524,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address], - 'deauth votes' + 'deauth votes', ) }) @@ -540,10 +540,10 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address], - 'auth votes' + 'auth votes', ) }) @@ -563,9 +563,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -585,9 +585,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address, C.address] + [A.address, B.address, C.address], ) }) @@ -613,9 +613,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [B.address, C.address, D.address, E.address, F.address] + [B.address, C.address, D.address, E.address, F.address], ) }) @@ -634,7 +634,7 @@ describe('Clique: Initialization', () => { { baseChain: Chain.Goerli, hardfork: Hardfork.Chainstart, - } + }, ) const { blocks, blockchain } = await initWithSigners([A, B], common) await addNextBlock(blockchain, blocks, A, [C, true], undefined, common) @@ -644,9 +644,9 @@ describe('Clique: Initialization', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), - [A.address, B.address] + [A.address, B.address], ) }) @@ -659,7 +659,7 @@ describe('Clique: Initialization', () => { } catch (error: any) { assert.ok( error.message.includes('invalid PoA block signature (clique)'), - 'correct error thrown' + 'correct error thrown', ) } }) @@ -690,7 +690,7 @@ describe('Clique: Initialization', () => { { baseChain: Chain.Goerli, hardfork: Hardfork.Chainstart, - } + }, ) const { blocks, blockchain } = await initWithSigners([A, B, C], common) await addNextBlock(blockchain, blocks, A, undefined, undefined, common) @@ -711,80 +711,80 @@ describe('Clique: Initialization', () => { assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( A.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( B.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.ok( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( C.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) // block 2: C, next signer: A await addNextBlock(blockchain, blocks, C) assert.ok( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( A.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( B.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( C.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) // block 3: A, next signer: B await addNextBlock(blockchain, blocks, A) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( A.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.ok( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( B.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( C.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) // block 4: B, next signer: C await addNextBlock(blockchain, blocks, B) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( A.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.notOk( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( B.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) assert.ok( await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( C.address, - blocks[blocks.length - 1].header.number - ) + blocks[blocks.length - 1].header.number, + ), ) }) }) @@ -797,10 +797,10 @@ describe('clique: reorgs', () => { const headBlockUnforked = await addNextBlock(blockchain, blocks, B, [C, true]) assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address, C.address], - 'address C added to signers' + 'address C added to signers', ) assert.deepEqual((await blockchain.getCanonicalHeadBlock()).hash(), headBlockUnforked.hash()) await addNextBlockReorg(blockchain, blocks, genesis, B) @@ -811,10 +811,10 @@ describe('clique: reorgs', () => { assert.deepEqual( (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - blocks[blocks.length - 1].header.number + BigInt(1) + blocks[blocks.length - 1].header.number + BigInt(1), ), [A.address, B.address], - 'address C not added to signers' + 'address C not added to signers', ) }) diff --git a/packages/blockchain/test/customConsensus.spec.ts b/packages/blockchain/test/customConsensus.spec.ts index 1a82b93e50..8775375827 100644 --- a/packages/blockchain/test/customConsensus.spec.ts +++ b/packages/blockchain/test/customConsensus.spec.ts @@ -24,7 +24,7 @@ class fibonacciConsensus implements Consensus { validateConsensus(_block: Block): Promise { if (bytesToHex(_block.header.extraData) !== '0x12358d') { throw new Error( - 'header contains invalid extradata - must match first 6 elements of fibonacci sequence' + 'header contains invalid extradata - must match first 6 elements of fibonacci sequence', ) } return new Promise((resolve) => resolve()) @@ -55,7 +55,7 @@ describe('Optional consensus parameter in blockchain constructor', () => { assert.equal( (blockchain.consensus as fibonacciConsensus).algorithm, 'fibonacciConsensus', - 'consensus algorithm matches' + 'consensus algorithm matches', ) } catch (err) { assert.fail('blockchain should instantiate successfully') @@ -78,7 +78,7 @@ describe('Custom consensus validation rules', () => { gasLimit: blockchain.genesisBlock.header.gasLimit + 1n, }, }, - { common } + { common }, ) try { @@ -86,7 +86,7 @@ describe('Custom consensus validation rules', () => { assert.deepEqual( (await blockchain.getBlock(block.header.number)).header.hash(), block.header.hash(), - 'put block with valid difficulty and extraData' + 'put block with valid difficulty and extraData', ) } catch { assert.fail('should have put block with valid difficulty and extraData') @@ -102,7 +102,7 @@ describe('Custom consensus validation rules', () => { timestamp: block.header.timestamp + 1n, }, }, - { common } + { common }, ) try { await blockchain.putBlock(blockWithBadDifficulty) @@ -110,7 +110,7 @@ describe('Custom consensus validation rules', () => { } catch (err: any) { assert.ok( err.message.includes('invalid difficulty'), - 'failed to put block with invalid difficulty' + 'failed to put block with invalid difficulty', ) } @@ -125,7 +125,7 @@ describe('Custom consensus validation rules', () => { gasLimit: block.header.gasLimit + 1n, }, }, - { common } + { common }, ) try { await blockchain.putBlock(blockWithBadExtraData) @@ -134,7 +134,7 @@ describe('Custom consensus validation rules', () => { assert.ok( err.message === 'header contains invalid extradata - must match first 6 elements of fibonacci sequence', - 'failed to put block with invalid extraData' + 'failed to put block with invalid extraData', ) } }) @@ -150,7 +150,7 @@ describe('consensus transition checks', () => { assert.ok('checkAndTransitionHardForkByNumber does not throw with custom consensus') } catch (err: any) { assert.fail( - `checkAndTransitionHardForkByNumber should not throw with custom consensus, error=${err.message}` + `checkAndTransitionHardForkByNumber should not throw with custom consensus, error=${err.message}`, ) } @@ -159,7 +159,7 @@ describe('consensus transition checks', () => { try { await blockchain.checkAndTransitionHardForkByNumber(5n) assert.fail( - 'checkAndTransitionHardForkByNumber should throw when using standard consensus (ethash, clique, casper) but consensus algorithm defined in common is different' + 'checkAndTransitionHardForkByNumber should throw when using standard consensus (ethash, clique, casper) but consensus algorithm defined in common is different', ) } catch (err: any) { assert.ok(err.message.includes('Consensus object for ethash must be passed')) diff --git a/packages/blockchain/test/index.spec.ts b/packages/blockchain/test/index.spec.ts index 937ff6a187..7192f92852 100644 --- a/packages/blockchain/test/index.spec.ts +++ b/packages/blockchain/test/index.spec.ts @@ -34,14 +34,14 @@ describe('blockchain test', () => { assert.deepEqual( iteratorHead.hash(), blockchain.genesisBlock.hash(), - 'correct genesis hash (getIteratorHead())' + 'correct genesis hash (getIteratorHead())', ) blockchain = await createBlockchain({ common, hardforkByHeadBlockNumber: true }) assert.equal( common.hardfork(), 'chainstart', - 'correct HF setting with hardforkByHeadBlockNumber option' + 'correct HF setting with hardforkByHeadBlockNumber option', ) }) @@ -94,7 +94,7 @@ describe('blockchain test', () => { assert.deepEqual( genesisBlock.hash(), (await blockchain.getCanonicalHeadHeader()).hash(), - 'genesis block hash should be correct' + 'genesis block hash should be correct', ) }) @@ -223,7 +223,7 @@ describe('blockchain test', () => { } catch (e: any) { assert.ok( e.message.includes('not found in DB'), - `should throw for non-existing block-by-number request` + `should throw for non-existing block-by-number request`, ) } @@ -233,7 +233,7 @@ describe('blockchain test', () => { } catch (e: any) { assert.ok( e.message.includes('not found in DB'), - `should throw for non-existing block-by-hash request` + `should throw for non-existing block-by-hash request`, ) } }) @@ -270,7 +270,7 @@ describe('blockchain test', () => { assert.equal( err.message, 'header with number 22 not found in canonical chain', - 'canonical references correctly deleted' + 'canonical references correctly deleted', ) } @@ -285,7 +285,7 @@ describe('blockchain test', () => { assert.equal( bytesToHex(newblock22.hash()), bytesToHex(newheader22.hash()), - 'fetched block should match' + 'fetched block should match', ) }) @@ -308,7 +308,7 @@ describe('blockchain test', () => { assert.equal( getBlocks![1].header.number, blocks[3].header.number, - 'should skip two blocks apart' + 'should skip two blocks apart', ) assert.ok(!isConsecutive(getBlocks!), 'blocks should not be consecutive') }) @@ -541,7 +541,7 @@ describe('blockchain test', () => { assert.equal( e.message, 'uncle hash should be equal to hash of empty array', - 'block not constructed from empty bodies' + 'block not constructed from empty bodies', ) } }) @@ -775,7 +775,7 @@ describe('initialization tests', () => { assert.deepEqual( (await blockchain.getIteratorHead()).hash(), genesisHash, - 'head hash should equal expected mainnet genesis hash' + 'head hash should equal expected mainnet genesis hash', ) const db = blockchain.db @@ -785,7 +785,7 @@ describe('initialization tests', () => { assert.deepEqual( (await newBlockchain.getIteratorHead()).hash(), genesisHash, - 'head hash should be read from the provided db' + 'head hash should be read from the provided db', ) }) @@ -797,7 +797,7 @@ describe('initialization tests', () => { extraData: utf8ToBytes('custom extra data'), }, }, - { common } + { common }, ) const hash = genesisBlock.hash() const blockchain = await createBlockchain({ common, genesisBlock }) @@ -806,14 +806,14 @@ describe('initialization tests', () => { assert.deepEqual( (await blockchain.getIteratorHead()).hash(), hash, - 'blockchain should put custom genesis block' + 'blockchain should put custom genesis block', ) const newBlockchain = await createBlockchain({ db, genesisBlock }) assert.deepEqual( (await newBlockchain.getIteratorHead()).hash(), hash, - 'head hash should be read from the provided db' + 'head hash should be read from the provided db', ) }) @@ -825,7 +825,7 @@ describe('initialization tests', () => { extraData: utf8ToBytes('custom extra data'), }, }, - { common } + { common }, ) const hash = genesisBlock.hash() const blockchain = await createBlockchain({ common, genesisBlock }) @@ -837,7 +837,7 @@ describe('initialization tests', () => { extraData: utf8ToBytes('other extra data'), }, }, - { common } + { common }, ) // assert that this is a block with a new hash @@ -853,7 +853,7 @@ describe('initialization tests', () => { assert.equal( e.message, 'Cannot put a different genesis block than current blockchain genesis: create a new Blockchain', - 'putting a genesis block did throw (otherGenesisBlock not found in chain)' + 'putting a genesis block did throw (otherGenesisBlock not found in chain)', ) } @@ -865,7 +865,7 @@ describe('initialization tests', () => { assert.equal( e.message, 'The genesis block in the DB has a different hash than the provided genesis block.', - 'creating blockchain with different genesis block than in db throws' + 'creating blockchain with different genesis block than in db throws', ) } }) @@ -875,10 +875,10 @@ it('should correctly derive mainnet genesis block hash and stateRoot', async () const common = new Common({ chain: Chain.Mainnet }) const blockchain = await createBlockchain({ common }) const mainnetGenesisBlockHash = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) const mainnetGenesisStateRoot = hexToBytes( - '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' + '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544', ) assert.deepEqual(blockchain.genesisBlock.hash(), mainnetGenesisBlockHash) assert.deepEqual(blockchain.genesisBlock.header.stateRoot, mainnetGenesisStateRoot) diff --git a/packages/blockchain/test/iterator.spec.ts b/packages/blockchain/test/iterator.spec.ts index 2e1690eed1..3edd1712ed 100644 --- a/packages/blockchain/test/iterator.spec.ts +++ b/packages/blockchain/test/iterator.spec.ts @@ -57,13 +57,13 @@ describe('blockchain test', () => { } }, undefined, - true + true, ) assert.equal(reorged, 1, 'should have reorged once') assert.equal( servedReorged, reorgedBlocks.length, - 'should have served all 21 reorged blocks with head resetting' + 'should have served all 21 reorged blocks with head resetting', ) assert.equal(iterated, 31, 'should have iterated 10 + 21 blocks in total') }) @@ -79,7 +79,7 @@ describe('blockchain test', () => { i++ } }, - 5 + 5, ) assert.equal(iterated, 5) assert.equal(i, 5) @@ -97,7 +97,7 @@ describe('blockchain test', () => { i++ } }, - 0 + 0, ) .catch(() => { assert.fail('Promise cannot throw when running 0 blocks') @@ -118,7 +118,7 @@ describe('blockchain test', () => { i++ } }, - -1 + -1, ) .catch(() => {}) // Note: if st.end() is not called (Promise did not throw), then this test fails, as it does not end. @@ -145,7 +145,7 @@ describe('blockchain test', () => { i++ } }, - 5 + 5, ) assert.equal(i, 1) @@ -186,7 +186,7 @@ describe('blockchain test', () => { assert.equal( bytesToHex((blockchain as any)._heads['head0']), '0xabcd', - 'should get state root heads' + 'should get state root heads', ) } else { assert.fail() diff --git a/packages/blockchain/test/pos.spec.ts b/packages/blockchain/test/pos.spec.ts index 406ebbe122..37c69f67a4 100644 --- a/packages/blockchain/test/pos.spec.ts +++ b/packages/blockchain/test/pos.spec.ts @@ -36,7 +36,7 @@ const buildChain = async (blockchain: Blockchain, common: Common, height: number calcDifficultyFromHeader: blocks[number - 1].header, common, setHardfork: await blockchain.getTotalDifficulty(blocks[number - 1].hash()), - } + }, ) blocks.push(block) await blockchain.putBlock(block) @@ -70,7 +70,7 @@ describe('Proof of Stake - inserting blocks into blockchain', () => { assert.equal( bytesToHex(genesisHeader.hash()), '0x1119dc5ff680bf7b4c3d9cd41168334dee127d46b3626482076025cdd498ed0b', - 'genesis hash matches' + 'genesis hash matches', ) await buildChain(blockchain, s.common, 15) @@ -80,13 +80,13 @@ describe('Proof of Stake - inserting blocks into blockchain', () => { assert.equal( (blockchain as any).common.hardfork(), 'paris', - 'HF should have been correctly updated' + 'HF should have been correctly updated', ) const td = await blockchain.getTotalDifficulty(latestHeader.hash()) assert.equal( td, BigInt(1313601), - 'should have calculated the correct post-Merge total difficulty' + 'should have calculated the correct post-Merge total difficulty', ) const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) @@ -100,7 +100,7 @@ describe('Proof of Stake - inserting blocks into blockchain', () => { gasLimit: BigInt(10000), }, }, - { common } + { common }, ) try { await blockchain.putBlock(powBlock) @@ -108,7 +108,7 @@ describe('Proof of Stake - inserting blocks into blockchain', () => { } catch (err: any) { assert.ok( err.message.includes('invalid difficulty'), - 'should throw with invalid difficulty message' + 'should throw with invalid difficulty message', ) } }) diff --git a/packages/blockchain/test/reorg.spec.ts b/packages/blockchain/test/reorg.spec.ts index fdbaf78ff6..b060838d3d 100644 --- a/packages/blockchain/test/reorg.spec.ts +++ b/packages/blockchain/test/reorg.spec.ts @@ -22,7 +22,7 @@ describe('reorg tests', () => { gasLimit: BigInt(8000000), }, }, - { common } + { common }, ) const blocks_lowTD: Block[] = [] @@ -39,7 +39,7 @@ describe('reorg tests', () => { while (TD_High < TD_Low) { blocks_lowTD.push(generateConsecutiveBlock(blocks_lowTD[blocks_lowTD.length - 1], 0)) blocks_highTD.push( - generateConsecutiveBlock(blocks_highTD[blocks_highTD.length - 1] ?? genesis, 1) + generateConsecutiveBlock(blocks_highTD[blocks_highTD.length - 1] ?? genesis, 1), ) TD_Low += blocks_lowTD[blocks_lowTD.length - 1].header.difficulty @@ -56,12 +56,12 @@ describe('reorg tests', () => { // ensure that the block difficulty is higher on the highTD chain when compared to the low TD chain assert.ok( number_lowTD > number_highTD, - 'low TD should have a lower TD than the reported high TD' + 'low TD should have a lower TD than the reported high TD', ) assert.ok( blocks_lowTD[blocks_lowTD.length - 1].header.number > blocks_highTD[blocks_highTD.length - 1].header.number, - 'low TD block should have a higher number than high TD block' + 'low TD block should have a higher number than high TD block', ) }) @@ -69,7 +69,7 @@ describe('reorg tests', () => { const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Chainstart }) const genesisBlock = createBlockFromBlockData( { header: { extraData: new Uint8Array(97) } }, - { common } + { common }, ) const consensusDict: ConsensusDict = {} @@ -83,7 +83,7 @@ describe('reorg tests', () => { }) const extraData = hexToBytes( - '0x506172697479205465636820417574686f7269747900000000000000000000002bbf886181970654ed46e3fae0ded41ee53fec702c47431988a7ae80e6576f3552684f069af80ba11d36327aaf846d470526e4a1c461601b2fd4ebdcdc2b734a01' + '0x506172697479205465636820417574686f7269747900000000000000000000002bbf886181970654ed46e3fae0ded41ee53fec702c47431988a7ae80e6576f3552684f069af80ba11d36327aaf846d470526e4a1c461601b2fd4ebdcdc2b734a01', ) // from goerli block 1 const { gasLimit } = genesisBlock.header const base = { extraData, gasLimit, difficulty: 1 } @@ -101,7 +101,7 @@ describe('reorg tests', () => { timestamp: genesisBlock.header.timestamp + BigInt(30), }, }, - { common } + { common }, ) const block2_low = createBlockFromBlockData( { @@ -114,7 +114,7 @@ describe('reorg tests', () => { coinbase: beneficiary1, }, }, - { common } + { common }, ) const block1_high = createBlockFromBlockData( @@ -126,7 +126,7 @@ describe('reorg tests', () => { timestamp: genesisBlock.header.timestamp + BigInt(15), }, }, - { common } + { common }, ) const block2_high = createBlockFromBlockData( { @@ -137,7 +137,7 @@ describe('reorg tests', () => { timestamp: block1_high.header.timestamp + BigInt(15), }, }, - { common } + { common }, ) const block3_high = createBlockFromBlockData( { @@ -150,7 +150,7 @@ describe('reorg tests', () => { coinbase: beneficiary2, }, }, - { common } + { common }, ) await blockchain.putBlocks([block1_low, block2_low]) @@ -161,9 +161,9 @@ describe('reorg tests', () => { assert.ok( !signerStates.find( - (s: any) => s[0] === BigInt(2) && s[1].find((a: Address) => a.equals(beneficiary1)) + (s: any) => s[0] === BigInt(2) && s[1].find((a: Address) => a.equals(beneficiary1)), ), - 'should not find reorged signer state' + 'should not find reorged signer state', ) let signerVotes = (blockchain.consensus as CliqueConsensus)._cliqueLatestVotes @@ -173,25 +173,25 @@ describe('reorg tests', () => { v[0] === BigInt(2) && v[1][0].equal(block1_low.header.cliqueSigner()) && v[1][1].equal(beneficiary1) && - equalsBytes(v[1][2], CLIQUE_NONCE_AUTH) + equalsBytes(v[1][2], CLIQUE_NONCE_AUTH), ), - 'should not find reorged clique vote' + 'should not find reorged clique vote', ) let blockSigners = (blockchain.consensus as CliqueConsensus)._cliqueLatestBlockSigners assert.ok( !blockSigners.find( - (s: any) => s[0] === BigInt(1) && s[1].equal(block1_low.header.cliqueSigner()) + (s: any) => s[0] === BigInt(1) && s[1].equal(block1_low.header.cliqueSigner()), ), - 'should not find reorged block signer' + 'should not find reorged block signer', ) signerStates = (blockchain.consensus as CliqueConsensus)._cliqueLatestSignerStates assert.ok( !!signerStates.find( - (s: any) => s[0] === BigInt(3) && s[1].find((a: Address) => a.equals(beneficiary2)) + (s: any) => s[0] === BigInt(3) && s[1].find((a: Address) => a.equals(beneficiary2)), ), - 'should find reorged signer state' + 'should find reorged signer state', ) signerVotes = (blockchain.consensus as CliqueConsensus)._cliqueLatestVotes @@ -200,9 +200,9 @@ describe('reorg tests', () => { blockSigners = (blockchain.consensus as CliqueConsensus)._cliqueLatestBlockSigners assert.ok( !!blockSigners.find( - (s: any) => s[0] === BigInt(3) && s[1].equals(block3_high.header.cliqueSigner()) + (s: any) => s[0] === BigInt(3) && s[1].equals(block3_high.header.cliqueSigner()), ), - 'should find reorged block signer' + 'should find reorged block signer', ) }) }) diff --git a/packages/blockchain/test/util.ts b/packages/blockchain/test/util.ts index bebc96fdce..aa1b972b40 100644 --- a/packages/blockchain/test/util.ts +++ b/packages/blockchain/test/util.ts @@ -76,7 +76,7 @@ export const generateBlockchain = async (numberOfBlocks: number, genesis?: Block export const generateConsecutiveBlock = ( parentBlock: Block, difficultyChangeFactor: number, - gasLimit: bigint = BigInt(8000000) + gasLimit: bigint = BigInt(8000000), ): Block => { if (difficultyChangeFactor > 1) { difficultyChangeFactor = 1 @@ -87,7 +87,7 @@ export const generateConsecutiveBlock = ( number: parentBlock.header.number + BigInt(1), timestamp: parentBlock.header.timestamp + BigInt(10 + -difficultyChangeFactor * 9), }, - { common } + { common }, ) const header = BlockHeader.fromHeaderData( { @@ -100,7 +100,7 @@ export const generateConsecutiveBlock = ( { common, calcDifficultyFromHeader: parentBlock.header, - } + }, ) const block = new Block(header, undefined, undefined, undefined, { common }, undefined) @@ -150,21 +150,21 @@ export const createTestDB = async (): Promise< { type: 'put', key: hexToBytes( - '0x680000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0x680000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ), value: genesis.header.serialize(), }, { type: 'put', key: hexToBytes( - '0x680000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa374' + '0x680000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa374', ), value: RLP.encode(toBytes(17179869184)), }, { type: 'put', key: hexToBytes( - '0x620000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0x620000000000000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ), value: RLP.encode(genesis.raw().slice(1)), }, @@ -187,7 +187,7 @@ function createBlock( parentBlock: Block, extraData: string, uncles?: BlockHeader[], - common?: Common + common?: Common, ): Block { uncles = uncles ?? [] common = common ?? new Common({ chain: Chain.Mainnet }) @@ -223,7 +223,7 @@ function createBlock( { common, calcDifficultyFromHeader: parentBlock.header, - } + }, ) } diff --git a/packages/blockchain/test/utils.spec.ts b/packages/blockchain/test/utils.spec.ts index 6900c1fb86..073dc314f9 100644 --- a/packages/blockchain/test/utils.spec.ts +++ b/packages/blockchain/test/utils.spec.ts @@ -27,7 +27,7 @@ describe('[Utils/Parse]', () => { assert.equal( bytesToHex(stateRoot), '0x52e628c7f35996ba5a0402d02b34535993c89ff7fc4c430b2763ada8554bee62', - 'kiln stateRoot matches' + 'kiln stateRoot matches', ) }) @@ -38,7 +38,7 @@ describe('[Utils/Parse]', () => { assert.equal( bytesToHex(genesisHash), '0x51c7fe41be669f69c45c33a56982cbde405313342d9e2b00d7c91a7b284dd4f8', - 'kiln genesis hash matches' + 'kiln genesis hash matches', ) }) }) diff --git a/packages/blockchain/tsconfig.lint.json b/packages/blockchain/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/blockchain/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/client/.eslintrc.cjs b/packages/client/.eslintrc.cjs index 974e754e63..43d2c22619 100644 --- a/packages/client/.eslintrc.cjs +++ b/packages/client/.eslintrc.cjs @@ -1,14 +1,11 @@ module.exports = { extends: '../../config/eslint.cjs', - rules: { - 'import/extensions': 'off', - }, parserOptions: { - project: ['./tsconfig.json', './tsconfig.browser.json', './tsconfig.eslint.json'], + project: ['./tsconfig.lint.json'], }, overrides: [ { - files: ['bin/**.ts', 'test/sim/**.ts'], + files: ['bin/**.ts', 'test/sim/**.ts', 'examples/**/*.ts'], rules: { 'no-console': 'off', }, diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index ee1eccb7be..7488a7d1d6 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -553,7 +553,7 @@ async function executeBlocks(client: EthereumClient) { } } catch (e: any) { client.config.logger.error( - 'Wrong input format for block execution, allowed format types: 5, 5-10, 5[0xba4b5fd92a26badad3cad22eb6f7c7e745053739b5f5d1e8a3afb00f8fb2a280,[TX_HASH_2],...], 5[*] (all txs in verbose mode)' + 'Wrong input format for block execution, allowed format types: 5, 5-10, 5[0xba4b5fd92a26badad3cad22eb6f7c7e745053739b5f5d1e8a3afb00f8fb2a280,[TX_HASH_2],...], 5[*] (all txs in verbose mode)', ) process.exit() } @@ -597,7 +597,7 @@ async function startExecutionFrom(client: EthereumClient) { const startExecutionParent = await client.chain.getBlock(startExecutionBlock.header.parentHash) const startExecutionParentTd = await client.chain.getTd( startExecutionParent.hash(), - startExecutionParent.header.number + startExecutionParent.header.number, ) const startExecutionHardfork = client.config.execCommon.getHardforkBy({ @@ -616,7 +616,7 @@ async function startExecutionFrom(client: EthereumClient) { await client.chain.blockchain.setIteratorHead('vm', startExecutionParent.hash()) await client.chain.update(false) logger.info( - `vmHead set to ${client.chain.headers.height} for starting stateless execution at hardfork=${startExecutionHardfork}` + `vmHead set to ${client.chain.headers.height} for starting stateless execution at hardfork=${startExecutionHardfork}`, ) } catch (err: any) { logger.error(`Error setting vmHead for starting stateless execution: ${err}`) @@ -634,7 +634,7 @@ async function startExecutionFrom(client: EthereumClient) { */ async function startClient( config: Config, - genesisMeta: { genesisState?: GenesisState; genesisStateRoot?: Uint8Array } = {} + genesisMeta: { genesisState?: GenesisState; genesisStateRoot?: Uint8Array } = {}, ) { config.logger.info(`Data directory: ${config.datadir}`) if (config.lightserv) { @@ -691,11 +691,11 @@ async function startClient( config.logger.info( `Preloading block hash=0x${short(bytesToHex(block.header.hash()))} number=${ block.header.number - }` + }`, ) } catch (err: any) { config.logger.info( - `Encountered error while while preloading chain data error=${err.message}` + `Encountered error while while preloading chain data error=${err.message}`, ) break } @@ -837,7 +837,7 @@ async function inputAccounts() { for (const addressString of addresses) { const address = Address.fromString(addressString) const inputKey = (await question( - `Please enter the 0x-prefixed private key to unlock ${address}:\n` + `Please enter the 0x-prefixed private key to unlock ${address}:\n`, )) as PrefixedHexString ;(rl as any).history = (rl as any).history.slice(1) const privKey = hexToBytes(inputKey) @@ -846,7 +846,7 @@ async function inputAccounts() { accounts.push([address, privKey]) } else { console.error( - `Private key does not match for ${address} (address derived: ${derivedAddress})` + `Private key does not match for ${address} (address derived: ${derivedAddress})`, ) process.exit() } @@ -890,7 +890,7 @@ const stopClient = async ( clientStartPromise: Promise<{ client: EthereumClient servers: (RPCServer | http.Server)[] - } | null> + } | null>, ) => { config.logger.info('Caught interrupt signal. Obtaining client handle for clean shutdown...') config.logger.info('(This might take a little longer if client not yet fully started)') @@ -945,14 +945,14 @@ async function run() { v: bigint, r: Uint8Array, s: Uint8Array, - chainID?: bigint + chainID?: bigint, ) => secp256k1Expand( secp256k1Recover( msgHash, concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32)), - Number(calculateSigRecovery(v, chainID)) - ) + Number(calculateSigRecovery(v, chainID)), + ), ).slice(1) cryptoFunctions.sha256 = wasmSha256 cryptoFunctions.ecsign = (msg: Uint8Array, pk: Uint8Array, chainId?: bigint) => { @@ -1040,7 +1040,7 @@ async function run() { if (args.mine === true && accounts.length === 0) { console.error( - 'Please provide an account to mine blocks with `--unlock [address]` or use `--dev` to generate' + 'Please provide an account to mine blocks with `--unlock [address]` or use `--dev` to generate', ) process.exit() } diff --git a/packages/client/bin/startRpc.ts b/packages/client/bin/startRpc.ts index 7f28bc7b8b..b12dcbd55f 100644 --- a/packages/client/bin/startRpc.ts +++ b/packages/client/bin/startRpc.ts @@ -101,7 +101,7 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { if ((rpc || rpcEngine) && !config.saveReceipts) { logger?.warn( - `Starting client without --saveReceipts might lead to interop issues with a CL especially if the CL intends to propose blocks, omitting methods=${saveReceiptsMethods}` + `Starting client without --saveReceipts might lead to interop issues with a CL especially if the CL intends to propose blocks, omitting methods=${saveReceiptsMethods}`, ) } @@ -136,12 +136,12 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { logger.info( `Started JSON RPC Server address=http://${rpcAddr}:${rpcPort} namespaces=${namespaces}${ withEngineMethods ? ' rpcEngineAuth=' + rpcEngineAuth.toString() : '' - }` + }`, ) logger.debug( `Methods available at address=http://${rpcAddr}:${rpcPort} namespaces=${namespaces} methods=${Object.keys( - methods - ).join(',')}` + methods, + ).join(',')}`, ) } if (ws) { @@ -160,12 +160,12 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { logger.info( `Started JSON RPC Server address=ws://${wsAddr}:${wsPort} namespaces=${namespaces}${ withEngineMethods ? ` rpcEngineAuth=${rpcEngineAuth}` : '' - }` + }`, ) logger.debug( `Methods available at address=ws://${wsAddr}:${wsPort} namespaces=${namespaces} methods=${Object.keys( - methods - ).join(',')}` + methods, + ).join(',')}`, ) } } @@ -189,12 +189,12 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { }) rpcHttpServer.listen(rpcEnginePort, rpcEngineAddr) logger.info( - `Started JSON RPC server address=http://${rpcEngineAddr}:${rpcEnginePort} namespaces=${namespaces} rpcEngineAuth=${rpcEngineAuth}` + `Started JSON RPC server address=http://${rpcEngineAddr}:${rpcEnginePort} namespaces=${namespaces} rpcEngineAuth=${rpcEngineAuth}`, ) logger.debug( `Methods available at address=http://${rpcEngineAddr}:${rpcEnginePort} namespaces=${namespaces} methods=${Object.keys( - methods - ).join(',')}` + methods, + ).join(',')}`, ) if (ws) { @@ -212,12 +212,12 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { const rpcWsServer = createWsRPCServerListener(opts) if (rpcWsServer) rpcWsServer.listen(wsEnginePort, wsEngineAddr) logger.info( - `Started JSON RPC Server address=ws://${wsEngineAddr}:${wsEnginePort} namespaces=${namespaces} rpcEngineAuth=${rpcEngineAuth}` + `Started JSON RPC Server address=ws://${wsEngineAddr}:${wsEnginePort} namespaces=${namespaces} rpcEngineAuth=${rpcEngineAuth}`, ) logger.debug( `Methods available at address=ws://${wsEngineAddr}:${wsEnginePort} namespaces=${namespaces} methods=${Object.keys( - methods - ).join(',')}` + methods, + ).join(',')}`, ) } } diff --git a/packages/client/src/blockchain/chain.ts b/packages/client/src/blockchain/chain.ts index 63f03235dd..0164e6bce2 100644 --- a/packages/client/src/blockchain/chain.ts +++ b/packages/client/src/blockchain/chain.ts @@ -266,7 +266,7 @@ export class Chain { this.config.chainCommon.events.on('hardforkChanged', async (hardfork: string) => { const block = this.config.chainCommon.hardforkBlock() this.config.superMsg( - `New hardfork reached 🪢 ! hardfork=${hardfork} ${block !== null ? `block=${block}` : ''}` + `New hardfork reached 🪢 ! hardfork=${hardfork} ${block !== null ? `block=${block}` : ''}`, ) }) } @@ -353,17 +353,17 @@ export class Chain { if (this.config.chainCommon.hardforkGteHardfork(nextBlockHf, Hardfork.Paris)) { this.config.logger.info('*'.repeat(85)) this.config.logger.info( - `Paris (Merge) hardfork reached 🐼 👉 👈 🐼 ! block=${headers.height} td=${headers.td}` + `Paris (Merge) hardfork reached 🐼 👉 👈 🐼 ! block=${headers.height} td=${headers.td}`, ) this.config.logger.info('-'.repeat(85)) this.config.logger.info(' ') this.config.logger.info('Consensus layer client (CL) needed for continued sync:') this.config.logger.info( - 'https://ethereum.org/en/developers/docs/nodes-and-clients/#consensus-clients' + 'https://ethereum.org/en/developers/docs/nodes-and-clients/#consensus-clients', ) this.config.logger.info(' ') this.config.logger.info( - 'Make sure to have the JSON RPC (--rpc) and Engine API (--rpcEngine) endpoints exposed' + 'Make sure to have the JSON RPC (--rpc) and Engine API (--rpcEngine) endpoints exposed', ) this.config.logger.info('and JWT authentication configured (see client README).') this.config.logger.info(' ') @@ -371,7 +371,7 @@ export class Chain { this.config.logger.info( `Transitioning to PoS! First block for CL-framed execution: block=${ headers.height + BIGINT_1 - }` + }`, ) } } @@ -393,7 +393,7 @@ export class Chain { block: Uint8Array | bigint, max = 1, skip = 0, - reverse = false + reverse = false, ): Promise { if (!this.opened) throw new Error('Chain closed') return this.blockchain.getBlocks(block, max, skip, reverse) @@ -427,7 +427,7 @@ export class Chain { const canonicalBlock = await this.getBlock(block.header.number) if (!equalsBytes(canonicalBlock.hash(), block.hash())) { throw Error( - `Invalid putBlock for block=${block.header.number} before finalized=${this.headers.finalized.number}` + `Invalid putBlock for block=${block.header.number} before finalized=${this.headers.finalized.number}`, ) } } else { @@ -449,7 +449,7 @@ export class Chain { await this.blockchain.checkAndTransitionHardForkByNumber( b.header.number, td, - b.header.timestamp + b.header.timestamp, ) await this.blockchain.consensus?.setup({ blockchain: this.blockchain }) } @@ -479,7 +479,7 @@ export class Chain { block: Uint8Array | bigint, max: number, skip: number, - reverse: boolean + reverse: boolean, ): Promise { const blocks = await this.getBlocks(block, max, skip, reverse) return blocks.map((b) => b.header) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 09113ed96b..0bdc05a320 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -129,11 +129,11 @@ export class EthereumClient { const packageJson = JSON.parse( readFileSync( '/' + import.meta.url.split('client')[0].split('file:///')[1] + 'client/package.json', - 'utf-8' - ) + 'utf-8', + ), ) this.config.logger.info( - `Initializing Ethereumjs client version=v${packageJson.version} network=${name} chainId=${chainId}` + `Initializing Ethereumjs client version=v${packageJson.version} network=${name} chainId=${chainId}`, ) this.config.events.on(Event.SERVER_ERROR, (error) => { @@ -141,7 +141,7 @@ export class EthereumClient { }) this.config.events.on(Event.SERVER_LISTENING, (details) => { this.config.logger.info( - `Server listener up transport=${details.transport} url=${details.url}` + `Server listener up transport=${details.transport} url=${details.url}`, ) }) diff --git a/packages/client/src/config.ts b/packages/client/src/config.ts index 7d0386d0ae..c20cb6809f 100644 --- a/packages/client/src/config.ts +++ b/packages/client/src/config.ts @@ -608,7 +608,7 @@ export class Config { this.synchronized = true // Log to console the sync status this.superMsg( - `Synchronized blockchain at height=${height} hash=${short(latest.hash())} 🎉` + `Synchronized blockchain at height=${height} hash=${short(latest.hash())} 🎉`, ) } @@ -623,7 +623,7 @@ export class Config { if (diff >= this.syncedStateRemovalPeriod) { this.synchronized = false this.logger.info( - `Sync status reset (no chain updates for ${Math.round(diff / 1000)} seconds).` + `Sync status reset (no chain updates for ${Math.round(diff / 1000)} seconds).`, ) } } @@ -635,7 +635,7 @@ export class Config { latest !== null && latest !== undefined ? ' height=' + latest.number : '' } syncTargetHeight=${this.syncTargetHeight} lastSyncDate=${ (Date.now() - this.lastSyncDate) / 1000 - } secs ago` + } secs ago`, ) this.lastsyncronized = this.synchronized } diff --git a/packages/client/src/execution/level.ts b/packages/client/src/execution/level.ts index 3f80ac704b..dbebf46699 100644 --- a/packages/client/src/execution/level.ts +++ b/packages/client/src/execution/level.ts @@ -41,7 +41,7 @@ const getEncodings = (opts: EncodingOpts = {}) => { */ export class LevelDB< TKey extends Uint8Array | string = Uint8Array | string, - TValue extends Uint8Array | string | DBObject = Uint8Array | string | DBObject + TValue extends Uint8Array | string | DBObject = Uint8Array | string | DBObject, > implements DB { _leveldb: AbstractLevel @@ -52,7 +52,7 @@ export class LevelDB< * @param leveldb - An abstract-leveldown compliant store */ constructor( - leveldb?: AbstractLevel + leveldb?: AbstractLevel, ) { this._leveldb = leveldb ?? new MemoryLevel() } diff --git a/packages/client/src/execution/receipt.ts b/packages/client/src/execution/receipt.ts index 2c1f4c0904..b560b60c0f 100644 --- a/packages/client/src/execution/receipt.ts +++ b/packages/client/src/execution/receipt.ts @@ -38,7 +38,7 @@ type GetReceiptByTxHashReturn = [ receipt: TxReceipt, blockHash: Uint8Array, txIndex: number, - logIndex: number + logIndex: number, ] type GetLogsReturn = { log: Log @@ -121,17 +121,17 @@ export class ReceiptsManager extends MetaDBManager { async getReceipts( blockHash: Uint8Array, calcBloom?: boolean, - includeTxType?: true + includeTxType?: true, ): Promise async getReceipts( blockHash: Uint8Array, calcBloom?: boolean, - includeTxType?: false + includeTxType?: false, ): Promise async getReceipts( blockHash: Uint8Array, calcBloom = false, - includeTxType = false + includeTxType = false, ): Promise { const encoded = await this.get(DBKey.Receipts, blockHash) if (!encoded) return [] @@ -176,7 +176,7 @@ export class ReceiptsManager extends MetaDBManager { from: Block, to: Block, addresses?: Uint8Array[], - topics: (Uint8Array | Uint8Array[] | null)[] = [] + topics: (Uint8Array | Uint8Array[] | null)[] = [], ): Promise { const returnedLogs: GetLogsReturn = [] let returnedLogsSize = 0 @@ -194,7 +194,7 @@ export class ReceiptsManager extends MetaDBManager { tx: block.transactions[receiptIndex], txIndex: receiptIndex, logIndex: logIndex++, - })) + })), ) } if (addresses && addresses.length > 0) { @@ -245,7 +245,7 @@ export class ReceiptsManager extends MetaDBManager { private async updateIndex( operation: IndexOperation, type: IndexType.TxHash, - value: Block + value: Block, ): Promise private async updateIndex(operation: IndexOperation, type: IndexType, value: any): Promise { switch (type) { @@ -309,14 +309,14 @@ export class ReceiptsManager extends MetaDBManager { private rlp( conversion: RlpConvert.Decode, type: RlpType.Receipts, - values: Uint8Array + values: Uint8Array, ): TxReceipt[] private rlp(conversion: RlpConvert.Decode, type: RlpType.Logs, value: rlpLog[]): Log[] private rlp(conversion: RlpConvert.Decode, type: RlpType.TxHash, value: Uint8Array): TxHashIndex private rlp( conversion: RlpConvert, type: RlpType, - value: Uint8Array | rlpOut + value: Uint8Array | rlpOut, ): Uint8Array | rlpOut { switch (type) { case RlpType.Receipts: @@ -328,7 +328,7 @@ export class ReceiptsManager extends MetaDBManager { intToBytes((r as PostByzantiumTxReceipt).status), bigIntToBytes(r.cumulativeBlockGasUsed), this.rlp(RlpConvert.Encode, RlpType.Logs, r.logs), - ]) + ]), ) } else { const decoded = RLP.decode(value as Uint8Array) as unknown as rlpReceipt[] diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index 17ea600cd6..87e73cd7e3 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -129,7 +129,7 @@ export class VMExecution extends Execution { if (resolve !== undefined) { resolve() } - } + }, ) } if (this.config.savePreimages) { @@ -236,7 +236,7 @@ export class VMExecution extends Execution { const verkleStateRoot = await verkleStateManager.getTransitionStateRoot( merkleStateManager, - merkleStateRoot + merkleStateRoot, ) await verkleStateManager.setStateRoot(verkleStateRoot) @@ -285,7 +285,7 @@ export class VMExecution extends Execution { this.vm = this.verkleVM! } else { this.config.logger.info( - `Initializing VM merkle statemanager genesis hardfork=${this.hardfork}` + `Initializing VM merkle statemanager genesis hardfork=${this.hardfork}`, ) await this.setupMerkleVM() this.vm = this.merkleVM! @@ -369,7 +369,7 @@ export class VMExecution extends Execution { opts: RunBlockOpts & { parentBlock?: Block }, receipts?: TxReceipt[], blocking: boolean = false, - skipBlockchain: boolean = false + skipBlockchain: boolean = false, ): Promise { // if its not blocking request then return early if its already running else wait to grab the lock if ((!blocking && this.running) || !this.started || this.config.shutdown) return false @@ -508,7 +508,7 @@ export class VMExecution extends Execution { */ async setHead( blocks: Block[], - { finalizedBlock, safeBlock }: { finalizedBlock?: Block; safeBlock?: Block } = {} + { finalizedBlock, safeBlock }: { finalizedBlock?: Block; safeBlock?: Block } = {}, ): Promise { if (!this.started || this.config.shutdown) return false @@ -524,8 +524,8 @@ export class VMExecution extends Execution { // execution run will always fail throw Error( `vmHeadBlock's stateRoot not found number=${vmHeadBlock.header.number} root=${short( - vmHeadBlock.header.stateRoot - )}` + vmHeadBlock.header.stateRoot, + )}`, ) } @@ -563,7 +563,7 @@ export class VMExecution extends Execution { const td = await this.chain.getTd( vmHeadBlock.header.parentHash, - vmHeadBlock.header.number - BIGINT_1 + vmHeadBlock.header.number - BIGINT_1, ) const hardfork = this.config.execCommon.setHardforkBy({ blockNumber: vmHeadBlock.header.number, @@ -596,7 +596,7 @@ export class VMExecution extends Execution { return this.runWithLock(async () => { // check if the block is canonical in chain this.config.logger.warn( - `Setting execution head to hash=${short(jumpToHash)} number=${jumpToNumber}` + `Setting execution head to hash=${short(jumpToHash)} number=${jumpToNumber}`, ) await this.vm.blockchain.setIteratorHead('vm', jumpToHash) }) @@ -626,13 +626,13 @@ export class VMExecution extends Execution { if (typeof blockchain.getCanonicalHeadBlock !== 'function') { throw new Error( - 'cannot get iterator head: blockchain has no getCanonicalHeadBlock function' + 'cannot get iterator head: blockchain has no getCanonicalHeadBlock function', ) } let canonicalHead = await blockchain.getCanonicalHeadBlock() this.config.logger.debug( - `Running execution startHeadBlock=${startHeadBlock?.header.number} canonicalHead=${canonicalHead?.header.number} loop=${loop}` + `Running execution startHeadBlock=${startHeadBlock?.header.number} canonicalHead=${canonicalHead?.header.number} loop=${loop}`, ) let headBlock: Block | undefined @@ -672,7 +672,7 @@ export class VMExecution extends Execution { if (reorg) { clearCache = true this.config.logger.info( - `VM run: Chain reorged, setting new head to block number=${headBlock.header.number} clearCache=${clearCache}.` + `VM run: Chain reorged, setting new head to block number=${headBlock.header.number} clearCache=${clearCache}.`, ) } else { const prevVMStateRoot = await this.vm.stateManager.getStateRoot() @@ -688,7 +688,7 @@ export class VMExecution extends Execution { const { number, timestamp } = block.header if (typeof blockchain.getTotalDifficulty !== 'function') { throw new Error( - 'cannot get iterator head: blockchain has no getTotalDifficulty function' + 'cannot get iterator head: blockchain has no getTotalDifficulty function', ) } const td = await blockchain.getTotalDifficulty(block.header.parentHash) @@ -702,7 +702,7 @@ export class VMExecution extends Execution { const wasPrePrague = !this.config.execCommon.gteHardfork(Hardfork.Osaka) const hash = short(block.hash()) this.config.superMsg( - `Execution hardfork switch on block number=${number} hash=${hash} old=${this.hardfork} new=${hardfork}` + `Execution hardfork switch on block number=${number} hash=${hash} old=${this.hardfork} new=${hardfork}`, ) this.hardfork = this.config.execCommon.setHardforkBy({ blockNumber: number, @@ -724,7 +724,7 @@ export class VMExecution extends Execution { throw Error( `Invalid vm stateManager type=${typeof this.vm.stateManager} for fork=${ this.hardfork - }` + }`, ) } @@ -785,7 +785,7 @@ export class VMExecution extends Execution { }, this.config.numBlocksPerIteration, // release lock on this callback so other blockchain ops can happen while this block is being executed - true + true, ) // Ensure to catch and not throw as this would lead to unCaughtException with process exit .catch(async (error) => { @@ -812,7 +812,7 @@ export class VMExecution extends Execution { hasParentStateRoot = false if (headBlock !== undefined) { hasParentStateRoot = await this.vm.stateManager.hasStateRoot( - headBlock.header.stateRoot + headBlock.header.stateRoot, ) backStepTo = headBlock.header.number ?? BIGINT_0 - BIGINT_1 backStepToHash = headBlock.header.parentHash @@ -822,17 +822,17 @@ export class VMExecution extends Execution { if (hasParentStateRoot === true && backStepToHash !== undefined) { this.config.logger.warn( `${errorMsg}, backStepping vmHead to number=${backStepTo} hash=${short( - backStepToHash ?? 'na' - )} hasParentStateRoot=${short(backStepToRoot ?? 'na')}:\n${error}` + backStepToHash ?? 'na', + )} hasParentStateRoot=${short(backStepToRoot ?? 'na')}:\n${error}`, ) await this.vm.blockchain.setIteratorHead('vm', backStepToHash) } else { this.config.logger.error( `${errorMsg}, couldn't back step to vmHead number=${backStepTo} hash=${short( - backStepToHash ?? 'na' + backStepToHash ?? 'na', )} hasParentStateRoot=${hasParentStateRoot} backStepToRoot=${short( - backStepToRoot ?? 'na' - )}:\n${error}` + backStepToRoot ?? 'na', + )}:\n${error}`, ) } } else { @@ -869,7 +869,7 @@ export class VMExecution extends Execution { } this.config.events.emit(Event.SYNC_EXECUTION_VM_ERROR, error) const actualExecuted = Number( - errorBlock.header.number - startHeadBlock.header.number + errorBlock.header.number - startHeadBlock.header.number, ) return actualExecuted } else { @@ -885,7 +885,7 @@ export class VMExecution extends Execution { endHeadBlock = await this.vm.blockchain.getIteratorHead('vm') } else { throw new Error( - 'cannot get iterator head: blockchain has no getIteratorHead function' + 'cannot get iterator head: blockchain has no getIteratorHead function', ) } @@ -904,7 +904,7 @@ export class VMExecution extends Execution { ;(this.config.execCommon.gteHardfork(Hardfork.Paris) ? this.config.logger.debug : this.config.logger.info)( - `Executed blocks count=${numExecuted} first=${firstNumber} hash=${firstHash} ${tdAdd}${baseFeeAdd}hardfork=${this.hardfork} last=${lastNumber} hash=${lastHash} txs=${txCounter}` + `Executed blocks count=${numExecuted} first=${firstNumber} hash=${firstHash} ${tdAdd}${baseFeeAdd}hardfork=${this.hardfork} last=${lastNumber} hash=${lastHash} txs=${txCounter}`, ) await this.chain.update(false) @@ -912,13 +912,13 @@ export class VMExecution extends Execution { this.config.logger.debug( `No blocks executed past chain head hash=${short(endHeadBlock.hash())} number=${ endHeadBlock.header.number - }` + }`, ) } startHeadBlock = endHeadBlock if (typeof this.vm.blockchain.getCanonicalHeadBlock !== 'function') { throw new Error( - 'cannot get iterator head: blockchain has no getCanonicalHeadBlock function' + 'cannot get iterator head: blockchain has no getCanonicalHeadBlock function', ) } canonicalHead = await this.vm.blockchain.getCanonicalHeadBlock() @@ -939,7 +939,7 @@ export class VMExecution extends Execution { this._statsInterval = setInterval( // eslint-disable-next-line @typescript-eslint/await-thenable await this.stats.bind(this), - this.STATS_INTERVAL + this.STATS_INTERVAL, ) const { blockchain } = this.vm @@ -1075,7 +1075,7 @@ export class VMExecution extends Execution { if (allTxs || txHashes.includes(txHash)) { const res = await runTx(vm, { block, tx }) this.config.logger.info( - `Executed tx hash=${txHash} gasUsed=${res.totalGasSpent} from block num=${blockNumber}` + `Executed tx hash=${txHash} gasUsed=${res.totalGasSpent} from block num=${blockNumber}`, ) count += 1 } @@ -1099,22 +1099,22 @@ export class VMExecution extends Execution { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions stats = !sm._accountCacheSettings.deactivate ? sm._accountCache.stats() : disactivatedStats this.config.logger.info( - `Account cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}` + `Account cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}`, ) // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions stats = !sm._storageCacheSettings.deactivate ? sm._storageCache.stats() : disactivatedStats this.config.logger.info( - `Storage cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}` + `Storage cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}`, ) // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions stats = !sm._codeCacheSettings.deactivate ? sm._codeCache.stats() : disactivatedStats this.config.logger.info( - `Code cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}` + `Code cache stats size=${stats.size} reads=${stats.reads} hits=${stats.hits} writes=${stats.writes}`, ) const tStats = (sm._trie as Trie).database().stats() this.config.logger.info( `Trie cache stats size=${tStats.size} reads=${tStats.cache.reads} hits=${tStats.cache.hits} ` + - `writes=${tStats.cache.writes} readsDB=${tStats.db.reads} hitsDB=${tStats.db.hits} writesDB=${tStats.db.writes}` + `writes=${tStats.cache.writes} readsDB=${tStats.db.reads} hitsDB=${tStats.db.hits} writesDB=${tStats.db.writes}`, ) } } diff --git a/packages/client/src/ext/jwt-simple.ts b/packages/client/src/ext/jwt-simple.ts index 45ce840259..a33be6c7dc 100644 --- a/packages/client/src/ext/jwt-simple.ts +++ b/packages/client/src/ext/jwt-simple.ts @@ -102,7 +102,7 @@ const decode = function jwt_decode( token: string, key: string, noVerify: boolean = false, - algorithm: string = '' + algorithm: string = '', ) { // check token if (!token) { @@ -168,7 +168,7 @@ const encode = function jwt_encode( payload: any, key: string, algorithm: string = '', - options: any = undefined + options: any = undefined, ) { // Check key if (!key) { diff --git a/packages/client/src/ext/qheap.ts b/packages/client/src/ext/qheap.ts index 346245b232..dc83e56f23 100644 --- a/packages/client/src/ext/qheap.ts +++ b/packages/client/src/ext/qheap.ts @@ -63,10 +63,10 @@ export class Heap { // @ts-ignore return opts!.compar!(a, b) < 0 } - : opts.comparBefore ?? + : (opts.comparBefore ?? function (a: any, b: any): boolean { return a < b - } + }) this._sortBefore = opts.compar ?? diff --git a/packages/client/src/logging.ts b/packages/client/src/logging.ts index defa127bc7..b62749ead9 100644 --- a/packages/client/src/logging.ts +++ b/packages/client/src/logging.ts @@ -86,7 +86,7 @@ function logFormat(colors = false) { const msg = `[${info.timestamp}] ${level} ${CLLog}${HFLog}${info.message}` return msg - } + }, ) } @@ -99,7 +99,7 @@ function formatConfig(colors = false) { format.splat(), label({ label: 'ethereumjs' }), timestamp({ format: 'MM-DD|HH:mm:ss' }), - logFormat(colors) + logFormat(colors), ) } diff --git a/packages/client/src/miner/miner.ts b/packages/client/src/miner/miner.ts index a9bed0341d..a5ff3f719a 100644 --- a/packages/client/src/miner/miner.ts +++ b/packages/client/src/miner/miner.ts @@ -110,11 +110,11 @@ export class Miner { const number = parentBlock.header.number + BIGINT_1 const inTurn = await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress, - number + number, ) if (inTurn === false) { const signerCount = (blockchain.consensus as CliqueConsensus).cliqueActiveSigners( - number + number, ).length timeout += Math.random() * signerCount * 500 } @@ -159,7 +159,7 @@ export class Miner { this.config.logger.debug( `Miner: Chain updated with block ${ latestBlockHeader.number - }. Queuing next block assembly in ${Math.round(timeout / 1000)}s` + }. Queuing next block assembly in ${Math.round(timeout / 1000)}s`, ) await this.queueNextAssembly(timeout) } @@ -211,7 +211,7 @@ export class Miner { const cliqueSigner = this.config.accounts[0][1] const header = BlockHeader.fromHeaderData( { number }, - { common: this.config.chainCommon, cliqueSigner } + { common: this.config.chainCommon, cliqueSigner }, ) if ( (this.service.chain.blockchain as any).consensus.cliqueCheckRecentlySigned(header) === true @@ -247,7 +247,7 @@ export class Miner { // Determine if signer is INTURN (2) or NOTURN (1) inTurn = await (vmCopy.blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress, - number + number, ) difficulty = inTurn ? 2 : 1 } @@ -297,7 +297,7 @@ export class Miner { typeof baseFeePerGas === 'bigint' && baseFeePerGas !== BIGINT_0 ? `(baseFee: ${baseFeePerGas})` : '' - }` + }`, ) let index = 0 let blockFull = false @@ -319,14 +319,14 @@ export class Miner { // If block has less than 21000 gas remaining, consider it full blockFull = true this.config.logger.info( - `Miner: Assembled block full (gasLeft: ${gasLimit - blockBuilder.gasUsed})` + `Miner: Assembled block full (gasLeft: ${gasLimit - blockBuilder.gasUsed})`, ) } } else { // If there is an error adding a tx, it will be skipped const hash = bytesToHex(txs[index].hash()) this.config.logger.debug( - `Skipping tx ${hash}, error encountered when trying to add tx:\n${error}` + `Skipping tx ${hash}, error encountered when trying to add tx:\n${error}`, ) } } @@ -343,7 +343,7 @@ export class Miner { this.config.chainCommon.consensusType() === ConsensusType.ProofOfWork ? `(difficulty: ${block.header.difficulty})` : `(${inTurn === true ? 'in turn' : 'not in turn'})` - }` + }`, ) this.assembling = false if (interrupt) return diff --git a/packages/client/src/miner/pendingBlock.ts b/packages/client/src/miner/pendingBlock.ts index e5978359fd..0d08db6e76 100644 --- a/packages/client/src/miner/pendingBlock.ts +++ b/packages/client/src/miner/pendingBlock.ts @@ -98,7 +98,7 @@ export class PendingBlock { vm: VM, parentBlock: Block, headerData: Partial = {}, - withdrawals?: WithdrawalData[] + withdrawals?: WithdrawalData[], ) { const number = parentBlock.header.number + BIGINT_1 const { timestamp, mixHash, parentBeaconBlockRoot, coinbase } = headerData @@ -138,7 +138,7 @@ export class PendingBlock { for (const withdrawal of withdrawals) { const indexBuf = bigIntToUnpaddedBytes(toType(withdrawal.index ?? 0, TypeOutput.BigInt)) const validatorIndex = bigIntToUnpaddedBytes( - toType(withdrawal.validatorIndex ?? 0, TypeOutput.BigInt) + toType(withdrawal.validatorIndex ?? 0, TypeOutput.BigInt), ) const address = toType(withdrawal.address ?? Address.zero(), TypeOutput.Uint8Array) const amount = bigIntToUnpaddedBytes(toType(withdrawal.amount ?? 0, TypeOutput.BigInt)) @@ -158,9 +158,9 @@ export class PendingBlock { gasLimitBuf, parentBeaconBlockRootBuf, coinbaseBuf, - withdrawalsBuf - ) - ).subarray(0, 8) + withdrawalsBuf, + ), + ).subarray(0, 8), ) const payloadId = bytesToHex(payloadIdBytes) @@ -210,12 +210,12 @@ export class PendingBlock { allowedBlobs, }) this.config.logger.info( - `Pending: Assembling block from ${txs.length} eligible txs (baseFee: ${baseFeePerGas})` + `Pending: Assembling block from ${txs.length} eligible txs (baseFee: ${baseFeePerGas})`, ) const { addedTxs, skippedByAddErrors, blobTxs } = await this.addTransactions(builder, txs) this.config.logger.info( - `Pending: Added txs=${addedTxs} skippedByAddErrors=${skippedByAddErrors} from total=${txs.length} tx candidates` + `Pending: Added txs=${addedTxs} skippedByAddErrors=${skippedByAddErrors} from total=${txs.length} tx candidates`, ) // Construct initial blobs bundle when payload is constructed @@ -244,7 +244,7 @@ export class PendingBlock { * Returns the completed block */ async build( - payloadIdBytes: Uint8Array | string + payloadIdBytes: Uint8Array | string, ): Promise { const payloadId = typeof payloadIdBytes !== 'string' ? bytesToHex(payloadIdBytes) : payloadIdBytes @@ -283,8 +283,8 @@ export class PendingBlock { ).filter( (tx) => (builder as any).transactions.some((t: TypedTransaction) => - equalsBytes(t.hash(), tx.hash()) - ) === false + equalsBytes(t.hash(), tx.hash()), + ) === false, ) const { skippedByAddErrors, blobTxs } = await this.addTransactions(builder, txs) @@ -303,8 +303,8 @@ export class PendingBlock { `Pending: Built block number=${block.header.number} txs=${ block.transactions.length }${withdrawalsStr}${blobsStr} skippedByAddErrors=${skippedByAddErrors} hash=${bytesToHex( - block.hash() - )}` + block.hash(), + )}`, ) return [block, builder.transactionReceipts, builder.minerValue, blobs] @@ -365,15 +365,15 @@ export class PendingBlock { // Remove the blob tx which doesn't has blobs bundled this.txPool.removeByHash(bytesToHex(tx.hash()), tx) this.config.logger.error( - `Pending: Removed from txPool a blob tx ${bytesToHex(tx.hash())} with missing blobs` + `Pending: Removed from txPool a blob tx ${bytesToHex(tx.hash())} with missing blobs`, ) addTxResult = AddTxResult.RemovedByErrors } else { // If there is an error adding a tx, it will be skipped this.config.logger.debug( `Pending: Skipping tx ${bytesToHex( - tx.hash() - )}, error encountered when trying to add tx:\n${error}` + tx.hash(), + )}, error encountered when trying to add tx:\n${error}`, ) addTxResult = AddTxResult.SkippedByErrors } diff --git a/packages/client/src/net/peer/rlpxpeer.ts b/packages/client/src/net/peer/rlpxpeer.ts index 92277a2d3a..d2016f20f8 100644 --- a/packages/client/src/net/peer/rlpxpeer.ts +++ b/packages/client/src/net/peer/rlpxpeer.ts @@ -176,19 +176,19 @@ export class RlpxPeer extends Peer { const snapProtocol = snapRlpxProtocol !== undefined ? this.protocols.find( - (p) => p.name === snapRlpxProtocol?.constructor.name.toLowerCase() + (p) => p.name === snapRlpxProtocol?.constructor.name.toLowerCase(), ) : undefined if (snapProtocol !== undefined) { const snapSender = new RlpxSender( - snapRlpxProtocol as Devp2pETH | Devp2pLES | Devp2pSNAP + snapRlpxProtocol as Devp2pETH | Devp2pLES | Devp2pSNAP, ) return this.addProtocol(snapSender, snapProtocol) } } }) } - }) + }), ) this.connected = true } diff --git a/packages/client/src/net/peerpool.ts b/packages/client/src/net/peerpool.ts index f48a397405..c02daa800e 100644 --- a/packages/client/src/net/peerpool.ts +++ b/packages/client/src/net/peerpool.ts @@ -91,13 +91,13 @@ export class PeerPool { this._statusCheckInterval = setInterval( // eslint-disable-next-line @typescript-eslint/await-thenable await this._statusCheck.bind(this), - this.DEFAULT_STATUS_CHECK_INTERVAL + this.DEFAULT_STATUS_CHECK_INTERVAL, ) this._peerBestHeaderUpdateInterval = setInterval( // eslint-disable-next-line @typescript-eslint/await-thenable await this._peerBestHeaderUpdate.bind(this), - this.DEFAULT_PEER_BEST_HEADER_UPDATE_INTERVAL + this.DEFAULT_PEER_BEST_HEADER_UPDATE_INTERVAL, ) this.running = true diff --git a/packages/client/src/net/protocol/boundprotocol.ts b/packages/client/src/net/protocol/boundprotocol.ts index 5198d86dfa..299d18c5d2 100644 --- a/packages/client/src/net/protocol/boundprotocol.ts +++ b/packages/client/src/net/protocol/boundprotocol.ts @@ -84,7 +84,7 @@ export class BoundProtocol { } }) this.sender.on('error', (error: Error) => - this.config.events.emit(Event.PROTOCOL_ERROR, error, this.peer) + this.config.events.emit(Event.PROTOCOL_ERROR, error, this.peer), ) } @@ -137,7 +137,7 @@ export class BoundProtocol { Event.PROTOCOL_MESSAGE, { name: message.name, data }, this.protocol.name, - this.peer + this.peer, ) } } diff --git a/packages/client/src/net/protocol/ethprotocol.ts b/packages/client/src/net/protocol/ethprotocol.ts index b0cbdebd2e..ed8f811776 100644 --- a/packages/client/src/net/protocol/ethprotocol.ts +++ b/packages/client/src/net/protocol/ethprotocol.ts @@ -175,7 +175,7 @@ export class EthProtocol extends Protocol { // to correct hardfork choice const header = BlockHeader.fromValuesArray( h, - difficulty > 0 ? { common, setHardfork: true } : { common, setHardfork: this.chainTTD } + difficulty > 0 ? { common, setHardfork: true } : { common, setHardfork: this.chainTTD }, ) return header }), @@ -231,7 +231,7 @@ export class EthProtocol extends Protocol { ] }, decode: ( - params: Uint8Array[] | [types: PrefixedHexString, sizes: number[], hashes: Uint8Array[]] + params: Uint8Array[] | [types: PrefixedHexString, sizes: number[], hashes: Uint8Array[]], ) => { if (isNestedUint8Array(params) === true) { return params @@ -337,7 +337,7 @@ export class EthProtocol extends Protocol { Uint8Array, Uint8Array, Uint8Array, - Log[] + Log[], ] const receipt = { cumulativeBlockGasUsed: bytesToBigInt(cumulativeGasUsed), diff --git a/packages/client/src/net/protocol/flowcontrol.ts b/packages/client/src/net/protocol/flowcontrol.ts index 4330244e76..54414961dd 100644 --- a/packages/client/src/net/protocol/flowcontrol.ts +++ b/packages/client/src/net/protocol/flowcontrol.ts @@ -27,7 +27,7 @@ export class FlowControl { readonly bl: number readonly mrc: Mrc readonly mrr: number - readonly out: Map; + readonly out: Map readonly in: Map constructor(options?: FlowControlOptions) { diff --git a/packages/client/src/net/protocol/lesprotocol.ts b/packages/client/src/net/protocol/lesprotocol.ts index b64324b774..bf624f2c2b 100644 --- a/packages/client/src/net/protocol/lesprotocol.ts +++ b/packages/client/src/net/protocol/lesprotocol.ts @@ -41,7 +41,7 @@ type GetBlockHeadersOpts = { */ export interface LesProtocolMethods { getBlockHeaders: ( - opts: GetBlockHeadersOpts + opts: GetBlockHeadersOpts, ) => Promise<{ reqId: bigint; bv: bigint; headers: BlockHeader[] }> } @@ -112,7 +112,7 @@ export class LesProtocol extends Protocol { BlockHeader.fromValuesArray(h, { setHardfork: true, common: this.config.chainCommon, // eslint-disable-line no-invalid-this - }) + }), ), }), }, @@ -186,10 +186,10 @@ export class LesProtocol extends Protocol { const forkHash = this.config.chainCommon.forkHash( this.config.chainCommon.hardfork(), - this.chain.genesis.hash() + this.chain.genesis.hash(), ) const nextFork = this.config.chainCommon.nextHardforkBlockOrTimestamp( - this.config.chainCommon.hardfork() + this.config.chainCommon.hardfork(), ) const forkID = [hexToBytes(forkHash), bigIntToUnpaddedBytes(nextFork ?? 0n)] diff --git a/packages/client/src/net/protocol/snapprotocol.ts b/packages/client/src/net/protocol/snapprotocol.ts index db70510457..614ae8aaa7 100644 --- a/packages/client/src/net/protocol/snapprotocol.ts +++ b/packages/client/src/net/protocol/snapprotocol.ts @@ -81,7 +81,7 @@ type GetTrieNodesOpts = { */ export interface SnapProtocolMethods { getAccountRange: ( - opts: GetAccountRangeOpts + opts: GetAccountRangeOpts, ) => Promise<{ reqId: bigint; accounts: AccountData[]; proof: Uint8Array[] }> getStorageRanges: (opts: GetStorageRangesOpts) => Promise<{ reqId: bigint @@ -158,7 +158,7 @@ export class SnapProtocol extends Protocol { ({ hash, body: this.convertSlimBody === true ? accountBodyFromSlim(body) : body, - } as AccountData) + }) as AccountData, ), proof, } @@ -206,7 +206,7 @@ export class SnapProtocol extends Protocol { return [ bigIntToUnpaddedBytes(reqId ?? ++this.nextReqId), slots.map((accSlots) => - accSlots.map((slotData) => [setLengthLeft(slotData.hash, 32), slotData.body]) + accSlots.map((slotData) => [setLengthLeft(slotData.hash, 32), slotData.body]), ), proof, ] @@ -215,7 +215,7 @@ export class SnapProtocol extends Protocol { return { reqId: bytesToBigInt(reqId), slots: slots.map((accSlots: any) => - accSlots.map(([hash, body]: any) => ({ hash, body } as StorageData)) + accSlots.map(([hash, body]: any) => ({ hash, body }) as StorageData), ), proof, } diff --git a/packages/client/src/net/server/rlpxserver.ts b/packages/client/src/net/server/rlpxserver.ts index 11de958b9a..f041ff7a5c 100644 --- a/packages/client/src/net/server/rlpxserver.ts +++ b/packages/client/src/net/server/rlpxserver.ts @@ -41,7 +41,7 @@ const ignoredErrors = new RegExp( // Client 'Handshake timed out', // Protocol handshake 'Server already destroyed', // Bootstrap retrigger - ].join('|') + ].join('|'), ) /** @@ -243,7 +243,7 @@ export class RlpxServer extends Server { this.dpt.bind(this.config.port, '0.0.0.0') } this.config.logger.info( - `Started discovery service discV4=${this.config.discV4} dns=${this.config.discDns} refreshInterval=${this.refreshInterval}` + `Started discovery service discV4=${this.config.discV4} dns=${this.config.discDns} refreshInterval=${this.refreshInterval}`, ) }) } @@ -291,14 +291,14 @@ export class RlpxServer extends Server { if (peer) { this.peers.delete(peer.id) this.config.logger.debug( - `Peer disconnected (${rlpxPeer.getDisconnectPrefix(reason)}): ${peer}` + `Peer disconnected (${rlpxPeer.getDisconnectPrefix(reason)}): ${peer}`, ) this.config.events.emit(Event.PEER_DISCONNECTED, peer) } }) this.rlpx.events.on('peer:error', (rlpxPeer: Devp2pRLPxPeer, error: Error) => - this.error(error) + this.error(error), ) this.rlpx.events.on('error', (e: Error) => { diff --git a/packages/client/src/rpc/index.ts b/packages/client/src/rpc/index.ts index fc18973587..58ddd1972e 100644 --- a/packages/client/src/rpc/index.ts +++ b/packages/client/src/rpc/index.ts @@ -32,7 +32,7 @@ export class RPCManager { getMethods(engine = false, rpcDebug = false) { const methods: { [key: string]: Function } = {} const mods = modules.list.filter((name: string) => - engine ? name === 'Engine' : name !== 'Engine' + engine ? name === 'Engine' : name !== 'Engine', ) for (const modName of mods) { const mod = new (modules as any)[modName](this._client, rpcDebug) @@ -64,7 +64,7 @@ export class RPCManager { */ static getMethodNames(mod: Object): string[] { const methodNames = Object.getOwnPropertyNames((mod as any).prototype).filter( - (methodName: string) => methodName !== 'constructor' + (methodName: string) => methodName !== 'constructor', ) return methodNames } diff --git a/packages/client/src/rpc/modules/debug.ts b/packages/client/src/rpc/modules/debug.ts index e8e63b8c9e..729889f199 100644 --- a/packages/client/src/rpc/modules/debug.ts +++ b/packages/client/src/rpc/modules/debug.ts @@ -94,7 +94,7 @@ export class Debug { this.traceTransaction = middleware( callWithStackTrace(this.traceTransaction.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.traceCall = middleware(callWithStackTrace(this.traceCall.bind(this), this._rpcDebug), 2, [ [validators.transaction()], @@ -109,27 +109,27 @@ export class Debug { [validators.address], [validators.uint256], [validators.unsignedInteger], - ] + ], ) this.getRawBlock = middleware( callWithStackTrace(this.getRawBlock.bind(this), this._rpcDebug), 1, - [[validators.blockOption]] + [[validators.blockOption]], ) this.getRawHeader = middleware( callWithStackTrace(this.getRawHeader.bind(this), this._rpcDebug), 1, - [[validators.blockOption]] + [[validators.blockOption]], ) this.getRawReceipts = middleware( callWithStackTrace(this.getRawReceipts.bind(this), this._rpcDebug), 1, - [[validators.blockOption]] + [[validators.blockOption]], ) this.getRawTransaction = middleware( callWithStackTrace(this.getRawTransaction.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) } @@ -153,7 +153,7 @@ export class Debug { const opts = validateTracerConfig(config) const result = await this.service.execution.receiptsManager.getReceiptByTxHash( - hexToBytes(txHash) + hexToBytes(txHash), ) if (!result) return null const [_, blockHash, txIndex] = result @@ -318,7 +318,7 @@ export class Debug { * The object will also contain `nextKey`, the next (hashed) storage key after the range included in `storage`. */ async storageRangeAt( - params: [PrefixedHexString, number, PrefixedHexString, PrefixedHexString, number] + params: [PrefixedHexString, number, PrefixedHexString, PrefixedHexString, number], ) { const [blockHash, txIndex, account, startKey, limit] = params @@ -357,7 +357,7 @@ export class Debug { // Validator already verified that `account` and `startKey` are properly formatted. Address.fromString(account), BigInt(startKey), - limit + limit, ) } /** @@ -390,7 +390,7 @@ export class Debug { const receipts = await this.service.execution.receiptsManager.getReceipts( block.hash(), true, - true + true, ) return receipts.map((r) => bytesToHex(encodeReceipt(r, r.txType))) } @@ -402,7 +402,7 @@ export class Debug { const [txHash] = params if (!this.service.execution.receiptsManager) throw new Error('missing receiptsManager') const result = await this.service.execution.receiptsManager.getReceiptByTxHash( - hexToBytes(txHash) + hexToBytes(txHash), ) if (!result) return null const [_receipt, blockHash, txIndex] = result diff --git a/packages/client/src/rpc/modules/engine/CLConnectionManager.ts b/packages/client/src/rpc/modules/engine/CLConnectionManager.ts index 148772f1e0..da6e5c0776 100644 --- a/packages/client/src/rpc/modules/engine/CLConnectionManager.ts +++ b/packages/client/src/rpc/modules/engine/CLConnectionManager.ts @@ -137,15 +137,15 @@ export class CLConnectionManager { this._connectionCheckInterval = setInterval( // eslint-disable @typescript-eslint/await-thenable this.connectionCheck.bind(this), - this.DEFAULT_CONNECTION_CHECK_INTERVAL + this.DEFAULT_CONNECTION_CHECK_INTERVAL, ) this._payloadLogInterval = setInterval( this.lastPayloadLog.bind(this), - this.DEFAULT_PAYLOAD_LOG_INTERVAL + this.DEFAULT_PAYLOAD_LOG_INTERVAL, ) this._forkchoiceLogInterval = setInterval( this.lastForkchoiceLog.bind(this), - this.DEFAULT_FORKCHOICE_LOG_INTERVAL + this.DEFAULT_FORKCHOICE_LOG_INTERVAL, ) } @@ -166,11 +166,11 @@ export class CLConnectionManager { private _getPayloadLogMsg(payload: NewPayload) { let msg = `number=${Number(payload.payload.blockNumber)} hash=${short( - payload.payload.blockHash + payload.payload.blockHash, )} parentHash=${short(payload.payload.parentHash)} status=${ payload.response ? payload.response.status : '-' } gasUsed=${this.compactNum(Number(payload.payload.gasUsed))} baseFee=${Number( - payload.payload.baseFeePerGas + payload.payload.baseFeePerGas, )} txs=${payload.payload.transactions.length}` if ('withdrawals' in payload.payload && payload.payload.withdrawals !== null) { @@ -190,7 +190,7 @@ export class CLConnectionManager { msg += `number=${Number(update.headBlock.header.number)} ` } msg += `head=${short(update.state.headBlockHash)} finalized=${short( - update.state.finalizedBlockHash + update.state.finalizedBlockHash, )} response=${update.response ? update.response.payloadStatus.status : '-'}` if (update.headBlock) { msg += ` timestampDiff=${this.timeDiffStr(update.headBlock)}` @@ -217,7 +217,7 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `Initial consensus forkchoice update ${this._getForkchoiceUpdateLogMsg(update)}`, - logLevel.INFO + logLevel.INFO, ) } this._lastForkchoiceUpdate = update @@ -230,7 +230,7 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `Initial consensus payload received ${this._getPayloadLogMsg(payload)}`, - logLevel.INFO + logLevel.INFO, ) } this._lastPayload = payload @@ -319,12 +319,12 @@ export class CLConnectionManager { logCLStatus( this.config.logger, 'CL client connection is needed, Merge HF happening soon', - logLevel.WARN + logLevel.WARN, ) logCLStatus( this.config.logger, '(no CL <-> EL communication yet, connection might be in a workable state though)', - logLevel.WARN + logLevel.WARN, ) } } @@ -337,12 +337,12 @@ export class CLConnectionManager { logCLStatus( this.config.logger, 'Paris (Merge) HF activated, CL client connection is needed for continued block processing', - logLevel.INFO + logLevel.INFO, ) logCLStatus( this.config.logger, '(note that CL client might need to be synced up to beacon chain Merge transition slot until communication starts)', - logLevel.INFO + logLevel.INFO, ) } this.oneTimeMergeCLConnectionCheck = true @@ -365,7 +365,7 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `Last consensus payload received ${payloadMsg}`, - logLevel.INFO + logLevel.INFO, ) const count = this._payloadToPayloadStats['blockCount'] const min = this._payloadToPayloadStats['minBlockNumber'] @@ -381,7 +381,7 @@ export class CLConnectionManager { `Payload stats blocks count=${count} minBlockNum=${min} maxBlockNum=${max} txsPerType=${ txsMsg.length > 0 ? txsMsg.join('|') : '0' }`, - logLevel.DEBUG + logLevel.DEBUG, ) this.clearPayloadStats() } @@ -398,7 +398,7 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `New consensus payload received ${payloadMsg}`, - logLevel.INFO + logLevel.INFO, ) } } @@ -415,15 +415,15 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `No consensus forkchoice update received yet`, - logLevel.INFO + logLevel.INFO, ) } else { logCLStatus( this.config.logger, `Last consensus forkchoice update ${this._getForkchoiceUpdateLogMsg( - this._lastForkchoiceUpdate + this._lastForkchoiceUpdate, )}`, - logLevel.INFO + logLevel.INFO, ) } } @@ -437,9 +437,9 @@ export class CLConnectionManager { logCLStatus( this.config.logger, `New chain head set (forkchoice update) ${this._getForkchoiceUpdateLogMsg( - this._lastForkchoiceUpdate + this._lastForkchoiceUpdate, )}`, - logLevel.INFO + logLevel.INFO, ) } } @@ -451,7 +451,7 @@ export class CLConnectionManager { */ export function middleware( methodFn: (params: any[]) => Promise, - handler: (params: any[], response: any, errormsg: any) => void + handler: (params: any[], response: any, errormsg: any) => void, ): any { return function (params: any[] = []) { return methodFn(params) diff --git a/packages/client/src/rpc/modules/engine/engine.ts b/packages/client/src/rpc/modules/engine/engine.ts index d9094eba22..7eddb70f0c 100644 --- a/packages/client/src/rpc/modules/engine/engine.ts +++ b/packages/client/src/rpc/modules/engine/engine.ts @@ -178,7 +178,7 @@ export class Engine { middleware(callWithStackTrace(this.newPayloadV1.bind(this), this._rpcDebug), 1, [ [validators.object(executionPayloadV1FieldValidators)], ]), - ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }) + ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }), ) this.newPayloadV2 = cmMiddleware( @@ -186,11 +186,11 @@ export class Engine { [ validators.either( validators.object(executionPayloadV1FieldValidators), - validators.object(executionPayloadV2FieldValidators) + validators.object(executionPayloadV2FieldValidators), ), ], ]), - ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }) + ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }), ) this.newPayloadV3 = cmMiddleware( @@ -202,9 +202,9 @@ export class Engine { [validators.array(validators.bytes32)], [validators.bytes32], ], - ['executionPayload', 'blobVersionedHashes', 'parentBeaconBlockRoot'] + ['executionPayload', 'blobVersionedHashes', 'parentBeaconBlockRoot'], ), - ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }) + ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }), ) this.newPayloadV4 = cmMiddleware( @@ -216,9 +216,9 @@ export class Engine { [validators.array(validators.bytes32)], [validators.bytes32], ], - ['executionPayload', 'blobVersionedHashes', 'parentBeaconBlockRoot'] + ['executionPayload', 'blobVersionedHashes', 'parentBeaconBlockRoot'], ), - ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }) + ([payload], response) => this.connectionManager.lastNewPayload({ payload, response }), ) /** @@ -227,7 +227,7 @@ export class Engine { const forkchoiceUpdatedResponseCMHandler = ( [state]: ForkchoiceStateV1[], response?: ForkchoiceResponseV1 & { headBlock?: Block }, - error?: string + error?: string, ) => { this.connectionManager.lastForkchoiceUpdate({ state, @@ -244,21 +244,21 @@ export class Engine { [validators.object(forkchoiceFieldValidators)], [validators.optional(validators.object(payloadAttributesFieldValidatorsV1))], ]), - forkchoiceUpdatedResponseCMHandler + forkchoiceUpdatedResponseCMHandler, ) this.forkchoiceUpdatedV2 = cmMiddleware( middleware(callWithStackTrace(this.forkchoiceUpdatedV2.bind(this), this._rpcDebug), 1, [ [validators.object(forkchoiceFieldValidators)], [validators.optional(validators.object(payloadAttributesFieldValidatorsV2))], ]), - forkchoiceUpdatedResponseCMHandler + forkchoiceUpdatedResponseCMHandler, ) this.forkchoiceUpdatedV3 = cmMiddleware( middleware(callWithStackTrace(this.forkchoiceUpdatedV3.bind(this), this._rpcDebug), 1, [ [validators.object(forkchoiceFieldValidators)], [validators.optional(validators.object(payloadAttributesFieldValidatorsV3))], ]), - forkchoiceUpdatedResponseCMHandler + forkchoiceUpdatedResponseCMHandler, ) /** @@ -268,28 +268,28 @@ export class Engine { middleware(callWithStackTrace(this.getPayloadV1.bind(this), this._rpcDebug), 1, [ [validators.bytes8], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) this.getPayloadV2 = cmMiddleware( middleware(callWithStackTrace(this.getPayloadV2.bind(this), this._rpcDebug), 1, [ [validators.bytes8], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) this.getPayloadV3 = cmMiddleware( middleware(callWithStackTrace(this.getPayloadV3.bind(this), this._rpcDebug), 1, [ [validators.bytes8], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) this.getPayloadV4 = cmMiddleware( middleware(callWithStackTrace(this.getPayloadV4.bind(this), this._rpcDebug), 1, [ [validators.bytes8], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) /** @@ -307,9 +307,9 @@ export class Engine { terminalBlockNumber: validators.uint64, }), ], - ] + ], ), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) /** @@ -317,7 +317,7 @@ export class Engine { */ this.exchangeCapabilities = cmMiddleware( middleware(callWithStackTrace(this.exchangeCapabilities.bind(this), this._rpcDebug), 0, []), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) /** @@ -327,7 +327,7 @@ export class Engine { middleware(callWithStackTrace(this.getPayloadBodiesByHashV1.bind(this), this._rpcDebug), 1, [ [validators.array(validators.bytes32)], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) /** @@ -338,7 +338,7 @@ export class Engine { [validators.bytes8], [validators.bytes8], ]), - () => this.connectionManager.updateStatus() + () => this.connectionManager.updateStatus(), ) } @@ -360,7 +360,7 @@ export class Engine { * 3. validationError: String|null - validation error message */ private async newPayload( - params: [ExecutionPayload, (Bytes32[] | null)?, (Bytes32 | null)?] + params: [ExecutionPayload, (Bytes32[] | null)?, (Bytes32 | null)?], ): Promise { const [payload, blobVersionedHashes, parentBeaconBlockRoot] = params if (this.config.synchronized) { @@ -386,7 +386,7 @@ export class Engine { parentBeaconBlockRoot: parentBeaconBlockRoot ?? undefined, }, this.chain, - this.chainCache + this.chainCache, ) if (headBlock === undefined || error !== undefined) { let response = error @@ -396,7 +396,7 @@ export class Engine { const latestValidHash = await validHash( hexToBytes(parentHash as PrefixedHexString), this.chain, - this.chainCache + this.chainCache, ) response = { status: Status.INVALID, latestValidHash, validationError } } @@ -421,7 +421,7 @@ export class Engine { const latestValidHash = await validHash( hexToBytes(parentHash as PrefixedHexString), this.chain, - this.chainCache + this.chainCache, ) const response = { status: Status.INVALID, latestValidHash, validationError } // skip marking the block invalid as this is more of a data issue from CL @@ -432,7 +432,7 @@ export class Engine { const latestValidHash = await validHash( hexToBytes(parentHash as PrefixedHexString), this.chain, - this.chainCache + this.chainCache, ) const response = { status: Status.INVALID, latestValidHash, validationError } // skip marking the block invalid as this is more of a data issue from CL @@ -447,8 +447,8 @@ export class Engine { if (hardfork !== this.lastNewPayloadHF && this.lastNewPayloadHF !== '') { this.config.logger.info( `Hardfork change along new payload block number=${headBlock.header.number} hash=${short( - headBlock.hash() - )} old=${this.lastNewPayloadHF} new=${hardfork}` + headBlock.hash(), + )} old=${this.lastNewPayloadHF} new=${hardfork}`, ) } this.lastNewPayloadHF = hardfork @@ -474,7 +474,7 @@ export class Engine { } this.invalidBlocks.set( blockHash.slice(2), - new Error(response.validationError ?? 'Terminal block validation failed') + new Error(response.validationError ?? 'Terminal block validation failed'), ) return response } @@ -492,7 +492,7 @@ export class Engine { const latestValidHash = await validHash( hexToBytes(parentHash as PrefixedHexString), this.chain, - this.chainCache + this.chainCache, ) const response = { status: Status.INVALID, latestValidHash, validationError } // skip marking the block invalid as this is more of a data issue from CL @@ -546,17 +546,17 @@ export class Engine { // if the invalid block is canonical along the current chain return invalid const invalidBlock = await this.skeleton.getBlockByHash( this.execution.chainStatus.hash, - true + true, ) if (invalidBlock !== undefined) { // hard luck: block along canonical chain is invalid const latestValidHash = await validHash( invalidBlock.header.parentHash, this.chain, - this.chainCache + this.chainCache, ) const validationError = `Block number=${invalidBlock.header.number} hash=${short( - invalidBlock.hash() + invalidBlock.hash(), )} root=${short(invalidBlock.header.stateRoot)} along the canonical chain is invalid` const response = { @@ -633,10 +633,10 @@ export class Engine { const latestValidHash = await validHash( invalidBlock.header.parentHash, this.chain, - this.chainCache + this.chainCache, ) const validationError = `Block number=${invalidBlock.header.number} hash=${short( - invalidBlock.hash() + invalidBlock.hash(), )} root=${short(invalidBlock.header.stateRoot)} along the canonical chain is invalid` const response = { @@ -695,9 +695,9 @@ export class Engine { const blockParent = i > 0 ? blocks[i - 1] - : this.chainCache.remoteBlocks.get( - bytesToHex(block.header.parentHash).slice(2) - ) ?? (await this.chain.getBlock(block.header.parentHash)) + : (this.chainCache.remoteBlocks.get( + bytesToHex(block.header.parentHash).slice(2), + ) ?? (await this.chain.getBlock(block.header.parentHash))) const blockExecuted = await this.execution.runWithoutSetHead({ block, root: blockParent.header.stateRoot, @@ -711,12 +711,12 @@ export class Engine { if (!executed) { this.config.logger.debug( `Skipping block(s) execution for headBlock=${headBlock.header.number} hash=${short( - headBlock.hash() + headBlock.hash(), )} : pendingBlocks=${blocks.length - i}(limit=${ this.chain.config.engineNewpayloadMaxExecute }) transactions=${block.transactions.length}(limit=${ this.chain.config.engineNewpayloadMaxTxsExecute - }) executionBusy=${this.execution.running}` + }) executionBusy=${this.execution.running}`, ) // determind status to be returned depending on if block could extend chain or not const status = optimisticLookup === true ? Status.SYNCING : Status.ACCEPTED @@ -731,7 +731,7 @@ export class Engine { const latestValidHash = await validHash( headBlock.header.parentHash, this.chain, - this.chainCache + this.chainCache, ) const errorMsg = `${error}`.toLowerCase() @@ -922,7 +922,7 @@ export class Engine { * 3. headBlock: Block|undefined - Block corresponding to headBlockHash if found */ private async forkchoiceUpdated( - params: [forkchoiceState: ForkchoiceStateV1, payloadAttributes: PayloadAttributes | undefined] + params: [forkchoiceState: ForkchoiceStateV1, payloadAttributes: PayloadAttributes | undefined], ): Promise { const { headBlockHash, finalizedBlockHash, safeBlockHash } = params[0] const payloadAttributes = params[1] @@ -974,7 +974,7 @@ export class Engine { (await this.chain.getBlock(head)) } catch (error) { this.config.logger.debug( - `Forkchoice announced head block unknown to EL hash=${short(headBlockHash)}` + `Forkchoice announced head block unknown to EL hash=${short(headBlockHash)}`, ) const payloadStatus = { status: Status.SYNCING, @@ -993,7 +993,7 @@ export class Engine { this.config.logger.info( `Hardfork change along forkchoice head block update number=${ headBlock.header.number - } hash=${short(headBlock.hash())} old=${this.lastForkchoiceUpdatedHF} new=${hardfork}` + } hash=${short(headBlock.hash())} old=${this.lastForkchoiceUpdatedHF} new=${hardfork}`, ) } this.lastForkchoiceUpdatedHF = hardfork @@ -1002,8 +1002,8 @@ export class Engine { // requirements that might come later because of reorg or CL restarts this.config.logger.debug( `Forkchoice requested update to new head number=${headBlock.header.number} hash=${short( - headBlock.hash() - )}` + headBlock.hash(), + )}`, ) /** @@ -1064,17 +1064,17 @@ export class Engine { // see if the invalid block is canonical along the current skeleton/chain return invalid const invalidBlock = await this.skeleton.getBlockByHash( this.execution.chainStatus.hash, - true + true, ) if (invalidBlock !== undefined) { // hard luck: block along canonical chain is invalid const latestValidHash = await validHash( invalidBlock.header.parentHash, this.chain, - this.chainCache + this.chainCache, ) const validationError = `Block number=${invalidBlock.header.number} hash=${short( - invalidBlock.hash() + invalidBlock.hash(), )} root=${short(invalidBlock.header.stateRoot)} along the canonical chain is invalid` const payloadStatus = { @@ -1094,11 +1094,11 @@ export class Engine { ) { // jump the vm head to failing block so that next block can be executed this.config.logger.debug( - `Jumping the stalled vmHead forward to hash=${this.execution.chainStatus.hash} height=${this.execution.chainStatus.height} to continue the execution` + `Jumping the stalled vmHead forward to hash=${this.execution.chainStatus.hash} height=${this.execution.chainStatus.height} to continue the execution`, ) await this.execution.jumpVmHead( this.execution.chainStatus.hash, - this.execution.chainStatus.height + this.execution.chainStatus.height, ) } @@ -1129,7 +1129,7 @@ export class Engine { parentBlocks = await recursivelyFindParents( vmHeadHash, headBlock.header.parentHash, - this.chain + this.chain, ) } catch (error) { const payloadStatus = { @@ -1213,7 +1213,7 @@ export class Engine { coinbase: suggestedFeeRecipient, parentBeaconBlockRoot, }, - withdrawals + withdrawals, ) const latestValidHash = await validHash(headBlock.hash(), this.chain, this.chainCache) const payloadStatus = { status: Status.VALID, latestValidHash, validationError: null } @@ -1240,7 +1240,10 @@ export class Engine { * @returns */ private async forkchoiceUpdatedV1( - params: [forkchoiceState: ForkchoiceStateV1, payloadAttributes: PayloadAttributesV1 | undefined] + params: [ + forkchoiceState: ForkchoiceStateV1, + payloadAttributes: PayloadAttributesV1 | undefined, + ], ): Promise { const payloadAttributes = params[1] if (payloadAttributes !== undefined && payloadAttributes !== null) { @@ -1258,7 +1261,7 @@ export class Engine { 1, null, Hardfork.Paris, - BigInt(payloadAttributes.timestamp) + BigInt(payloadAttributes.timestamp), ) } @@ -1274,8 +1277,8 @@ export class Engine { private async forkchoiceUpdatedV2( params: [ forkchoiceState: ForkchoiceStateV1, - payloadAttributes: PayloadAttributesV1 | PayloadAttributesV2 | undefined - ] + payloadAttributes: PayloadAttributesV1 | PayloadAttributesV2 | undefined, + ], ): Promise { const payloadAttributes = params[1] if (payloadAttributes !== undefined && payloadAttributes !== null) { @@ -1294,7 +1297,7 @@ export class Engine { 2, null, Hardfork.Shanghai, - BigInt(payloadAttributes.timestamp) + BigInt(payloadAttributes.timestamp), ) const shanghaiTimestamp = this.chain.config.chainCommon.hardforkTimestamp(Hardfork.Shanghai) @@ -1335,7 +1338,10 @@ export class Engine { * @returns */ private async forkchoiceUpdatedV3( - params: [forkchoiceState: ForkchoiceStateV1, payloadAttributes: PayloadAttributesV3 | undefined] + params: [ + forkchoiceState: ForkchoiceStateV1, + payloadAttributes: PayloadAttributesV3 | undefined, + ], ): Promise { const payloadAttributes = params[1] if (payloadAttributes !== undefined && payloadAttributes !== null) { @@ -1355,7 +1361,7 @@ export class Engine { Hardfork.Cancun, // this could be valid post cancun as well, if not then update the valid till hf here null, - BigInt(payloadAttributes.timestamp) + BigInt(payloadAttributes.timestamp), ) } @@ -1432,7 +1438,7 @@ export class Engine { payloadVersion, checkNotBeforeHf, checkNotAfterHf, - BigInt(executionPayload.executionPayload.timestamp) + BigInt(executionPayload.executionPayload.timestamp), ) return executionPayload } catch (error: any) { @@ -1492,7 +1498,7 @@ export class Engine { * @returns Instance of {@link TransitionConfigurationV1} or an error */ async exchangeTransitionConfigurationV1( - params: [TransitionConfigurationV1] + params: [TransitionConfigurationV1], ): Promise { const { terminalTotalDifficulty, terminalBlockHash, terminalBlockNumber } = params[0] const ttd = this.chain.config.chainCommon.hardforkTTD(Hardfork.Paris) @@ -1506,7 +1512,7 @@ export class Engine { throw { code: INVALID_PARAMS, message: `terminalTotalDifficulty set to ${ttd}, received ${parseInt( - terminalTotalDifficulty + terminalTotalDifficulty, )}`, } } @@ -1535,7 +1541,7 @@ export class Engine { * @returns an array of ExecutionPayloadBodyV1 objects or null if a given execution payload isn't stored locally */ private async getPayloadBodiesByHashV1( - params: [[Bytes32]] + params: [[Bytes32]], ): Promise<(ExecutionPayloadBodyV1 | null)[]> { if (params[0].length > 32) { throw { @@ -1567,7 +1573,7 @@ export class Engine { * @returns an array of ExecutionPayloadBodyV1 objects or null if a given execution payload isn't stored locally */ private async getPayloadBodiesByRangeV1( - params: [Bytes8, Bytes8] + params: [Bytes8, Bytes8], ): Promise<(ExecutionPayloadBodyV1 | null)[]> { const start = BigInt(params[0]) let count = BigInt(params[1]) diff --git a/packages/client/src/rpc/modules/engine/util/generic.ts b/packages/client/src/rpc/modules/engine/util/generic.ts index f36d5805c8..618e06434d 100644 --- a/packages/client/src/rpc/modules/engine/util/generic.ts +++ b/packages/client/src/rpc/modules/engine/util/generic.ts @@ -15,7 +15,7 @@ import type { PrefixedHexString } from '@ethereumjs/util' export const recursivelyFindParents = async ( vmHeadHash: Uint8Array, parentHash: Uint8Array, - chain: Chain + chain: Chain, ) => { if (equalsBytes(parentHash, vmHeadHash) || equalsBytes(parentHash, new Uint8Array(32))) { return [] @@ -28,7 +28,7 @@ export const recursivelyFindParents = async ( while (!equalsBytes(parentBlocks[parentBlocks.length - 1].hash(), vmHeadHash)) { const block: Block = await chain.getBlock( - parentBlocks[parentBlocks.length - 1].header.parentHash + parentBlocks[parentBlocks.length - 1].header.parentHash, ) parentBlocks.push(block) @@ -50,7 +50,7 @@ export const recursivelyFindParents = async ( */ export const validExecutedChainBlock = async ( blockOrHash: Uint8Array | Block, - chain: Chain + chain: Chain, ): Promise => { try { const block = blockOrHash instanceof Block ? blockOrHash : await chain.getBlock(blockOrHash) @@ -77,7 +77,7 @@ export const validExecutedChainBlock = async ( export const validHash = async ( hash: Uint8Array, chain: Chain, - chainCache: ChainCache + chainCache: ChainCache, ): Promise => { const { remoteBlocks, executedBlocks, invalidBlocks, skeleton } = chainCache const maxDepth = chain.config.engineParentLookupMaxDepth @@ -136,7 +136,7 @@ export function validateHardforkRange( methodVersion: number, checkNotBeforeHf: Hardfork | null, checkNotAfterHf: Hardfork | null, - timestamp: bigint + timestamp: bigint, ) { if (checkNotBeforeHf !== null) { const hfTimeStamp = chainCommon.hardforkTimestamp(checkNotBeforeHf) diff --git a/packages/client/src/rpc/modules/engine/util/newPayload.ts b/packages/client/src/rpc/modules/engine/util/newPayload.ts index f566fb2361..efe07b16c4 100644 --- a/packages/client/src/rpc/modules/engine/util/newPayload.ts +++ b/packages/client/src/rpc/modules/engine/util/newPayload.ts @@ -20,7 +20,7 @@ import type { PrefixedHexString } from '@ethereumjs/util' export const assembleBlock = async ( payload: ExecutionPayload, chain: Chain, - chainCache: ChainCache + chainCache: ChainCache, ): Promise<{ block?: Block; error?: PayloadStatusV1 }> => { const { blockNumber, timestamp } = payload const { config } = chain @@ -44,7 +44,7 @@ export const assembleBlock = async ( const latestValidHash = await validHash( hexToBytes(payload.parentHash as PrefixedHexString), chain, - chainCache + chainCache, ) const response = { status: `${error}`.includes('Invalid blockHash') ? Status.INVALID_BLOCK_HASH : Status.INVALID, @@ -57,7 +57,7 @@ export const assembleBlock = async ( export const validate4844BlobVersionedHashes = ( headBlock: Block, - blobVersionedHashes: PrefixedHexString[] + blobVersionedHashes: PrefixedHexString[], ): string | null => { let validationError: string | null = null @@ -79,7 +79,7 @@ export const validate4844BlobVersionedHashes = ( // if mismatch, record error and break if (!equalsBytes(hexToBytes(blobVersionedHashes[vIndex]), txVersionedHashes[vIndex])) { validationError = `Error verifying blobVersionedHashes: mismatch at index=${vIndex} expected=${short( - txVersionedHashes[vIndex] + txVersionedHashes[vIndex], )} received=${short(blobVersionedHashes[vIndex])}` break } diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 9afdf2c69b..afb2a8ca51 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -108,12 +108,12 @@ type JsonRpcLog = { const jsonRpcBlock = async ( block: Block, chain: Chain, - includeTransactions: boolean + includeTransactions: boolean, ): Promise => { const json = block.toJSON() const header = json!.header! const transactions = block.transactions.map((tx, txIndex) => - includeTransactions ? jsonRpcTx(tx, block, txIndex) : bytesToHex(tx.hash()) + includeTransactions ? jsonRpcTx(tx, block, txIndex) : bytesToHex(tx.hash()), ) const withdrawalsAttr = header.withdrawalsRoot !== undefined @@ -162,7 +162,7 @@ const jsonRpcLog = async ( block?: Block, tx?: TypedTransaction, txIndex?: number, - logIndex?: number + logIndex?: number, ): Promise => ({ removed: false, // TODO implement logIndex: logIndex !== undefined ? intToHex(logIndex) : null, @@ -188,7 +188,7 @@ const jsonRpcReceipt = async ( logIndex: number, contractAddress?: Address, blobGasUsed?: bigint, - blobGasPrice?: bigint + blobGasPrice?: bigint, ): Promise => ({ transactionHash: bytesToHex(tx.hash()), transactionIndex: intToHex(txIndex), @@ -201,7 +201,7 @@ const jsonRpcReceipt = async ( gasUsed: bigIntToHex(gasUsed), contractAddress: contractAddress?.toString() ?? null, logs: await Promise.all( - receipt.logs.map((l, i) => jsonRpcLog(l, block, tx, txIndex, logIndex + i)) + receipt.logs.map((l, i) => jsonRpcLog(l, block, tx, txIndex, logIndex + i)), ), logsBloom: bytesToHex(receipt.bitvector), root: @@ -220,7 +220,7 @@ const jsonRpcReceipt = async ( const calculateRewards = async ( block: Block, receiptsManager: ReceiptsManager, - priorityFeePercentiles: number[] + priorityFeePercentiles: number[], ) => { if (priorityFeePercentiles.length === 0) { return [] @@ -315,7 +315,7 @@ export class Eth { this.blockNumber = middleware( callWithStackTrace(this.blockNumber.bind(this), this._rpcDebug), - 0 + 0, ) this.call = middleware(callWithStackTrace(this.call.bind(this), this._rpcDebug), 2, [ @@ -328,13 +328,13 @@ export class Eth { this.estimateGas = middleware( callWithStackTrace(this.estimateGas.bind(this), this._rpcDebug), 1, - [[validators.transaction()], [validators.blockOption]] + [[validators.transaction()], [validators.blockOption]], ) this.getBalance = middleware( callWithStackTrace(this.getBalance.bind(this), this._rpcDebug), 2, - [[validators.address], [validators.blockOption]] + [[validators.address], [validators.blockOption]], ) this.coinbase = middleware(callWithStackTrace(this.coinbase.bind(this), this._rpcDebug), 0, []) @@ -342,19 +342,19 @@ export class Eth { this.getBlockByNumber = middleware( callWithStackTrace(this.getBlockByNumber.bind(this), this._rpcDebug), 2, - [[validators.blockOption], [validators.bool]] + [[validators.blockOption], [validators.bool]], ) this.getBlockByHash = middleware( callWithStackTrace(this.getBlockByHash.bind(this), this._rpcDebug), 2, - [[validators.hex, validators.blockHash], [validators.bool]] + [[validators.hex, validators.blockHash], [validators.bool]], ) this.getBlockTransactionCountByHash = middleware( callWithStackTrace(this.getBlockTransactionCountByHash.bind(this), this._rpcDebug), 1, - [[validators.hex, validators.blockHash]] + [[validators.hex, validators.blockHash]], ) this.getCode = middleware(callWithStackTrace(this.getCode.bind(this), this._rpcDebug), 2, [ @@ -365,54 +365,54 @@ export class Eth { this.getUncleCountByBlockNumber = middleware( callWithStackTrace(this.getUncleCountByBlockNumber.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.getStorageAt = middleware( callWithStackTrace(this.getStorageAt.bind(this), this._rpcDebug), 3, - [[validators.address], [validators.hex], [validators.blockOption]] + [[validators.address], [validators.hex], [validators.blockOption]], ) this.getTransactionByBlockHashAndIndex = middleware( callWithStackTrace(this.getTransactionByBlockHashAndIndex.bind(this), this._rpcDebug), 2, - [[validators.hex, validators.blockHash], [validators.hex]] + [[validators.hex, validators.blockHash], [validators.hex]], ) this.getTransactionByBlockNumberAndIndex = middleware( callWithStackTrace(this.getTransactionByBlockNumberAndIndex.bind(this), this._rpcDebug), 2, - [[validators.hex, validators.blockOption], [validators.hex]] + [[validators.hex, validators.blockOption], [validators.hex]], ) this.getTransactionByHash = middleware( callWithStackTrace(this.getTransactionByHash.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.getTransactionCount = middleware( callWithStackTrace(this.getTransactionCount.bind(this), this._rpcDebug), 2, - [[validators.address], [validators.blockOption]] + [[validators.address], [validators.blockOption]], ) this.getBlockReceipts = middleware( callWithStackTrace(this.getBlockReceipts.bind(this), this._rpcDebug), 1, - [[validators.blockOption]] + [[validators.blockOption]], ) this.getTransactionReceipt = middleware( callWithStackTrace(this.getTransactionReceipt.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.getUncleCountByBlockNumber = middleware( callWithStackTrace(this.getUncleCountByBlockNumber.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.getLogs = middleware(callWithStackTrace(this.getLogs.bind(this), this._rpcDebug), 1, [ @@ -421,14 +421,14 @@ export class Eth { fromBlock: validators.optional(validators.blockOption), toBlock: validators.optional(validators.blockOption), address: validators.optional( - validators.either(validators.array(validators.address), validators.address) + validators.either(validators.array(validators.address), validators.address), ), topics: validators.optional( validators.array( validators.optional( - validators.either(validators.hex, validators.array(validators.hex)) - ) - ) + validators.either(validators.hex, validators.array(validators.hex)), + ), + ), ), blockHash: validators.optional(validators.blockHash), }), @@ -438,13 +438,13 @@ export class Eth { this.sendRawTransaction = middleware( callWithStackTrace(this.sendRawTransaction.bind(this), this._rpcDebug), 1, - [[validators.hex]] + [[validators.hex]], ) this.protocolVersion = middleware( callWithStackTrace(this.protocolVersion.bind(this), this._rpcDebug), 0, - [] + [], ) this.syncing = middleware(callWithStackTrace(this.syncing.bind(this), this._rpcDebug), 0, []) @@ -458,7 +458,7 @@ export class Eth { this.getBlockTransactionCountByNumber = middleware( callWithStackTrace(this.getBlockTransactionCountByNumber.bind(this), this._rpcDebug), 1, - [[validators.blockOption]] + [[validators.blockOption]], ) this.gasPrice = middleware(callWithStackTrace(this.gasPrice.bind(this), this._rpcDebug), 0, []) @@ -470,13 +470,13 @@ export class Eth { [validators.either(validators.hex, validators.integer)], [validators.either(validators.hex, validators.blockOption)], [validators.rewardPercentiles], - ] + ], ) this.blobBaseFee = middleware( callWithStackTrace(this.blobBaseFee.bind(this), this._rpcDebug), 0, - [] + [], ) } @@ -596,7 +596,7 @@ export class Eth { : undefined, }, }, - { common: vm.common, setHardfork: true } + { common: vm.common, setHardfork: true }, ) vm.common.setHardforkBy({ @@ -886,7 +886,7 @@ export class Eth { // Add pending txns to nonce if blockOpt is 'pending' if (blockOpt === 'pending') { pendingTxsCount = BigInt( - (this.service as FullEthereumService).txPool.pool.get(addressHex.slice(2))?.length ?? 0 + (this.service as FullEthereumService).txPool.pool.get(addressHex.slice(2))?.length ?? 0, ) } return bigIntToHex(account.nonce + pendingTxsCount) @@ -973,9 +973,9 @@ export class Eth { i, createdAddress, blobGasUsed, - blobGasPrice + blobGasPrice, ) - }) + }), ) return receipts } @@ -1035,7 +1035,7 @@ export class Eth { logIndex, createdAddress, blobGasUsed, - blobGasPrice + blobGasPrice, ) } @@ -1124,8 +1124,8 @@ export class Eth { const logs = await this.receiptsManager.getLogs(from, to, addressBytes, formattedTopics) return Promise.all( logs.map(({ log, block, tx, txIndex, logIndex }) => - jsonRpcLog(log, block, tx, txIndex, logIndex) - ) + jsonRpcLog(log, block, tx, txIndex, logIndex), + ), ) } @@ -1171,7 +1171,7 @@ export class Eth { throw Error( `tx blobs=${(tx.blobs ?? []).length} exceeds block limit=${ blobGasLimit / blobGasPerBlob - }` + }`, ) } } else { @@ -1229,7 +1229,7 @@ export class Eth { * @returns The {@link Proof} */ async getProof( - params: [PrefixedHexString, PrefixedHexString[], PrefixedHexString] + params: [PrefixedHexString, PrefixedHexString[], PrefixedHexString], ): Promise { const [addressHex, slotsHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) @@ -1386,11 +1386,11 @@ export class Eth { const requestedBlockNumbers = Array.from( { length: Number(blockCount) }, - (_, i) => oldestBlockNumber + BigInt(i) + (_, i) => oldestBlockNumber + BigInt(i), ) const requestedBlocks = await Promise.all( - requestedBlockNumbers.map((n) => getBlockByOption(n.toString(), this._chain)) + requestedBlockNumbers.map((n) => getBlockByOption(n.toString(), this._chain)), ) const [baseFees, gasUsedRatios, baseFeePerBlobGas, blobGasUsedRatio] = requestedBlocks.reduce( @@ -1414,7 +1414,7 @@ export class Eth { return [prevBaseFees, prevGasUsedRatios, prevBaseFeesPerBlobGas, prevBlobGasUsedRatio] }, - [[], [], [], []] as [bigint[], number[], bigint[], number[]] + [[], [], [], []] as [bigint[], number[], bigint[], number[]], ) const londonHardforkBlockNumber = this._chain.blockchain.common.hardforkBlock(Hardfork.London)! @@ -1426,7 +1426,7 @@ export class Eth { if (this._chain.blockchain.common.isActivatedEIP(4844)) { baseFeePerBlobGas.push( - requestedBlocks[requestedBlocks.length - 1].header.calcNextBlobGasPrice() + requestedBlocks[requestedBlocks.length - 1].header.calcNextBlobGasPrice(), ) } else { // TODO (?): known bug @@ -1440,8 +1440,8 @@ export class Eth { if (this.receiptsManager && priorityFeePercentiles) { rewards = await Promise.all( requestedBlocks.map((b) => - calculateRewards(b, this.receiptsManager!, priorityFeePercentiles) - ) + calculateRewards(b, this.receiptsManager!, priorityFeePercentiles), + ), ) } diff --git a/packages/client/src/rpc/modules/net.ts b/packages/client/src/rpc/modules/net.ts index 54639921af..f53c10ca5f 100644 --- a/packages/client/src/rpc/modules/net.ts +++ b/packages/client/src/rpc/modules/net.ts @@ -33,12 +33,12 @@ export class Net { this.listening = middleware( callWithStackTrace(this.listening.bind(this), this._rpcDebug), 0, - [] + [], ) this.peerCount = middleware( callWithStackTrace(this.peerCount.bind(this), this._rpcDebug), 0, - [] + [], ) } diff --git a/packages/client/src/rpc/validation.ts b/packages/client/src/rpc/validation.ts index af2e2f30fe..4b150cdc85 100644 --- a/packages/client/src/rpc/validation.ts +++ b/packages/client/src/rpc/validation.ts @@ -11,7 +11,7 @@ export function middleware( method: any, requiredParamsCount: number, validators: any[] = [], - names: string[] = [] + names: string[] = [], ): any { return function (params: any[] = []) { return new Promise((resolve, reject) => { @@ -430,7 +430,13 @@ export const validators = { get depositRequest() { return ( - requiredFields: string[] = ['pubkey', 'withdrawalCredentials', 'amount', 'signature', 'index'] + requiredFields: string[] = [ + 'pubkey', + 'withdrawalCredentials', + 'amount', + 'signature', + 'index', + ], ) => { return (params: any[], index: number) => { if (typeof params[index] !== 'object') { diff --git a/packages/client/src/service/fullethereumservice.ts b/packages/client/src/service/fullethereumservice.ts index 94268bd9d4..684398ee3a 100644 --- a/packages/client/src/service/fullethereumservice.ts +++ b/packages/client/src/service/fullethereumservice.ts @@ -159,7 +159,7 @@ export class FullEthereumService extends Service { this.synchronizer instanceof BeaconSynchronizer ? 'BeaconSynchronizer' : 'FullSynchronizer' - }.` + }.`, ) } else { this.config.logger.info('Starting FullEthereumService with no syncing.') @@ -197,13 +197,13 @@ export class FullEthereumService extends Service { throw Error(`Currently stateful verkle execution not supported`) } this.execution.config.logger.info( - `Skipping VM verkle statemanager genesis hardfork=${this.execution.hardfork}` + `Skipping VM verkle statemanager genesis hardfork=${this.execution.hardfork}`, ) await this.execution.setupVerkleVM() this.execution.vm = this.execution.verkleVM! } else { this.execution.config.logger.info( - `Initializing VM merkle statemanager genesis hardfork=${this.execution.hardfork}` + `Initializing VM merkle statemanager genesis hardfork=${this.execution.hardfork}`, ) await this.execution.setupMerkleVM() this.execution.vm = this.execution.merkleVM! @@ -262,12 +262,12 @@ export class FullEthereumService extends Service { } } else { this.config.logger.debug( - `skipping snapsync since cl (skeleton) synchronized=${this.skeleton?.synchronized}` + `skipping snapsync since cl (skeleton) synchronized=${this.skeleton?.synchronized}`, ) } } else { this.config.logger.warn( - 'skipping building head state as neither execution is started nor snapsync is available' + 'skipping building head state as neither execution is started nor snapsync is available', ) } } catch (error) { @@ -329,7 +329,7 @@ export class FullEthereumService extends Service { chain: this.chain, flow: this.flow, timeout: this.timeout, - }) + }), ) } return protocols @@ -379,7 +379,7 @@ export class FullEthereumService extends Service { case 'GetBlockBodies': { const { reqId, hashes } = message.data const blocks: Block[] = await Promise.all( - hashes.map((hash: Uint8Array) => this.chain.getBlock(hash)) + hashes.map((hash: Uint8Array) => this.chain.getBlock(hash)), ) const bodies = blocks.map((block) => block.raw().slice(1)) peer.eth!.send('BlockBodies', { reqId, bodies }) @@ -388,7 +388,7 @@ export class FullEthereumService extends Service { case 'NewBlockHashes': { if (this.config.chainCommon.gteHardfork(Hardfork.Paris)) { this.config.logger.debug( - `Dropping peer ${peer.id} for sending NewBlockHashes after merge (EIP-3675)` + `Dropping peer ${peer.id} for sending NewBlockHashes after merge (EIP-3675)`, ) this.pool.ban(peer, 9000000) } else if (this.synchronizer instanceof FullSynchronizer) { @@ -403,7 +403,7 @@ export class FullEthereumService extends Service { case 'NewBlock': { if (this.config.chainCommon.gteHardfork(Hardfork.Paris)) { this.config.logger.debug( - `Dropping peer ${peer.id} for sending NewBlock after merge (EIP-3675)` + `Dropping peer ${peer.id} for sending NewBlock after merge (EIP-3675)`, ) this.pool.ban(peer, 9000000) } else if (this.synchronizer instanceof FullSynchronizer) { diff --git a/packages/client/src/service/service.ts b/packages/client/src/service/service.ts index aa1a9da8d3..5b9aee525a 100644 --- a/packages/client/src/service/service.ts +++ b/packages/client/src/service/service.ts @@ -86,7 +86,7 @@ export class Service { await this.handle(message, protocol, peer) } catch (error: any) { this.config.logger.debug( - `Error handling message (${protocol}:${message.name}): ${error.message}` + `Error handling message (${protocol}:${message.name}): ${error.message}`, ) } } @@ -126,13 +126,13 @@ export class Service { this.config.server && this.config.server.addProtocols(protocols) this.config.events.on(Event.POOL_PEER_BANNED, (peer) => - this.config.logger.debug(`Peer banned: ${peer}`) + this.config.logger.debug(`Peer banned: ${peer}`), ) this.config.events.on(Event.POOL_PEER_ADDED, (peer) => - this.config.logger.debug(`Peer added: ${peer}`) + this.config.logger.debug(`Peer added: ${peer}`), ) this.config.events.on(Event.POOL_PEER_REMOVED, (peer) => - this.config.logger.debug(`Peer removed: ${peer}`) + this.config.logger.debug(`Peer removed: ${peer}`), ) await this.pool.open() @@ -168,7 +168,7 @@ export class Service { this._statsInterval = setInterval( // eslint-disable-next-line @typescript-eslint/await-thenable await this.stats.bind(this), - this.STATS_INTERVAL + this.STATS_INTERVAL, ) this.running = true this.config.logger.info(`Started ${this.name} service.`) diff --git a/packages/client/src/service/skeleton.ts b/packages/client/src/service/skeleton.ts index e31815d85c..346dfe407e 100644 --- a/packages/client/src/service/skeleton.ts +++ b/packages/client/src/service/skeleton.ts @@ -216,7 +216,7 @@ export class Skeleton extends MetaDBManager { this.config.logger.debug( `Canonical subchain linked with main, removing junked chains ${junkedSubChains .map((s) => `[tail=${s.tail} head=${s.head} next=${short(s.next)}]`) - .join(',')}` + .join(',')}`, ) await this.writeSyncStatus() } @@ -262,7 +262,7 @@ export class Skeleton extends MetaDBManager { } lastchain.head = headBlock.header.number this.config.logger.debug( - `lastchain head fast forwarded from=${head} to=${lastchain.head} tail=${lastchain.tail}` + `lastchain head fast forwarded from=${head} to=${lastchain.head} tail=${lastchain.tail}`, ) } @@ -282,8 +282,8 @@ export class Skeleton extends MetaDBManager { if (!equalsBytes(this.chain.genesis.hash(), head.hash())) { throw Error( `Invalid genesis setHead announcement number=${number} hash=${short( - head.hash() - )} genesisHash=${short(this.chain.genesis.hash())}` + head.hash(), + )} genesisHash=${short(this.chain.genesis.hash())}`, ) } // genesis announcement @@ -302,14 +302,14 @@ export class Skeleton extends MetaDBManager { // Not a noop / double head announce, abort with a reorg if (force) { this.config.logger.warn( - `Skeleton setHead before tail, resetting skeleton tail=${lastchain.tail} head=${lastchain.head} newHead=${number}` + `Skeleton setHead before tail, resetting skeleton tail=${lastchain.tail} head=${lastchain.head} newHead=${number}`, ) lastchain.head = number lastchain.tail = number lastchain.next = head.header.parentHash } else { this.config.logger.debug( - `Skeleton announcement before tail, will reset skeleton tail=${lastchain.tail} head=${lastchain.head} newHead=${number}` + `Skeleton announcement before tail, will reset skeleton tail=${lastchain.tail} head=${lastchain.head} newHead=${number}`, ) } return true @@ -321,7 +321,7 @@ export class Skeleton extends MetaDBManager { this.config.logger.debug( `Skeleton duplicate ${force ? 'setHead' : 'announcement'} tail=${lastchain.tail} head=${ lastchain.head - } number=${number} hash=${short(head.hash())}` + } number=${number} hash=${short(head.hash())}`, ) return false } else { @@ -332,12 +332,12 @@ export class Skeleton extends MetaDBManager { `Skeleton head reorg tail=${lastchain.tail} head=${ lastchain.head } number=${number} expected=${short( - mayBeDupBlock?.hash() ?? zeroBlockHash - )} actual=${short(head.hash())}` + mayBeDupBlock?.hash() ?? zeroBlockHash, + )} actual=${short(head.hash())}`, ) } else { this.config.logger.debug( - `Skeleton differing announcement tail=${lastchain.tail} head=${lastchain.head} number=${number}` + `Skeleton differing announcement tail=${lastchain.tail} head=${lastchain.head} number=${number}`, ) } return true @@ -348,13 +348,13 @@ export class Skeleton extends MetaDBManager { // If its still less than number then its gapped head if (lastchain.head + BIGINT_1 < number) { this.config.logger.debug( - `Beacon chain gapped setHead head=${lastchain.head} newHead=${number}` + `Beacon chain gapped setHead head=${lastchain.head} newHead=${number}`, ) return true } } else { this.config.logger.debug( - `Beacon chain gapped announcement head=${lastchain.head} newHead=${number}` + `Beacon chain gapped announcement head=${lastchain.head} newHead=${number}`, ) return true } @@ -364,8 +364,8 @@ export class Skeleton extends MetaDBManager { if (force) { this.config.logger.warn( `Beacon chain forked ancestor=${parent?.header.number} hash=${short( - parent?.hash() ?? 'NA' - )} want=${short(head.header.parentHash)}` + parent?.hash() ?? 'NA', + )} want=${short(head.header.parentHash)}`, ) } return true @@ -380,8 +380,8 @@ export class Skeleton extends MetaDBManager { } this.config.logger.debug( `Beacon chain extended new head=${lastchain.head} tail=${lastchain.tail} next=${short( - lastchain.next - )}` + lastchain.next, + )}`, ) } return false @@ -415,8 +415,8 @@ export class Skeleton extends MetaDBManager { this.config.logger.debug( `New skeleton head announced number=${head.header.number} hash=${short( - head.hash() - )} force=${force}` + head.hash(), + )} force=${force}`, ) let [lastchain] = this.status.progress.subchains @@ -432,7 +432,7 @@ export class Skeleton extends MetaDBManager { this.config.logger.debug( `Initing empty skeleton with current chain head tail=${lastchain.tail} head=${ lastchain.head - } next=${short(lastchain.next)}` + } next=${short(lastchain.next)}`, ) this.status.progress.subchains.push(lastchain) } @@ -473,12 +473,12 @@ export class Skeleton extends MetaDBManager { this.config.logger.info( `Truncated subchain0 with head=${subchain.head} to a new tail=${ subchain.tail - } next=${short(subchain.next)} before overlaying a new subchain` + } next=${short(subchain.next)} before overlaying a new subchain`, ) } else { // clear out this subchain this.config.logger.info( - `Dropping subchain0 with head=${subchain.head} before overlaying a new subchain as trucateTailToNumber=${trucateTailToNumber} block not available ` + `Dropping subchain0 with head=${subchain.head} before overlaying a new subchain as trucateTailToNumber=${trucateTailToNumber} block not available `, ) this.status.progress.subchains.splice(0, 1) } @@ -531,7 +531,7 @@ export class Skeleton extends MetaDBManager { subchain.tail } next=${short(subchain.next)} linked=${this.status.linked} canonicalHeadReset=${ this.status.canonicalHeadReset - }` + }`, ) } else { subchain.tail = trucateTailTo.header.number @@ -542,7 +542,7 @@ export class Skeleton extends MetaDBManager { subchain.tail } next=${short(subchain.next)} linked=${this.status.linked} canonicalHeadReset=${ this.status.canonicalHeadReset - }` + }`, ) } } @@ -617,7 +617,7 @@ export class Skeleton extends MetaDBManager { this.synchronized = true // Log to console the sync status this.config.superMsg( - `Synchronized cl (skeleton) at height=${height} hash=${short(latest.hash())} 🎉` + `Synchronized cl (skeleton) at height=${height} hash=${short(latest.hash())} 🎉`, ) } } @@ -629,8 +629,8 @@ export class Skeleton extends MetaDBManager { this.synchronized = false this.config.logger.info( `Cl (skeleton) sync status reset (no chain updates for ${Math.round( - diff / 1000 - )} seconds).` + diff / 1000, + )} seconds).`, ) } } @@ -642,7 +642,7 @@ export class Skeleton extends MetaDBManager { latest !== null && latest !== undefined ? ' height=' + latest.number : '' } syncTargetHeight=${this.config.syncTargetHeight} lastSyncDate=${ (Date.now() - this.lastSyncDate) / 1000 - } secs ago` + } secs ago`, ) this.lastsyncronized = this.synchronized } @@ -653,7 +653,7 @@ export class Skeleton extends MetaDBManager { { safeBlockHash, finalizedBlockHash, - }: { safeBlockHash?: Uint8Array; finalizedBlockHash?: Uint8Array } = {} + }: { safeBlockHash?: Uint8Array; finalizedBlockHash?: Uint8Array } = {}, ): Promise<{ reorged: boolean; safeBlock?: Block; finalizedBlock?: Block }> { // setHead locks independently and between setHead unlocking and locking below there should // be no injected code as each of the async ops take the lock. so once setHead takes the @@ -665,7 +665,7 @@ export class Skeleton extends MetaDBManager { await this.blockingTailBackfillWithCutoff(this.chain.config.engineParentLookupMaxDepth).catch( (e) => { this.config.logger.debug(`blockingTailBackfillWithCutoff exited with error=${e}`) - } + }, ) } @@ -816,7 +816,7 @@ export class Skeleton extends MetaDBManager { return this.runWithLock(async () => { // check if the synced state's block is canonical and <= current safe and chain has synced till const syncedBlock = await this.getBlock( - syncedHeight + syncedHeight, // need to debug why this flag causes to return undefined when chain gets synced //, true ) @@ -883,7 +883,7 @@ export class Skeleton extends MetaDBManager { if (tail >= this.status.progress.subchains[0].tail) { // Fully overwritten, get rid of the subchain as a whole this.config.logger.debug( - `Previous subchain fully overwritten tail=${tail} head=${head} next=${short(next)}` + `Previous subchain fully overwritten tail=${tail} head=${head} next=${short(next)}`, ) this.status.progress.subchains.splice(1, 1) edited = true @@ -893,8 +893,8 @@ export class Skeleton extends MetaDBManager { this.status.progress.subchains[1].head = this.status.progress.subchains[0].tail - BIGINT_1 this.config.logger.debug( `Previous subchain partially overwritten tail=${tail} head=${head} next=${short( - next - )} with newHead=${this.status.progress.subchains[1].head}` + next, + )} with newHead=${this.status.progress.subchains[1].head}`, ) edited = true } @@ -913,7 +913,7 @@ export class Skeleton extends MetaDBManager { // if subChain1Head is not in the skeleton then all previous subchains are not useful // and better to junk this.config.logger.debug( - `Removing all previous subchains as skeleton missing block at previous subchain head=${this.status.progress.subchains[1].head} or its tail=${this.status.progress.subchains[1].tail}` + `Removing all previous subchains as skeleton missing block at previous subchain head=${this.status.progress.subchains[1].head} or its tail=${this.status.progress.subchains[1].tail}`, ) this.status.progress.subchains.splice(1, this.status.progress.subchains.length - 1) } else if ( @@ -923,7 +923,7 @@ export class Skeleton extends MetaDBManager { // to disruption of the block fetcher to start a fresh if (head - tail > this.config.skeletonSubchainMergeMinimum) { this.config.logger.debug( - `Previous subchain merged tail=${tail} head=${head} next=${short(next)}` + `Previous subchain merged tail=${tail} head=${head} next=${short(next)}`, ) this.status.progress.subchains[0].tail = tail this.status.progress.subchains[0].next = next @@ -933,7 +933,7 @@ export class Skeleton extends MetaDBManager { merged = true } else { this.config.logger.debug( - `Subchain ignored for merge tail=${tail} head=${head} count=${head - tail}` + `Subchain ignored for merge tail=${tail} head=${head} count=${head - tail}`, ) this.status.progress.subchains.splice(1, 1) } @@ -962,12 +962,12 @@ export class Skeleton extends MetaDBManager { let tailUpdated = false this.config.logger.debug( `Skeleton putBlocks start=${blocks[0]?.header.number} hash=${short( - blocks[0]?.hash() + blocks[0]?.hash(), )} fork=${blocks[0].common.hardfork()} end=${ blocks[blocks.length - 1]?.header.number } count=${blocks.length}, subchain head=${this.status.progress.subchains[0]?.head} tail = ${ this.status.progress.subchains[0].tail - } next=${short(this.status.progress.subchains[0]?.next)}` + } next=${short(this.status.progress.subchains[0]?.next)}`, ) for (const block of blocks) { const { number } = block.header @@ -979,8 +979,8 @@ export class Skeleton extends MetaDBManager { if (!equalsBytes(this.chain.genesis.hash(), block.hash())) { throw Error( `Skeleton pubBlocks with invalid genesis block number=${number} hash=${short( - block.hash() - )} genesisHash=${short(this.chain.genesis.hash())}` + block.hash(), + )} genesisHash=${short(this.chain.genesis.hash())}`, ) } continue @@ -1003,12 +1003,12 @@ export class Skeleton extends MetaDBManager { `Blocks don't extend canonical subchain tail=${ this.status.progress.subchains[0].tail } head=${this.status.progress.subchains[0].head} next=${short( - this.status.progress.subchains[0].next + this.status.progress.subchains[0].next, )} tailHash=${short( - tailBlock?.hash() ?? zeroBlockHash + tailBlock?.hash() ?? zeroBlockHash, )} tailFork=${tailBlock?.common.hardfork()}, block number=${number} tailparent=${short( - tailBlock?.header.parentHash ?? zeroBlockHash - )} hash=${short(block.hash())} fork=${block.common.hardfork()}` + tailBlock?.header.parentHash ?? zeroBlockHash, + )} hash=${short(block.hash())} fork=${block.common.hardfork()}`, ) throw Error(`Blocks don't extend canonical subchain`) } @@ -1035,7 +1035,7 @@ export class Skeleton extends MetaDBManager { // If the sync is finished, start filling the canonical chain. if (this.status.linked) { this.config.superMsg( - `Backfilling subchain completed, filling canonical chain=${!skipForwardFill}` + `Backfilling subchain completed, filling canonical chain=${!skipForwardFill}`, ) if (!skipForwardFill) { void this.fillCanonicalChain() @@ -1075,7 +1075,7 @@ export class Skeleton extends MetaDBManager { this.status.progress.subchains = [] await this.writeSyncStatus() this.config.logger.warn( - `Couldn't backStep subchain 0, dropping subchains for new head signal` + `Couldn't backStep subchain 0, dropping subchains for new head signal`, ) return null } @@ -1168,7 +1168,7 @@ export class Skeleton extends MetaDBManager { if (this.status.canonicalHeadReset) { if (subchain.tail > canonicalHead + BIGINT_1) { throw Error( - `Canonical head should already be on or ahead subchain tail canonicalHead=${canonicalHead} tail=${subchain.tail}` + `Canonical head should already be on or ahead subchain tail canonicalHead=${canonicalHead} tail=${subchain.tail}`, ) } let newHead = subchain.tail - BIGINT_1 @@ -1178,7 +1178,7 @@ export class Skeleton extends MetaDBManager { if (canonicalHead > BIGINT_0) { this.config.logger.debug( - `Resetting canonicalHead for fillCanonicalChain from=${canonicalHead} to=${newHead}` + `Resetting canonicalHead for fillCanonicalChain from=${canonicalHead} to=${newHead}`, ) canonicalHead = newHead await this.chain.resetCanonicalHead(canonicalHead) @@ -1192,7 +1192,7 @@ export class Skeleton extends MetaDBManager { const start = canonicalHead // This subchain is a reference to update the tail for the very subchain we are filling the data for this.config.logger.debug( - `Starting canonical chain fill canonicalHead=${canonicalHead} subchainHead=${subchain.head}` + `Starting canonical chain fill canonicalHead=${canonicalHead} subchainHead=${subchain.head}`, ) // run till it has not been determined that tail reset is required by concurrent setHead calls @@ -1210,7 +1210,7 @@ export class Skeleton extends MetaDBManager { // Else we should back step and fetch again as it indicates some concurrency/db errors if (!this.status.canonicalHeadReset) { this.config.logger.debug( - `fillCanonicalChain block number=${number} not found, backStepping...` + `fillCanonicalChain block number=${number} not found, backStepping...`, ) await this.runWithLock(async () => { // backstep the subchain from the block that was not found only if the canonicalHeadReset @@ -1219,7 +1219,7 @@ export class Skeleton extends MetaDBManager { }) } else { this.config.logger.debug( - `fillCanonicalChain block number=${number} not found canonicalHeadReset=${this.status.canonicalHeadReset}, breaking out...` + `fillCanonicalChain block number=${number} not found canonicalHeadReset=${this.status.canonicalHeadReset}, breaking out...`, ) } break @@ -1251,12 +1251,12 @@ export class Skeleton extends MetaDBManager { await this.runWithLock(async () => { if (!this.status.canonicalHeadReset) { this.config.logger.debug( - `fillCanonicalChain canonicalHeadReset=${this.status.canonicalHeadReset}, backStepping...` + `fillCanonicalChain canonicalHeadReset=${this.status.canonicalHeadReset}, backStepping...`, ) await this.backStep(number) } else { this.config.logger.debug( - `fillCanonicalChain canonicalHeadReset=${this.status.canonicalHeadReset}, breaking out...` + `fillCanonicalChain canonicalHeadReset=${this.status.canonicalHeadReset}, breaking out...`, ) } }) @@ -1274,8 +1274,8 @@ export class Skeleton extends MetaDBManager { if (numBlocksInserted !== 1) { this.config.logger.error( `Failed to put block number=${number} fork=${block.common.hardfork()} hash=${short( - block.hash() - )} parentHash=${short(block.header.parentHash)}from skeleton chain to canonical` + block.hash(), + )} parentHash=${short(block.header.parentHash)}from skeleton chain to canonical`, ) // Lets log some parent by number and parent by hash, that may help to understand whats going on let parent = null @@ -1283,8 +1283,8 @@ export class Skeleton extends MetaDBManager { parent = await this.chain.getBlock(number - BIGINT_1) this.config.logger.info( `ParentByNumber number=${parent?.header.number}, hash=${short( - parent?.hash() ?? 'undefined' - )} hf=${parent?.common.hardfork()}` + parent?.hash() ?? 'undefined', + )} hf=${parent?.common.hardfork()}`, ) } catch (e) { this.config.logger.error(`Failed to fetch parent of number=${number}`) @@ -1295,12 +1295,12 @@ export class Skeleton extends MetaDBManager { parentWithHash = await this.chain.getBlock(block.header.parentHash) this.config.logger.info( `parentByHash number=${parentWithHash?.header.number}, hash=${short( - parentWithHash?.hash() ?? 'undefined' - )} hf=${parentWithHash?.common.hardfork()} ` + parentWithHash?.hash() ?? 'undefined', + )} hf=${parentWithHash?.common.hardfork()} `, ) } catch (e) { this.config.logger.error( - `Failed to fetch parent with parentWithHash=${short(block.header.parentHash)}` + `Failed to fetch parent with parentWithHash=${short(block.header.parentHash)}`, ) } break @@ -1330,14 +1330,14 @@ export class Skeleton extends MetaDBManager { }) if (fillLogIndex >= this.config.numBlocksPerIteration) { this.config.logger.debug( - `Skeleton canonical chain fill status: canonicalHead=${canonicalHead} chainHead=${this.chain.blocks.height} subchainHead=${subchain.head}` + `Skeleton canonical chain fill status: canonicalHead=${canonicalHead} chainHead=${this.chain.blocks.height} subchainHead=${subchain.head}`, ) fillLogIndex = 0 } } this.filling = false this.config.logger.debug( - `Successfully put=${fillLogIndex} skipped (because already inserted)=${skippedLogIndex} blocks start=${start} end=${canonicalHead} skeletonHead=${subchain.head} from skeleton chain to canonical syncTargetHeight=${this.config.syncTargetHeight}` + `Successfully put=${fillLogIndex} skipped (because already inserted)=${skippedLogIndex} blocks start=${start} end=${canonicalHead} skeletonHead=${subchain.head} from skeleton chain to canonical syncTargetHeight=${this.config.syncTargetHeight}`, ) } @@ -1373,7 +1373,7 @@ export class Skeleton extends MetaDBManager { await this.put( DBKey.SkeletonBlockHashToNumber, block.hash(), - bigIntToBytes(block.header.number) + bigIntToBytes(block.header.number), ) } @@ -1418,7 +1418,7 @@ export class Skeleton extends MetaDBManager { */ async getBlockByHash( hash: Uint8Array, - onlyCanonical: boolean = false + onlyCanonical: boolean = false, ): Promise { const number = await this.get(DBKey.SkeletonBlockHashToNumber, hash) if (number) { @@ -1505,7 +1505,7 @@ export class Skeleton extends MetaDBManager { fetching?: boolean snapsync?: SnapFetcherDoneFlags peers?: number | string - } = {} + } = {}, ): string { const vmHead = this.chain.blocks.vm const subchain0 = this.status.progress.subchains[0] @@ -1534,10 +1534,10 @@ export class Skeleton extends MetaDBManager { const status = isValid ? 'VALID' : isSynced - ? vmexecution?.running === true - ? `EXECUTING` - : `SYNCED` - : `SYNCING` + ? vmexecution?.running === true + ? `EXECUTING` + : `SYNCED` + : `SYNCING` if (peers === undefined || peers === 0) { this.lastsyncedAt = 0 @@ -1645,7 +1645,7 @@ export class Skeleton extends MetaDBManager { extraStatus = '' } const chainHead = `el=${this.chain.blocks.latest?.header.number ?? 'na'} hash=${short( - this.chain.blocks.latest?.hash() ?? 'na' + this.chain.blocks.latest?.hash() ?? 'na', )}` forceShowInfo = forceShowInfo ?? false @@ -1662,7 +1662,7 @@ export class Skeleton extends MetaDBManager { const sinceStarted = (new Date().getTime() - this.started) / 1000 beaconSyncETA = `${timeDuration((sinceStarted / Number(this.pulled)) * Number(left))}` this.config.logger.debug( - `Syncing beacon headers downloaded=${this.pulled} left=${left} eta=${beaconSyncETA}` + `Syncing beacon headers downloaded=${this.pulled} left=${left} eta=${beaconSyncETA}`, ) } } @@ -1687,23 +1687,23 @@ export class Skeleton extends MetaDBManager { const { snapTargetHeight, snapTargetRoot, snapTargetHash } = snapsync if (snapsync.done === true) { snapLogInfo = `snapsync=synced height=${snapTargetHeight} hash=${short( - snapTargetHash ?? 'na' + snapTargetHash ?? 'na', )} root=${short(snapTargetRoot ?? 'na')}` } else if (snapsync.syncing) { const accountsDone = formatBigDecimal( snapsync.accountFetcher.first * BIGINT_100, BIGINT_2EXP256, - BIGINT_100 + BIGINT_100, ) const storageReqsDone = formatBigDecimal( snapsync.storageFetcher.first * BIGINT_100, snapsync.storageFetcher.count, - BIGINT_100 + BIGINT_100, ) const codeReqsDone = formatBigDecimal( snapsync.byteCodeFetcher.first * BIGINT_100, snapsync.byteCodeFetcher.count, - BIGINT_100 + BIGINT_100, ) const snapprogress = `accounts=${accountsDone}% storage=${storageReqsDone}% of ${snapsync.storageFetcher.count} codes=${codeReqsDone}% of ${snapsync.byteCodeFetcher.count}` @@ -1722,7 +1722,7 @@ export class Skeleton extends MetaDBManager { } snapLogInfo = `${stage} ${snapprogress} (hash=${short( - snapTargetHash ?? 'na' + snapTargetHash ?? 'na', )} root=${short(snapTargetRoot ?? 'na')})` } else { if (this.synchronized) { @@ -1760,7 +1760,7 @@ export class Skeleton extends MetaDBManager { } else { // else break into two this.config.logger.info( - `${logPrefix} ${status}${extraStatus} synchronized=${this.config.synchronized} peers=${peers}` + `${logPrefix} ${status}${extraStatus} synchronized=${this.config.synchronized} peers=${peers}`, ) if (snapLogInfo !== undefined && snapLogInfo !== '') { this.config.logger.info(`${logPrefix} ${snapLogInfo}`) @@ -1778,7 +1778,7 @@ export class Skeleton extends MetaDBManager { this.status.linked } subchains=${this.status.progress.subchains .map((s) => `[tail=${s.tail} head=${s.head} next=${short(s.next)}]`) - .join(',')} reset=${this.status.canonicalHeadReset} ${chainHead}` + .join(',')} reset=${this.status.canonicalHeadReset} ${chainHead}`, ) } return status @@ -1848,7 +1848,7 @@ export class Skeleton extends MetaDBManager { Uint8Array, // safe and finalized Uint8Array, - Uint8Array + Uint8Array, ] const subchains: SkeletonSubchain[] = rawStatus[0].map((raw) => ({ head: bytesToBigInt(raw[0]), diff --git a/packages/client/src/service/txpool.ts b/packages/client/src/service/txpool.ts index 693b5e9231..47ba8d9727 100644 --- a/packages/client/src/service/txpool.ts +++ b/packages/client/src/service/txpool.ts @@ -200,7 +200,7 @@ export class TxPool { } this._cleanupInterval = setInterval( this.cleanup.bind(this), - this.POOLED_STORAGE_TIME_LIMIT * 1000 * 60 + this.POOLED_STORAGE_TIME_LIMIT * 1000 * 60, ) if (this.config.logger.isInfoEnabled()) { @@ -242,7 +242,7 @@ export class TxPool { (existingTxGasPrice.maxFee * BigInt(MIN_GAS_PRICE_BUMP_PERCENT)) / BigInt(100) if (newGasPrice.tip < minTipCap || newGasPrice.maxFee < minFeeCap) { throw new Error( - `replacement gas too low, got tip ${newGasPrice.tip}, min: ${minTipCap}, got fee ${newGasPrice.maxFee}, min: ${minFeeCap}` + `replacement gas too low, got tip ${newGasPrice.tip}, min: ${minTipCap}, got fee ${newGasPrice.maxFee}, min: ${minFeeCap}`, ) } @@ -252,7 +252,7 @@ export class TxPool { (existingTx.maxFeePerBlobGas * BigInt(MIN_GAS_PRICE_BUMP_PERCENT)) / BigInt(100) if (addedTx.maxFeePerBlobGas < minblobGasFee) { throw new Error( - `replacement blob gas too low, got: ${addedTx.maxFeePerBlobGas}, min: ${minblobGasFee}` + `replacement blob gas too low, got: ${addedTx.maxFeePerBlobGas}, min: ${minblobGasFee}`, ) } } @@ -268,7 +268,7 @@ export class TxPool { } if (tx.data.length > TX_MAX_DATA_SIZE) { throw new Error( - `Tx is too large (${tx.data.length} bytes) and exceeds the max data size of ${TX_MAX_DATA_SIZE} bytes` + `Tx is too large (${tx.data.length} bytes) and exceeds the max data size of ${TX_MAX_DATA_SIZE} bytes`, ) } const currentGasPrice = this.txGasPrice(tx) @@ -291,7 +291,7 @@ export class TxPool { if (inPool) { if (!isLocalTransaction && inPool.length >= MAX_TXS_PER_ACCOUNT) { throw new Error( - `Cannot add tx for ${senderAddress}: already have max amount of txs for this account` + `Cannot add tx for ${senderAddress}: already have max amount of txs for this account`, ) } // Replace pooled txs with the same nonce @@ -307,13 +307,13 @@ export class TxPool { if (typeof block.baseFeePerGas === 'bigint' && block.baseFeePerGas !== BIGINT_0) { if (currentGasPrice.maxFee < block.baseFeePerGas / BIGINT_2 && !isLocalTransaction) { throw new Error( - `Tx cannot pay basefee of ${block.baseFeePerGas}, have ${currentGasPrice.maxFee} (not within 50% range of current basefee)` + `Tx cannot pay basefee of ${block.baseFeePerGas}, have ${currentGasPrice.maxFee} (not within 50% range of current basefee)`, ) } } if (tx.gasLimit > block.gasLimit) { throw new Error( - `Tx gaslimit of ${tx.gasLimit} exceeds block gas limit of ${block.gasLimit} (exceeds last block gas limit)` + `Tx gaslimit of ${tx.gasLimit} exceeds block gas limit of ${block.gasLimit} (exceeds last block gas limit)`, ) } @@ -327,13 +327,13 @@ export class TxPool { } if (account.nonce > tx.nonce) { throw new Error( - `0x${sender} tries to send a tx with nonce ${tx.nonce}, but account has nonce ${account.nonce} (tx nonce too low)` + `0x${sender} tries to send a tx with nonce ${tx.nonce}, but account has nonce ${account.nonce} (tx nonce too low)`, ) } const minimumBalance = tx.value + currentGasPrice.maxFee * tx.gasLimit if (account.balance < minimumBalance) { throw new Error( - `0x${sender} does not have enough balance to cover transaction costs, need ${minimumBalance}, but have ${account.balance} (insufficient balance)` + `0x${sender} does not have enough balance to cover transaction costs, need ${minimumBalance}, but have ${account.balance} (insufficient balance)`, ) } } @@ -571,7 +571,7 @@ export class TxPool { this.config.logger.debug(`TxPool: received new transactions number=${txs.length}`) this.addToKnownByPeer( txs.map((tx) => tx.hash()), - peer + peer, ) const newTxHashes: [number[], number[], Uint8Array[]] = [] as any @@ -583,7 +583,7 @@ export class TxPool { newTxHashes[2].push(tx.hash()) } catch (error: any) { this.config.logger.debug( - `Error adding tx to TxPool: ${error.message} (tx hash: ${bytesToHex(tx.hash())})` + `Error adding tx to TxPool: ${error.message} (tx hash: ${bytesToHex(tx.hash())})`, ) } } @@ -621,7 +621,7 @@ export class TxPool { const reqHashesStr: UnprefixedHash[] = reqHashes.map(bytesToUnprefixedHex) this.pending = this.pending.concat(reqHashesStr) this.config.logger.debug( - `TxPool: requesting txs number=${reqHashes.length} pending=${this.pending.length}` + `TxPool: requesting txs number=${reqHashes.length} pending=${this.pending.length}`, ) const getPooledTxs = await peer.eth?.getPooledTransactions({ hashes: reqHashes.slice(0, this.TX_RETRIEVAL_LIMIT), @@ -642,7 +642,7 @@ export class TxPool { await this.add(tx) } catch (error: any) { this.config.logger.debug( - `Error adding tx to TxPool: ${error.message} (tx hash: ${bytesToHex(tx.hash())})` + `Error adding tx to TxPool: ${error.message} (tx hash: ${bytesToHex(tx.hash())})`, ) } newTxHashes[0].push(tx.type) @@ -767,7 +767,7 @@ export class TxPool { */ async txsByPriceAndNonce( vm: VM, - { baseFee, allowedBlobs }: { baseFee?: bigint; allowedBlobs?: number } = {} + { baseFee, allowedBlobs }: { baseFee?: bigint; allowedBlobs?: number } = {}, ) { const txs: TypedTransaction[] = [] // Separate the transactions by account and sort by nonce @@ -846,7 +846,7 @@ export class TxPool { } } this.config.logger.info( - `txsByPriceAndNonce selected txs=${txs.length}, skipped byNonce=${skippedStats.byNonce} byPrice=${skippedStats.byPrice} byBlobsLimit=${skippedStats.byBlobsLimit}` + `txsByPriceAndNonce selected txs=${txs.length}, skipped byNonce=${skippedStats.byNonce} byPrice=${skippedStats.byPrice} byBlobsLimit=${skippedStats.byBlobsLimit}`, ) return txs } @@ -908,13 +908,13 @@ export class TxPool { } } this.config.logger.info( - `TxPool Statistics txs=${this.txsInPool} senders=${this.pool.size} peers=${this.service.pool.peers.length}` + `TxPool Statistics txs=${this.txsInPool} senders=${this.pool.size} peers=${this.service.pool.peers.length}`, ) this.config.logger.info( - `TxPool Statistics broadcasts=${broadcasts}/tx/peer broadcasterrors=${broadcasterrors}/tx/peer knownpeers=${knownpeers} since minutes=${this.POOLED_STORAGE_TIME_LIMIT}` + `TxPool Statistics broadcasts=${broadcasts}/tx/peer broadcasterrors=${broadcasterrors}/tx/peer knownpeers=${knownpeers} since minutes=${this.POOLED_STORAGE_TIME_LIMIT}`, ) this.config.logger.info( - `TxPool Statistics successfuladds=${handledadds} failedadds=${handlederrors} since minutes=${this.HANDLED_CLEANUP_TIME_LIMIT}` + `TxPool Statistics successfuladds=${handledadds} failedadds=${handlederrors} since minutes=${this.HANDLED_CLEANUP_TIME_LIMIT}`, ) } } diff --git a/packages/client/src/sync/beaconsync.ts b/packages/client/src/sync/beaconsync.ts index c852723022..372764b640 100644 --- a/packages/client/src/sync/beaconsync.ts +++ b/packages/client/src/sync/beaconsync.ts @@ -81,8 +81,8 @@ export class BeaconSynchronizer extends Synchronizer { this.config.logger.info( `Latest local block number=${Number(number)} td=${td} hash=${bytesToHex( - hash - )} hardfork=${this.config.chainCommon.hardfork()}` + hash, + )} hardfork=${this.config.chainCommon.hardfork()}`, ) const subchain = this.skeleton.bounds() @@ -165,8 +165,8 @@ export class BeaconSynchronizer extends Synchronizer { await this.stop() this.config.logger.debug( `Beacon sync reorged, new head number=${block.header.number} hash=${short( - block.header.hash() - )}` + block.header.hash(), + )}`, ) void this.start() } @@ -251,7 +251,7 @@ export class BeaconSynchronizer extends Synchronizer { this.fetcher === null ? '' : 'previous fetcher errored=' + this.fetcher.syncErrored?.message - }` + }`, ) this.fetcher = new ReverseBlockFetcher({ config: this.config, @@ -281,7 +281,7 @@ export class BeaconSynchronizer extends Synchronizer { const hash = short(blocks[0].hash()) this.config.logger.debug( - `Imported skeleton blocks count=${blocks.length} first=${first} last=${last} hash=${hash} peers=${this.pool.size}` + `Imported skeleton blocks count=${blocks.length} first=${first} last=${last} hash=${hash} peers=${this.pool.size}`, ) } diff --git a/packages/client/src/sync/fetcher/accountfetcher.ts b/packages/client/src/sync/fetcher/accountfetcher.ts index 3baf8e965b..dcd5a22879 100644 --- a/packages/client/src/sync/fetcher/accountfetcher.ts +++ b/packages/client/src/sync/fetcher/accountfetcher.ts @@ -138,8 +138,8 @@ export class AccountFetcher extends Fetcher this.debug( `Account fetcher instantiated root=${short(this.root)} origin=${short(origin)} limit=${short( - limit - )} destroyWhenDone=${this.destroyWhenDone}` + limit, + )} destroyWhenDone=${this.destroyWhenDone}`, ) } @@ -171,7 +171,7 @@ export class AccountFetcher extends Fetcher () => this.snapFetchersCompleted(StorageFetcher), () => { throw Error('Snap fetcher failed to exit') - } + }, ) : null const codeFetch = !this.fetcherDoneFlags.byteCodeFetcher.done @@ -179,12 +179,12 @@ export class AccountFetcher extends Fetcher () => this.snapFetchersCompleted(ByteCodeFetcher), () => { throw Error('Snap fetcher failed to exit') - } + }, ) : null this.config.superMsg( - `Snapsync: running storageFetch=${storageFetch !== null} codeFetch=${codeFetch !== null}` + `Snapsync: running storageFetch=${storageFetch !== null} codeFetch=${codeFetch !== null}`, ) this.storageFetcher.setDestroyWhenDone() @@ -196,7 +196,7 @@ export class AccountFetcher extends Fetcher this.fetcherDoneFlags.byteCodeFetcher.done !== true ) { throw Error( - `storageFetch or codeFetch didn't complete storageFetcherDone=${this.fetcherDoneFlags.storageFetcher.done} byteCodeFetcherDone=${this.fetcherDoneFlags.byteCodeFetcher.done}` + `storageFetch or codeFetch didn't complete storageFetcherDone=${this.fetcherDoneFlags.storageFetcher.done} byteCodeFetcherDone=${this.fetcherDoneFlags.byteCodeFetcher.done}`, ) } @@ -209,7 +209,7 @@ export class AccountFetcher extends Fetcher }, () => { throw Error('Snap fetcher failed to exit') - } + }, ) this.config.superMsg(`Snapsync: running trieNodeFetch=${trieNodeFetch !== null}`) this.trieNodeFetcher.setDestroyWhenDone() @@ -239,10 +239,10 @@ export class AccountFetcher extends Fetcher const fetcherProgress = formatBigDecimal( fetcherDoneFlags.accountFetcher.first * BIGINT_100, BIGINT_2EXP256, - BIGINT_100 + BIGINT_100, ) this.config.logger.warn( - `accountFetcher completed with pending range done=${fetcherProgress}%` + `accountFetcher completed with pending range done=${fetcherProgress}%`, ) } break @@ -253,10 +253,10 @@ export class AccountFetcher extends Fetcher const reqsDone = formatBigDecimal( fetcherDoneFlags.storageFetcher.first * BIGINT_100, fetcherDoneFlags.storageFetcher.count, - BIGINT_100 + BIGINT_100, ) this.config.logger.warn( - `storageFetcher completed with pending tasks done=${reqsDone}% of ${fetcherDoneFlags.storageFetcher.count} queued=${this.storageFetcher.storageRequests.length}` + `storageFetcher completed with pending tasks done=${reqsDone}% of ${fetcherDoneFlags.storageFetcher.count} queued=${this.storageFetcher.storageRequests.length}`, ) } @@ -268,10 +268,10 @@ export class AccountFetcher extends Fetcher const reqsDone = formatBigDecimal( fetcherDoneFlags.byteCodeFetcher.first * BIGINT_100, fetcherDoneFlags.byteCodeFetcher.count, - BIGINT_100 + BIGINT_100, ) this.config.logger.warn( - `byteCodeFetcher completed with pending tasks done=${reqsDone}% of ${fetcherDoneFlags.byteCodeFetcher.count}` + `byteCodeFetcher completed with pending tasks done=${reqsDone}% of ${fetcherDoneFlags.byteCodeFetcher.count}`, ) } break @@ -286,10 +286,10 @@ export class AccountFetcher extends Fetcher this.config.superMsg( `snapFetchersCompletion root=${short(this.root)} accountsRoot=${short( - fetcherDoneFlags.stateRoot ?? 'na' + fetcherDoneFlags.stateRoot ?? 'na', )} done=${this.fetcherDoneFlags.done} accountsDone=${accountFetcher.done} storageDone=${ storageFetcher.done - } byteCodesDone=${byteCodeFetcher.done} trieNodesDone=${trieNodeFetcher.done}` + } byteCodesDone=${byteCodeFetcher.done} trieNodesDone=${trieNodeFetcher.done}`, ) if (this.fetcherDoneFlags.done) { @@ -300,12 +300,12 @@ export class AccountFetcher extends Fetcher private async verifyRangeProof( stateRoot: Uint8Array, origin: Uint8Array, - { accounts, proof }: { accounts: AccountData[]; proof: Uint8Array[] } + { accounts, proof }: { accounts: AccountData[]; proof: Uint8Array[] }, ): Promise { this.debug( `verifyRangeProof accounts:${accounts.length} first=${bytesToHex( - accounts[0].hash - )} last=${short(accounts[accounts.length - 1].hash)}` + accounts[0].hash, + )} last=${short(accounts[accounts.length - 1].hash)}`, ) for (let i = 0; i < accounts.length - 1; i++) { @@ -314,7 +314,7 @@ export class AccountFetcher extends Fetcher throw Error( `Account hashes not monotonically increasing: ${i} ${accounts[i].hash} vs ${i + 1} ${ accounts[i + 1].hash - }` + }`, ) } } @@ -347,7 +347,7 @@ export class AccountFetcher extends Fetcher private isMissingRightRange( limit: Uint8Array, - { accounts, proof: _proof }: { accounts: AccountData[]; proof: Uint8Array[] } + { accounts, proof: _proof }: { accounts: AccountData[]; proof: Uint8Array[] }, ): boolean { if ( accounts.length > 0 && @@ -369,7 +369,7 @@ export class AccountFetcher extends Fetcher * @param peer */ async request( - job: Job + job: Job, ): Promise { const { peer } = job // Currently this is the only safe place to call peer.latest() without interfering with the fetcher @@ -410,7 +410,7 @@ export class AccountFetcher extends Fetcher [], [], rangeResult.proof, - { useKeyHashingFunction: keccak256 } + { useKeyHashingFunction: keccak256 }, ) // if proof is false, reject corrupt peer if (isMissingRightRange !== false) return undefined @@ -438,8 +438,8 @@ export class AccountFetcher extends Fetcher if (isMissingRightRange && this.isMissingRightRange(limit, rangeResult)) { this.debug( `Peer ${peerInfo} returned missing right range account=${bytesToHex( - rangeResult.accounts[rangeResult.accounts.length - 1].hash - )} limit=${bytesToHex(limit)}` + rangeResult.accounts[rangeResult.accounts.length - 1].hash, + )} limit=${bytesToHex(limit)}`, ) completed = false } else { @@ -460,7 +460,7 @@ export class AccountFetcher extends Fetcher */ process( job: Job, - result: AccountDataResponse + result: AccountDataResponse, ): AccountData[] | undefined { const fullResult = (job.partialResult ?? []).concat(result) @@ -533,11 +533,11 @@ export class AccountFetcher extends Fetcher if (storageFetchRequests.size > 0) this.storageFetcher.enqueueByStorageRequestList( - Array.from(storageFetchRequests) as StorageRequest[] + Array.from(storageFetchRequests) as StorageRequest[], ) if (byteCodeFetchRequests.size > 0) this.byteCodeFetcher.enqueueByByteCodeRequestList( - Array.from(byteCodeFetchRequests) as Uint8Array[] + Array.from(byteCodeFetchRequests) as Uint8Array[], ) } @@ -577,7 +577,7 @@ export class AccountFetcher extends Fetcher } debugStr += ` limit=${short( - setLengthLeft(bigIntToBytes(startedWith + pushedCount - BIGINT_1), 32) + setLengthLeft(bigIntToBytes(startedWith + pushedCount - BIGINT_1), 32), )}` this.debug(`Created new tasks num=${tasks.length} ${debugStr}`) return tasks @@ -626,7 +626,7 @@ export class AccountFetcher extends Fetcher processStoreError( error: Error, - _task: JobTask + _task: JobTask, ): { destroyFetcher: boolean; banPeer: boolean; stepBack: bigint } { const stepBack = BIGINT_0 const destroyFetcher = diff --git a/packages/client/src/sync/fetcher/blockfetcher.ts b/packages/client/src/sync/fetcher/blockfetcher.ts index 7568dcd259..732cc36ba7 100644 --- a/packages/client/src/sync/fetcher/blockfetcher.ts +++ b/packages/client/src/sync/fetcher/blockfetcher.ts @@ -69,7 +69,7 @@ export class BlockFetcher extends BlockFetcherBase { } const bodies = bodiesResult[1] this.debug( - `Requested blocks=${blocksRange} from ${peerInfo} (received: ${headers.length} headers / ${bodies.length} bodies)` + `Requested blocks=${blocksRange} from ${peerInfo} (received: ${headers.length} headers / ${bodies.length} bodies)`, ) const blocks: Block[] = [] for (const [i, [txsData, unclesData, withdrawalsData]] of bodies.entries()) { @@ -82,7 +82,7 @@ export class BlockFetcher extends BlockFetcherBase { (withdrawalsData?.length ?? 0) === 0) ) { this.debug( - `Requested block=${headers[i].number}} from peer ${peerInfo} missing non-empty txs=${txsData.length} or uncles=${unclesData.length} or withdrawals=${withdrawalsData?.length}` + `Requested block=${headers[i].number}} from peer ${peerInfo} missing non-empty txs=${txsData.length} or uncles=${unclesData.length} or withdrawals=${withdrawalsData?.length}`, ) return [] } @@ -100,7 +100,7 @@ export class BlockFetcher extends BlockFetcherBase { blocks.push(block) } this.debug( - `Returning blocks=${blocksRange} from ${peerInfo} (received: ${headers.length} headers / ${bodies.length} bodies)` + `Returning blocks=${blocksRange} from ${peerInfo} (received: ${headers.length} headers / ${bodies.length} bodies)`, ) return blocks } @@ -136,14 +136,14 @@ export class BlockFetcher extends BlockFetcherBase { this.debug( `Fetcher results stored in blockchain (blocks num=${blocks.length} first=${ blocks[0]?.header.number - } last=${blocks[blocks.length - 1]?.header.number})` + } last=${blocks[blocks.length - 1]?.header.number})`, ) this.config.events.emit(Event.SYNC_FETCHED_BLOCKS, blocks.slice(0, num)) } catch (e: any) { this.debug( `Error storing fetcher results in blockchain (blocks num=${blocks.length} first=${ blocks[0]?.header.number - } last=${blocks[blocks.length - 1]?.header.number}): ${e}` + } last=${blocks[blocks.length - 1]?.header.number}): ${e}`, ) throw e } diff --git a/packages/client/src/sync/fetcher/blockfetcherbase.ts b/packages/client/src/sync/fetcher/blockfetcherbase.ts index c84760d0bd..fc12a0d243 100644 --- a/packages/client/src/sync/fetcher/blockfetcherbase.ts +++ b/packages/client/src/sync/fetcher/blockfetcherbase.ts @@ -56,7 +56,7 @@ export abstract class BlockFetcherBase extends Fetcher< this.count = options.count this.reverse = options.reverse ?? false this.debug( - `Block fetcher instantiated interval=${this.interval} first=${this.first} count=${this.count} reverse=${this.reverse} destroyWhenDone=${this.destroyWhenDone}` + `Block fetcher instantiated interval=${this.interval} first=${this.first} count=${this.count} reverse=${this.reverse} destroyWhenDone=${this.destroyWhenDone}`, ) } @@ -105,7 +105,7 @@ export abstract class BlockFetcherBase extends Fetcher< this.processed - this.finished < this.config.maxFetcherRequests ) { this.debug( - `Fetcher pending with first=${this.first} count=${this.count} reverse=${this.reverse}` + `Fetcher pending with first=${this.first} count=${this.count} reverse=${this.reverse}`, ) const tasks = this.tasks(this.first, this.count) for (const task of tasks) { @@ -114,7 +114,7 @@ export abstract class BlockFetcherBase extends Fetcher< this.debug(`Enqueued num=${tasks.length} tasks`) } else { this.debug( - `No new tasks enqueued in=${this.in.length} count=${this.count} processed=${this.processed} finished=${this.finished}` + `No new tasks enqueued in=${this.in.length} count=${this.count} processed=${this.processed} finished=${this.finished}`, ) } } @@ -185,7 +185,7 @@ export abstract class BlockFetcherBase extends Fetcher< first: min, count: numBlocks, }, - true + true, ) } else { for (const first of numberList) { @@ -194,12 +194,12 @@ export abstract class BlockFetcherBase extends Fetcher< first, count: 1, }, - true + true, ) } } this.debug( - `Enqueued tasks by number list num=${numberList.length} min=${min} bulkRequest=${bulkRequest} ${updateHeightStr}` + `Enqueued tasks by number list num=${numberList.length} min=${min} bulkRequest=${bulkRequest} ${updateHeightStr}`, ) if (this.in.length === 0) { this.nextTasks() @@ -208,7 +208,7 @@ export abstract class BlockFetcherBase extends Fetcher< processStoreError( error: Error, - task: JobTask + task: JobTask, ): { destroyFetcher: boolean; banPeer: boolean; stepBack: bigint } { let stepBack = BIGINT_0 const destroyFetcher = !(error.message as string).includes('could not find parent header') diff --git a/packages/client/src/sync/fetcher/bytecodefetcher.ts b/packages/client/src/sync/fetcher/bytecodefetcher.ts index e0fdb957bc..d2f5c8207c 100644 --- a/packages/client/src/sync/fetcher/bytecodefetcher.ts +++ b/packages/client/src/sync/fetcher/bytecodefetcher.ts @@ -65,7 +65,7 @@ export class ByteCodeFetcher extends Fetcher if (this.hashes.length > 0) { const fullJob = { task: { hashes: this.hashes } } as Job this.debug( - `Bytecode fetcher instantiated ${fullJob.task.hashes.length} hash requests destroyWhenDone=${this.destroyWhenDone}` + `Bytecode fetcher instantiated ${fullJob.task.hashes.length} hash requests destroyWhenDone=${this.destroyWhenDone}`, ) } } @@ -82,7 +82,7 @@ export class ByteCodeFetcher extends Fetcher * @param peer */ async request( - job: Job + job: Job, ): Promise { const { task, peer } = job // Currently this is the only safe place to call peer.latest() without interfering with the fetcher @@ -155,7 +155,7 @@ export class ByteCodeFetcher extends Fetcher */ process( job: Job, - result: ByteCodeDataResponse + result: ByteCodeDataResponse, ): Uint8Array[] | undefined { const fullResult = (job.partialResult ?? []).concat(result) job.partialResult = undefined @@ -213,7 +213,7 @@ export class ByteCodeFetcher extends Fetcher this.fetcherDoneFlags.byteCodeFetcher.count = this.fetcherDoneFlags.byteCodeFetcher.first + BigInt(this.hashes.length) this.debug( - `Number of bytecode fetch requests added to fetcher queue: ${byteCodeRequestList.length}` + `Number of bytecode fetch requests added to fetcher queue: ${byteCodeRequestList.length}`, ) this.nextTasks() } @@ -269,7 +269,7 @@ export class ByteCodeFetcher extends Fetcher processStoreError( error: Error, - _task: JobTask + _task: JobTask, ): { destroyFetcher: boolean; banPeer: boolean; stepBack: bigint } { const stepBack = BIGINT_0 const destroyFetcher = diff --git a/packages/client/src/sync/fetcher/fetcher.ts b/packages/client/src/sync/fetcher/fetcher.ts index 6bc1e92d90..de527769ff 100644 --- a/packages/client/src/sync/fetcher/fetcher.ts +++ b/packages/client/src/sync/fetcher/fetcher.ts @@ -87,19 +87,19 @@ export abstract class Fetcher extends Readable this.maxQueue = options.maxQueue ?? 4 this.debug( - `Fetcher initialized timeout=${this.timeout} interval=${this.interval} banTime=${this.banTime} maxQueue=${this.maxQueue}` + `Fetcher initialized timeout=${this.timeout} interval=${this.interval} banTime=${this.banTime} maxQueue=${this.maxQueue}`, ) this.in = new Heap({ comparBefore: ( a: Job, - b: Job + b: Job, ) => a.index < b.index, }) as QHeap> this.out = new Heap({ comparBefore: ( a: Job, - b: Job + b: Job, ) => a.index < b.index, }) as QHeap> this.total = 0 @@ -119,7 +119,7 @@ export abstract class Fetcher extends Readable */ abstract request( _job?: Job, - _peer?: Peer + _peer?: Peer, ): Promise /** @@ -131,7 +131,7 @@ export abstract class Fetcher extends Readable */ abstract process( _job?: Job, - _result?: JobResult + _result?: JobResult, ): StorageItem[] | undefined /** @@ -146,7 +146,7 @@ export abstract class Fetcher extends Readable */ abstract processStoreError( _error: Error, - _task: JobTask | BlockFetcherJobTask + _task: JobTask | BlockFetcherJobTask, ): { destroyFetcher: boolean; banPeer: boolean; stepBack: bigint } abstract jobStr(job: Job, withIndex?: boolean): string @@ -259,8 +259,8 @@ export abstract class Fetcher extends Readable this.debug( `Re-enqueuing job ${jobStr} from peer id=${job.peer?.id?.substr( 0, - 8 - )} (${resultSet} result set returned).` + 8, + )} (${resultSet} result set returned).`, ) this.enqueue(job) void this.wait().then(() => { @@ -278,8 +278,8 @@ export abstract class Fetcher extends Readable this.debug( `Re-enqueuing job ${jobStr} from peer id=${job.peer?.id?.substr( 0, - 8 - )} (reply contains unexpected data).` + 8, + )} (reply contains unexpected data).`, ) this.enqueue(job) } @@ -297,7 +297,7 @@ export abstract class Fetcher extends Readable error?: Error, irrecoverable?: boolean, dequeued?: boolean, - banPeer?: boolean + banPeer?: boolean, ) { const jobItems = job instanceof Array ? job : [job] if (irrecoverable === true || banPeer === true) { @@ -314,8 +314,8 @@ export abstract class Fetcher extends Readable this.debug( `Failure - Re-enqueuing job ${jobStr} from peer id=${jobItem.peer?.id?.substr( 0, - 8 - )} (error: ${error}).` + 8, + )} (error: ${error}).`, ) // If the job has been dequeued, then the processed count needs to be decreased this.enqueue(jobItem, dequeued) @@ -339,7 +339,7 @@ export abstract class Fetcher extends Readable if (this.finished !== this.total) { // There are still jobs waiting to be processed out in the writer pipe this.debug( - `No job found as next task, skip next job execution processed=${this.processed} finished=${this.finished} total=${this.total}` + `No job found as next task, skip next job execution processed=${this.processed} finished=${this.finished} total=${this.total}`, ) } else { // There are no more jobs in the fetcher, so its better to resolve @@ -354,7 +354,7 @@ export abstract class Fetcher extends Readable this.debug( `Readable state length=${this._readableState!.length} exceeds max queue size=${ this.maxQueue - }, skip job ${jobStr} execution.` + }, skip job ${jobStr} execution.`, ) return false } @@ -403,7 +403,7 @@ export abstract class Fetcher extends Readable this.in.remove() } this.debug( - `Cleared out fetcher total=${this.total} processed=${this.processed} finished=${this.finished}` + `Cleared out fetcher total=${this.total} processed=${this.processed} finished=${this.finished}`, ) } @@ -435,7 +435,7 @@ export abstract class Fetcher extends Readable const _write = async ( job: Job | Job[], encoding: string | null, - cb: Function + cb: Function, ) => { const jobItems = job instanceof Array ? job : [job] this.debug(`Starting write for ${jobItems.length} jobs...`) @@ -449,7 +449,7 @@ export abstract class Fetcher extends Readable this.config.logger.warn(`Error storing received block or header result: ${error}`) const { destroyFetcher, banPeer, stepBack } = this.processStoreError( error, - jobItems[0].task + jobItems[0].task, ) if (!destroyFetcher) { // Non-fatal error: ban peer and re-enqueue job. @@ -475,12 +475,12 @@ export abstract class Fetcher extends Readable write: _write, writev: ( many: { chunk: Job; encoding: string }[], - cb: Function + cb: Function, ) => { const items = ([]>[]).concat( ...many.map( - (x: { chunk: Job; encoding: string }) => x.chunk - ) + (x: { chunk: Job; encoding: string }) => x.chunk, + ), ) return _write(items, null, cb) }, diff --git a/packages/client/src/sync/fetcher/headerfetcher.ts b/packages/client/src/sync/fetcher/headerfetcher.ts index 4c7aa0a281..0d75348487 100644 --- a/packages/client/src/sync/fetcher/headerfetcher.ts +++ b/packages/client/src/sync/fetcher/headerfetcher.ts @@ -92,14 +92,14 @@ export class HeaderFetcher extends BlockFetcherBase { try { this.debug( `verifyRangeProof slots:${slots.length} first=${short(slots[0].hash)} last=${short( - slots[slots.length - 1].hash - )}` + slots[slots.length - 1].hash, + )}`, ) const keys = slots.map((slot: any) => slot.hash) const values = slots.map((slot: any) => slot.body) @@ -136,7 +136,7 @@ export class StorageFetcher extends Fetcher 0 && @@ -214,7 +214,7 @@ export class StorageFetcher extends Fetcher + job: Job, ): Promise { const { task, peer } = job // Currently this is the only safe place to call peer.latest() without interfering with the fetcher @@ -230,7 +230,7 @@ export class StorageFetcher extends Fetcher bytesToHex(req.accountHash))}` + `requested account hashes: ${task.storageRequests.map((req) => bytesToHex(req.accountHash))}`, ) this.debug(`request is multi: ${job.task.multi}`) @@ -239,7 +239,7 @@ export class StorageFetcher extends FetcherrangeResult.proof, - { useKeyHashingFunction: keccak256 } + { useKeyHashingFunction: keccak256 }, ) // if proof is false, reject corrupt peer @@ -324,7 +324,7 @@ export class StorageFetcher extends Fetcher 0) { this.debug( - `Number of ignored account requests due to fragmentation: ${ignoredRequests.length}` + `Number of ignored account requests due to fragmentation: ${ignoredRequests.length}`, ) this.storageRequests.push(...ignoredRequests) } @@ -415,7 +415,7 @@ export class StorageFetcher extends Fetcher, - result: StorageDataResponse + result: StorageDataResponse, ): StorageData[][] | undefined { const accountSlots = (result[0] as any)[0] const highestReceivedhash = accountSlots[accountSlots.length - 1].hash @@ -442,7 +442,7 @@ export class StorageFetcher extends Fetcher { try { if (JSON.stringify(result[0]) === JSON.stringify({ skipped: true })) { @@ -468,7 +468,7 @@ export class StorageFetcher extends Fetcher 0) { this.debug( - `Number of accounts requested as a part of a multi-account request: ${this.storageRequests.length}` + `Number of accounts requested as a part of a multi-account request: ${this.storageRequests.length}`, ) tasks.unshift({ storageRequests: this.storageRequests, // TODO limit max number of accounts per single fetch request @@ -618,7 +618,7 @@ export class StorageFetcher extends Fetcher this.debug( `Trie node fetcher instantiated with ${this.pathToNodeRequestData.size()} node requests destroyWhenDone=${ this.destroyWhenDone - }` + }`, ) } @@ -139,7 +139,7 @@ export class TrieNodeFetcher extends Fetcher * @param peer */ async request( - job: Job + job: Job, ): Promise { const { task, peer } = job // Currently this is the only safe place to call peer.latest() without interfering with the fetcher @@ -193,7 +193,7 @@ export class TrieNodeFetcher extends Fetcher */ process( job: Job, - result: TrieNodesResponse + result: TrieNodesResponse, ): Uint8Array[] | undefined { const fullResult = (job.partialResult ?? []).concat(result) job.partialResult = undefined @@ -295,7 +295,7 @@ export class TrieNodeFetcher extends Fetcher // if error is thrown, than the node is unknown and should be queued for fetching unknownChildNodeCount++ const { parentAccountHash } = this.pathToNodeRequestData.getElementByKey( - pathString + pathString, ) as NodeRequestData this.pathToNodeRequestData.setElement(childNode.path, { nodeHash: bytesToHex(childNode.nodeHash as Uint8Array), @@ -307,13 +307,13 @@ export class TrieNodeFetcher extends Fetcher // record new node for batched storing after all subtrie nodes have been received const { nodeParentHash, parentAccountHash } = this.pathToNodeRequestData.getElementByKey( - pathString + pathString, ) as NodeRequestData if (storagePath !== undefined) { // if fetched node has a storagePath, it's storage node data and should be stored with // account leaf node data from where it originates const { pathToStorageNode } = this.fetchedAccountNodes.get( - parentAccountHash as string + parentAccountHash as string, ) as unknown as FetchedNodeData pathToStorageNode!.set(storagePath, nodeData as unknown as Uint8Array) } else { @@ -369,8 +369,8 @@ export class TrieNodeFetcher extends Fetcher const a = createAccountFromRLP(node.value()) this.debug( `Stored storageTrie with root actual=${bytesToHex( - storageTrie.root() - )} expected=${bytesToHex(a.storageRoot)}` + storageTrie.root(), + )} expected=${bytesToHex(a.storageRoot)}`, ) } } @@ -379,8 +379,8 @@ export class TrieNodeFetcher extends Fetcher await this.accountTrie.persistRoot() this.debug( `Stored accountTrie with root actual=${bytesToHex( - this.accountTrie.root() - )} expected=${bytesToHex(this.root)}` + this.accountTrie.root(), + )} expected=${bytesToHex(this.root)}`, ) } } catch (e) { @@ -468,7 +468,7 @@ export class TrieNodeFetcher extends Fetcher processStoreError( error: Error, - _task: JobTask + _task: JobTask, ): { destroyFetcher: boolean; banPeer: boolean; stepBack: bigint } { const stepBack = BIGINT_0 const destroyFetcher = diff --git a/packages/client/src/sync/fullsync.ts b/packages/client/src/sync/fullsync.ts index 53f3452368..4f7f5051a5 100644 --- a/packages/client/src/sync/fullsync.ts +++ b/packages/client/src/sync/fullsync.ts @@ -104,8 +104,8 @@ export class FullSynchronizer extends Synchronizer { this.config.logger.info( `Latest local block number=${Number(number)} td=${td} hash=${short( - hash - )} hardfork=${this.config.chainCommon.hardfork()}` + hash, + )} hardfork=${this.config.chainCommon.hardfork()}`, ) } @@ -260,7 +260,7 @@ export class FullSynchronizer extends Synchronizer { } first=${first} last=${last} hash=${hash} ${baseFeeAdd}hardfork=${this.config.chainCommon.hardfork()} peers=${ this.pool.size }`, - { attentionHF } + { attentionHF }, ) this.txPool.removeNewBlockTxs(blocks) @@ -320,7 +320,7 @@ export class FullSynchronizer extends Synchronizer { this.config.logger.debug( `Error processing new block from peer ${ peer ? `id=${peer.id.slice(0, 8)}` : '(no peer)' - } hash=${short(block.hash())}` + } hash=${short(block.hash())}`, ) this.config.logger.debug(err) return diff --git a/packages/client/src/sync/lightsync.ts b/packages/client/src/sync/lightsync.ts index 946ce20058..2b487080ea 100644 --- a/packages/client/src/sync/lightsync.ts +++ b/packages/client/src/sync/lightsync.ts @@ -146,7 +146,7 @@ export class LightSynchronizer extends Synchronizer { ? `baseFee=${headers[0].baseFeePerGas} ` : '' this.config.logger.info( - `Imported headers count=${headers.length} number=${first} hash=${hash} ${baseFeeAdd}peers=${this.pool.size}` + `Imported headers count=${headers.length} number=${first} hash=${hash} ${baseFeeAdd}peers=${this.pool.size}`, ) } diff --git a/packages/client/src/sync/snapsync.ts b/packages/client/src/sync/snapsync.ts index 69162ed194..97ae243777 100644 --- a/packages/client/src/sync/snapsync.ts +++ b/packages/client/src/sync/snapsync.ts @@ -62,7 +62,7 @@ export class SnapSynchronizer extends Synchronizer { await this.pool.open() this.config.logger.info( - `Opened SnapSynchronizer syncTargetHeight=${this.config.syncTargetHeight ?? 'NA'}` + `Opened SnapSynchronizer syncTargetHeight=${this.config.syncTargetHeight ?? 'NA'}`, ) } @@ -132,7 +132,7 @@ export class SnapSynchronizer extends Synchronizer { if (!this.fetcherDoneFlags.done) { throw Error( - `snap sync fetchers didn't sync complete state accountFetcherDone=${this.fetcherDoneFlags.accountFetcher.done} storageFetcherDone=${this.fetcherDoneFlags.storageFetcher.done} byteCodeFetcherDone=${this.fetcherDoneFlags.byteCodeFetcher.done} trieNodeFetcherDone=${this.fetcherDoneFlags.trieNodeFetcher.done}` + `snap sync fetchers didn't sync complete state accountFetcherDone=${this.fetcherDoneFlags.accountFetcher.done} storageFetcherDone=${this.fetcherDoneFlags.storageFetcher.done} byteCodeFetcherDone=${this.fetcherDoneFlags.byteCodeFetcher.done} trieNodeFetcherDone=${this.fetcherDoneFlags.trieNodeFetcher.done}`, ) } @@ -144,8 +144,8 @@ export class SnapSynchronizer extends Synchronizer { ) { throw Error( `Invalid synced data by snapsync snapTargetHeight=${snapTargetHeight} snapTargetRoot=${short( - snapTargetRoot ?? 'na' - )} snapTargetHash=${short(snapTargetHash ?? 'na')}` + snapTargetRoot ?? 'na', + )} snapTargetHash=${short(snapTargetHash ?? 'na')}`, ) } @@ -154,8 +154,8 @@ export class SnapSynchronizer extends Synchronizer { if (!equalsBytes(syncedRoot, snapTargetRoot)) { throw Error( `Invalid snap syncedRoot=${short(syncedRoot)} targetRoot=${short( - snapTargetRoot - )} for target height=${snapTargetHeight} hash=${short(snapTargetHash)}` + snapTargetRoot, + )} for target height=${snapTargetHeight} hash=${short(snapTargetHash)}`, ) // TODO: figure out what needs to be reinited // this.fetcherDoneFlags.accountFetcher.done = false; @@ -165,7 +165,7 @@ export class SnapSynchronizer extends Synchronizer { } const snapDoneMsg = `snapsync complete!!! height=${snapTargetHeight} root=${short( - snapTargetRoot + snapTargetRoot, )} hash=${short(snapTargetHash)}` if (fetchingAlreadyDone) { this.config.logger.debug(snapDoneMsg) @@ -223,7 +223,7 @@ export class SnapSynchronizer extends Synchronizer { this.fetcher === null ? '' : 'previous fetcher errored=' + this.fetcher.syncErrored?.message - }` + }`, ) this.fetcher = new AccountFetcher({ config: this.config, diff --git a/packages/client/src/sync/sync.ts b/packages/client/src/sync/sync.ts index 65741f07e9..53ce2d018c 100644 --- a/packages/client/src/sync/sync.ts +++ b/packages/client/src/sync/sync.ts @@ -123,7 +123,7 @@ export abstract class Synchronizer { this._syncedStatusCheckInterval = setInterval( this._syncedStatusCheck.bind(this), - this.SYNCED_STATE_REMOVAL_PERIOD + this.SYNCED_STATE_REMOVAL_PERIOD, ) const timeout = setTimeout(() => { @@ -161,7 +161,7 @@ export abstract class Synchronizer { return this.resolveSync() } catch (error: any) { this.config.logger.error( - `Received sync error, stopping sync and clearing fetcher: ${error.message ?? error}` + `Received sync error, stopping sync and clearing fetcher: ${error.message ?? error}`, ) this.clearFetcher() throw error diff --git a/packages/client/src/util/debug.ts b/packages/client/src/util/debug.ts index c4a549e83d..2226c849cc 100644 --- a/packages/client/src/util/debug.ts +++ b/packages/client/src/util/debug.ts @@ -38,7 +38,7 @@ const main = async () => { execution.hardfork }' }) const block = createBlockFromRLPSerializedBlock(hexToBytes('${bytesToHex( - block.serialize() + block.serialize(), )}'), { common }) const stateDB = new Level('${execution.config.getDataDirectory(DataDirectory.State)}') @@ -46,7 +46,7 @@ const main = async () => { const stateManager = new DefaultStateManager({ trie, common }) // Ensure we run on the right root stateManager.setStateRoot(hexToBytes('${bytesToHex( - await execution.vm.stateManager.getStateRoot() + await execution.vm.stateManager.getStateRoot(), )}')) diff --git a/packages/client/src/util/index.ts b/packages/client/src/util/index.ts index cf0326fb53..a3e42ade2d 100644 --- a/packages/client/src/util/index.ts +++ b/packages/client/src/util/index.ts @@ -22,8 +22,8 @@ export function getClientVersion() { const packageJson = JSON.parse( readFileSync( '/' + import.meta.url.split('client')[0].split('file:///')[1] + 'client/package.json', - 'utf-8' - ) + 'utf-8', + ), ) const { version } = process return `EthereumJS/${packageJson.version}/${platform()}/node${version.substring(1)}` diff --git a/packages/client/src/util/parse.ts b/packages/client/src/util/parse.ts index 28d27ac6dc..061f0157ae 100644 --- a/packages/client/src/util/parse.ts +++ b/packages/client/src/util/parse.ts @@ -7,7 +7,7 @@ import type { Multiaddr } from '@multiformats/multiaddr' // From: https://community.fortra.com/forums/intermapper/miscellaneous-topics/5acc4fcf-fa83-e511-80cf-0050568460e4 const ip6RegExp = new RegExp( - /((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))/ + /((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))/, ) /** diff --git a/packages/client/src/util/rpc.ts b/packages/client/src/util/rpc.ts index 9eb48cfc89..77d2d52baa 100644 --- a/packages/client/src/util/rpc.ts +++ b/packages/client/src/util/rpc.ts @@ -86,7 +86,7 @@ export function inspectParams(params: any, shorten?: number) { export function createRPCServer( manager: RPCManager, - opts: CreateRPCServerOpts + opts: CreateRPCServerOpts, ): CreateRPCServerReturn { const { methodConfig, rpcDebug, rpcDebugVerbose, logger } = opts const onRequest = (request: any) => { @@ -102,7 +102,7 @@ export function createRPCServer( logger?.info(`${request.method}${batchAddOn} responded with:\n${inspectParams(response)}`) } else if (checkFilter(request.method, rpcDebug)) { logger?.info( - `${request.method}${batchAddOn} responded with:\n${inspectParams(response, 125)}` + `${request.method}${batchAddOn} responded with:\n${inspectParams(response, 125)}`, ) } } diff --git a/packages/client/test/blockchain/chain.spec.ts b/packages/client/test/blockchain/chain.spec.ts index 2f6f945ca4..f684122bad 100644 --- a/packages/client/test/blockchain/chain.spec.ts +++ b/packages/client/test/blockchain/chain.spec.ts @@ -39,11 +39,11 @@ describe('[Chain]', () => { assert.equal( bytesToHex(chain.genesis.hash()), '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', - 'get chain.genesis' + 'get chain.genesis', ) assert.ok( equalsBytes(chain.genesis.hash(), chain.blocks.latest!.hash()), - 'get chain.block.latest' + 'get chain.block.latest', ) await chain.close() }) diff --git a/packages/client/test/cli/cli.spec.ts b/packages/client/test/cli/cli.spec.ts index cabf9ee261..18180c598b 100644 --- a/packages/client/test/cli/cli.spec.ts +++ b/packages/client/test/cli/cli.spec.ts @@ -11,7 +11,7 @@ import type { ChildProcessWithoutNullStreams } from 'child_process' export function clientRunHelper( cliArgs: string[], onData: (message: string, child: ChildProcessWithoutNullStreams, resolve: Function) => void, - shouldError = false + shouldError = false, ) { const file = require.resolve('../../bin/cli.ts') const child = spawn('tsx', [file, ...cliArgs]) @@ -36,7 +36,7 @@ describe('[CLI]', () => { if (message.includes('Initializing Ethereumjs client')) { assert.ok( message.includes('network=sepolia chainId=11155111'), - 'client is using custom inputs for network and network ID' + 'client is using custom inputs for network and network ID', ) child.kill(9) resolve(undefined) @@ -59,7 +59,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { // if http endpoint startup message detected, call http endpoint with RPC method @@ -71,7 +71,7 @@ describe('[CLI]', () => { const res = await client.request('eth_coinbase', [], 2.0) assert.ok( res.result === '0x7e5f4552091a69125d5dfcb7b8c2659029395bdf', - 'correct coinbase address set' + 'correct coinbase address set', ) count -= 1 } @@ -91,12 +91,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Invalid values')) { assert.ok( true, - 'client correctly throws error when "dev" option is passed in without a value' + 'client correctly throws error when "dev" option is passed in without a value', ) } child.kill(15) @@ -109,7 +109,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('cannot reuse')) { assert.ok(true, 'cannot reuse ports between HTTP and WS RPCs') @@ -125,7 +125,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { // if http endpoint startup message detected, call http endpoint with RPC method @@ -137,7 +137,7 @@ describe('[CLI]', () => { } catch (e: any) { assert( e.message.includes('Unauthorized: Error: Missing auth header'), - 'authentication failure shows that auth is defaulting to active' + 'authentication failure shows that auth is defaulting to active', ) } child.kill(15) @@ -157,13 +157,13 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { assert.ok(message.includes('engine'), 'engine rpc started') assert.ok( message.includes('rpcEngineAuth=false'), - 'auth is disabled according to client logs' + 'auth is disabled according to client logs', ) await wait(600) const client = Client.http({ port: 8553 }) @@ -187,14 +187,14 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { assert.ok(message.includes('engine'), 'engine rpc started') assert.ok(message.includes(customPort), 'custom port is being used') assert.ok( message.includes('rpcEngineAuth=false'), - 'auth is disabled according to client logs' + 'auth is disabled according to client logs', ) await wait(600) const client = Client.http({ port: Number(customPort) }) @@ -219,14 +219,14 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { assert.ok(message.includes('engine'), 'engine rpc started') assert.ok(message.includes('0.0.0.0'), 'custom address is being used') assert.ok( message.includes('rpcEngineAuth=false'), - 'auth is disabled according to client logs' + 'auth is disabled according to client logs', ) await wait(600) const client = Client.http({ hostname: '0.0.0.0', port: Number(customPort) }) @@ -252,12 +252,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('ws://') && message.includes('engine')) { assert.ok( message.includes('0.0.0.0:' + customPort), - 'client logs show correct custom address and port being used' + 'client logs show correct custom address and port being used', ) assert.ok(message.includes('engine'), 'engine ws started') await wait(600) @@ -286,7 +286,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('ws://')) { // if ws endpoint startup message detected, call ws endpoint with RPC method @@ -315,7 +315,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('http://')) { // if http endpoint startup message detected, call http endpoint with RPC method @@ -346,7 +346,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('address=http://')) { child.kill(15) @@ -369,7 +369,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('JSON-RPC: Supported Methods')) { assert.ok(message, 'logged out supported RPC methods') @@ -397,7 +397,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('DEBUG')) { assert.ok(message, 'debug logging is enabled') @@ -413,7 +413,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('account cache')) { assert.ok(message.includes('2000'), 'account cache option works') @@ -428,7 +428,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('storage cache')) { assert.ok(message.includes('2000'), 'storage cache option works') @@ -444,7 +444,7 @@ describe('[CLI]', () => { message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('code cache')) { assert.ok(message.includes('2000'), 'code cache option works') @@ -459,7 +459,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('trie cache')) { assert.ok(message.includes('2000'), 'trie cache option works') @@ -474,7 +474,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Reading bootnodes')) { assert.ok(message.includes('num=2'), 'passing bootnode.txt URL for bootnodes option works') @@ -490,12 +490,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Client started successfully')) { assert.ok( message.includes('Client started successfully'), - 'Clients started with experimental feature options' + 'Clients started with experimental feature options', ) child.kill(15) resolve(undefined) @@ -520,12 +520,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Client started successfully')) { assert.ok( message.includes('Client started successfully'), - 'Clients starts with client execution limits' + 'Clients starts with client execution limits', ) child.kill(15) resolve(undefined) @@ -547,7 +547,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Server listener up transport=rlpx')) { const [ip, port] = message @@ -584,12 +584,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Client started successfully')) { assert.ok( message.includes('Client started successfully'), - 'Clients starts with custom network options' + 'Clients starts with custom network options', ) await wait(600) const client = Client.http({ port: 8593 }) @@ -616,12 +616,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Serving light peer requests')) { assert.ok( message.includes('Serving light peer requests'), - 'client respects custom light-mode option' + 'client respects custom light-mode option', ) } if (message.includes('Starting FullEthereumService')) { @@ -630,7 +630,7 @@ describe('[CLI]', () => { if (message.includes('Client started successfully')) { assert.ok( message.includes('Client started successfully'), - 'Client starts with custom sync options' + 'Client starts with custom sync options', ) await wait(600) const client = Client.http({ port: 8548 }) @@ -735,12 +735,12 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Reading custom genesis state')) { assert.ok( message.includes('Reading custom genesis state'), - 'client respects custom genesis state file option' + 'client respects custom genesis state file option', ) } if (message.includes('Data directory')) { @@ -749,7 +749,7 @@ describe('[CLI]', () => { if (message.includes('Initializing Ethereumjs client')) { assert.ok( message.includes('network=customChain'), - 'Client respects custom chain parameters json file option' + 'Client respects custom chain parameters json file option', ) } if (message.includes('Client started successfully')) { @@ -770,7 +770,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Unknown argument: datadir')) { assert.ok(true, 'correctly errors on unknown arguments') @@ -785,7 +785,7 @@ describe('[CLI]', () => { const onData = async ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { if (message.includes('Arguments chainId and gethGenesis are mutually exclusive')) { assert.ok(true, 'correctly errors on conflicting arguments') diff --git a/packages/client/test/execution/vmexecution.spec.ts b/packages/client/test/execution/vmexecution.spec.ts index 48622702a4..882dd3e1b6 100644 --- a/packages/client/test/execution/vmexecution.spec.ts +++ b/packages/client/test/execution/vmexecution.spec.ts @@ -210,7 +210,7 @@ describe('[VMExecution]', () => { assert.equal( bytesToHex(block.hash()), bytesToHex(newHead.hash()), - 'vmHead should be on the latest block' + 'vmHead should be on the latest block', ) // reset head and run again @@ -219,7 +219,7 @@ describe('[VMExecution]', () => { assert.equal( bytesToHex(oldHead.hash()), bytesToHex(newHead.hash()), - 'vmHead should be on the latest block' + 'vmHead should be on the latest block', ) await execution.run() @@ -227,7 +227,7 @@ describe('[VMExecution]', () => { assert.equal( bytesToHex(block.hash()), bytesToHex(newHead.hash()), - 'vmHead should be on the latest block' + 'vmHead should be on the latest block', ) closeRPC(server) diff --git a/packages/client/test/ext/jwt-simple.spec.ts b/packages/client/test/ext/jwt-simple.spec.ts index 3fa9197a2f..c0af86a255 100644 --- a/packages/client/test/ext/jwt-simple.spec.ts +++ b/packages/client/test/ext/jwt-simple.spec.ts @@ -94,7 +94,7 @@ describe('decode', function () { const obj2 = jwt.decode(token, key, false, 'HS512') expect(obj2).to.eql(obj) expect(jwt.decode.bind(null, token, key, false, 'HS256')).toThrowError( - /Signature verification failed/ + /Signature verification failed/, ) }) diff --git a/packages/client/test/integration/fullethereumservice.spec.ts b/packages/client/test/integration/fullethereumservice.spec.ts index 15d6427517..c1ff4edc12 100644 --- a/packages/client/test/integration/fullethereumservice.spec.ts +++ b/packages/client/test/integration/fullethereumservice.spec.ts @@ -88,7 +88,7 @@ describe( difficulty: 1, }, }, - { common: config.chainCommon } + { common: config.chainCommon }, ) peer.eth!.send('NewBlock', [block, BigInt(1)]) @@ -97,12 +97,12 @@ describe( const tx = create1559FeeMarketTxFromRLP(toBytes(txData)) await service.execution.vm.stateManager.putAccount( tx.getSenderAddress(), - new Account(BigInt(0), BigInt('40000000000100000')) + new Account(BigInt(0), BigInt('40000000000100000')), ) await service.txPool.add(tx) service.config.chainCommon.getHardforkBy = td.func() td.when(service.config.chainCommon.getHardforkBy(td.matchers.anything())).thenReturn( - Hardfork.London + Hardfork.London, ) const [_, txs] = await peer.eth!.getPooledTransactions({ hashes: [tx.hash()] }) it('should handle GetPooledTransactions', async () => { @@ -111,7 +111,7 @@ describe( peer.eth!.send('Transactions', [tx]) }, - { timeout: 30000 } + { timeout: 30000 }, ) describe('should handle LES requests', async () => { @@ -122,7 +122,7 @@ describe('should handle LES requests', async () => { assert.equal( bytesToHex(headers[1].hash()), '0xa321d27cd2743617c1c1b0d7ecb607dd14febcdfca8f01b79c3f0249505ea069', - 'handled GetBlockHeaders' + 'handled GetBlockHeaders', ) }) await destroy(server, service) diff --git a/packages/client/test/integration/lightsync.spec.backup.ts b/packages/client/test/integration/lightsync.spec.backup.ts index 4ed1149672..1c1f3cb862 100644 --- a/packages/client/test/integration/lightsync.spec.backup.ts +++ b/packages/client/test/integration/lightsync.spec.backup.ts @@ -29,7 +29,7 @@ describe( }) await localService.synchronizer!.start() }, - { timeout: 30000 } + { timeout: 30000 }, ) describe( @@ -56,7 +56,7 @@ describe( assert.ok('did not sync') }) }, - { timeout: 30000 } + { timeout: 30000 }, ) describe( @@ -90,5 +90,5 @@ describe( }) await localService.synchronizer!.start() }, - { timeout: 30000 } + { timeout: 30000 }, ) diff --git a/packages/client/test/integration/merge.spec.ts b/packages/client/test/integration/merge.spec.ts index f9702dcaec..79215397bc 100644 --- a/packages/client/test/integration/merge.spec.ts +++ b/packages/client/test/integration/merge.spec.ts @@ -43,7 +43,7 @@ const commonPoA = createCustomCommon( }, ], }, - { baseChain: ChainCommon.Goerli, hardfork: Hardfork.London } + { baseChain: ChainCommon.Goerli, hardfork: Hardfork.London }, ) const commonPoW = createCustomCommon( { @@ -64,7 +64,7 @@ const commonPoW = createCustomCommon( }, ], }, - { baseChain: ChainCommon.Mainnet, hardfork: Hardfork.London } + { baseChain: ChainCommon.Mainnet, hardfork: Hardfork.London }, ) const accounts: [Address, Uint8Array][] = [ [ @@ -129,7 +129,7 @@ describe('should mine and stop at the merge (PoA)', async () => { assert.equal( remoteService.chain.headers.td, targetTTD, - 'synced blocks to the merge successfully' + 'synced blocks to the merge successfully', ) // Make sure the miner has stopped assert.notOk(service.miner!.running, 'miner should not be running') @@ -169,7 +169,7 @@ describe('should mine and stop at the merge (PoW)', async () => { assert.equal( remoteService.chain.headers.height, terminalHeight, - 'synced blocks to the merge successfully' + 'synced blocks to the merge successfully', ) // Make sure the miner has stopped assert.notOk(service.miner!.running, 'miner should not be running') diff --git a/packages/client/test/integration/miner.spec.ts b/packages/client/test/integration/miner.spec.ts index a92685eedf..bb75b08435 100644 --- a/packages/client/test/integration/miner.spec.ts +++ b/packages/client/test/integration/miner.spec.ts @@ -26,7 +26,7 @@ const hardforks = new Common({ chain: ChainCommon.Goerli }) .map((h) => h.name === Hardfork.London ? { ...h, block: 0, timestamp: undefined } - : { ...h, timestamp: undefined } + : { ...h, timestamp: undefined }, ) const common = createCustomCommon( { @@ -40,7 +40,7 @@ const common = createCustomCommon( }, }, }, - { baseChain: ChainCommon.Goerli, hardfork: Hardfork.London } + { baseChain: ChainCommon.Goerli, hardfork: Hardfork.London }, ) const accounts: [Address, Uint8Array][] = [ [ @@ -103,7 +103,7 @@ describe( assert.equal( remoteService.chain.blocks.height, targetHeight, - 'synced blocks successfully' + 'synced blocks successfully', ) }) await destroy(server, service) @@ -115,5 +115,5 @@ describe( }) }) }, - { timeout: 25000 } + { timeout: 25000 }, ) diff --git a/packages/client/test/integration/mocks/mockchain.ts b/packages/client/test/integration/mocks/mockchain.ts index d0c888d4d1..7a1c12bea8 100644 --- a/packages/client/test/integration/mocks/mockchain.ts +++ b/packages/client/test/integration/mocks/mockchain.ts @@ -38,7 +38,7 @@ export class MockChain extends Chain { parentHash: number ? blocks[number - 1].hash() : this.genesis.hash(), }, }, - { common } + { common }, ) blocks.push(block) } diff --git a/packages/client/test/integration/mocks/mockpeer.ts b/packages/client/test/integration/mocks/mockpeer.ts index 75d3461fd5..fbaf0f5d04 100644 --- a/packages/client/test/integration/mocks/mockpeer.ts +++ b/packages/client/test/integration/mocks/mockpeer.ts @@ -79,7 +79,7 @@ export class MockPeer extends Peer { if (!(stream.protocols as string[]).includes(`${p.name}/${p.versions[0]}`)) return await p.open() await this.addProtocol(new MockSender(p.name, pushableFn, receiver), p) - }) + }), ) this.connected = true } diff --git a/packages/client/test/integration/mocks/network.ts b/packages/client/test/integration/mocks/network.ts index db67d2477d..1bc30a5583 100644 --- a/packages/client/test/integration/mocks/network.ts +++ b/packages/client/test/integration/mocks/network.ts @@ -64,7 +64,7 @@ export function createStream(id: string, location: string, protocols: string[]) servers[location].streams[id] = stream setTimeout( () => servers[location].server.emit('connection', { id, stream: stream.local(id) }), - 10 + 10, ) return stream.remote(location) } diff --git a/packages/client/test/integration/peerpool.spec.ts b/packages/client/test/integration/peerpool.spec.ts index 583e9f425b..a875386595 100644 --- a/packages/client/test/integration/peerpool.spec.ts +++ b/packages/client/test/integration/peerpool.spec.ts @@ -81,7 +81,7 @@ describe('should handle peer messages', async () => { config.events.on(Event.POOL_PEER_ADDED, (peer: any) => it('should add peer', () => { assert.equal(peer.id, 'peer0', 'added peer') - }) + }), ) config.events.on(Event.PROTOCOL_MESSAGE, (msg: any, proto: any, peer: any) => { it('should get message', () => { diff --git a/packages/client/test/integration/util.ts b/packages/client/test/integration/util.ts index 7d467505b4..34abf6da7c 100644 --- a/packages/client/test/integration/util.ts +++ b/packages/client/test/integration/util.ts @@ -22,7 +22,7 @@ interface SetupOptions { } export async function setup( - options: SetupOptions = {} + options: SetupOptions = {}, ): Promise<[MockServer, FullEthereumService | LightEthereumService]> { const { location, height, interval, syncmode } = options const minPeers = options.minPeers ?? 1 @@ -86,7 +86,7 @@ export async function setup( export async function destroy( server: MockServer, - service: FullEthereumService | LightEthereumService + service: FullEthereumService | LightEthereumService, ): Promise { service.config.events.emit(Event.CLIENT_SHUTDOWN) await server.stop() diff --git a/packages/client/test/logging.spec.ts b/packages/client/test/logging.spec.ts index 5f48ea5b5e..b5542e9e56 100644 --- a/packages/client/test/logging.spec.ts +++ b/packages/client/test/logging.spec.ts @@ -9,11 +9,11 @@ describe('[Logging]', () => { it('should have correct transports', () => { assert.ok( logger.transports.find((t: any) => t.name === 'console') !== undefined, - 'should have stdout transport' + 'should have stdout transport', ) assert.ok( logger.transports.find((t: any) => t.name === 'file') !== undefined, - 'should have file transport' + 'should have file transport', ) }) @@ -24,11 +24,11 @@ describe('[Logging]', () => { e.level = 'error' assert.ok( /an error\n {4}at/.test((format.transform(e) as any).message), - 'log message should contain stack trace (1)' + 'log message should contain stack trace (1)', ) assert.ok( /an error\n {4}at/.test((format.transform({ level: 'error', message: e }) as any).message), - 'log message should contain stack trace (2)' + 'log message should contain stack trace (2)', ) } }) @@ -45,7 +45,7 @@ describe('[Logging]', () => { assert.equal( message, 'test \x1B[38;2;0;128;0mkey\x1B[39m=value ', - 'key=value pairs should be colorized' + 'key=value pairs should be colorized', ) }) }) diff --git a/packages/client/test/miner/miner.spec.ts b/packages/client/test/miner/miner.spec.ts index e3868c7cb7..0fa1c2e97b 100644 --- a/packages/client/test/miner/miner.spec.ts +++ b/packages/client/test/miner/miner.spec.ts @@ -168,7 +168,7 @@ const createTx = ( value = 1, gasPrice = 1000000000, gasLimit = 100000, - common = customCommon + common = customCommon, ) => { const txData = { nonce, @@ -191,7 +191,7 @@ const txA011 = createTx( 1, 1000000000, 100000, - goerliCommon + goerliCommon, ) // A -> B, nonce: 0, value: 1, normal gasPrice const txA02 = createTx(A, B, 1, 1, 2000000000) // A -> B, nonce: 1, value: 1, 2x gasPrice @@ -287,7 +287,7 @@ describe('assembleBlocks() -> with a hardfork mismatching tx', async () => { assert.equal( blocks[0].transactions.length, 0, - 'new block should not include tx due to hardfork mismatch' + 'new block should not include tx due to hardfork mismatch', ) assert.equal(txPool.txsInPool, 1, 'transaction should remain in pool') }) @@ -455,7 +455,7 @@ describe('assembleBlocks() -> should not include tx under the baseFee', async () // the default block baseFee will be 7 // add tx with maxFeePerGas of 6 const tx = create1559FeeMarketTx({ to: B.address, maxFeePerGas: 6 }, { common }).sign( - A.privateKey + A.privateKey, ) try { await txPool.add(tx, true) @@ -480,7 +480,7 @@ describe("assembleBlocks() -> should stop assembling a block after it's full", a const gasLimit = 100000 const block = createBlockFromBlockData( { header: { gasLimit } }, - { common: customCommon, setHardfork: true } + { common: customCommon, setHardfork: true }, ) Object.defineProperty(chain, 'headers', { get() { @@ -509,11 +509,11 @@ describe("assembleBlocks() -> should stop assembling a block after it's full", a const data = '0xfe' // INVALID opcode, consumes all gas const tx1FillsBlockGasLimit = createLegacyTx( { gasLimit: gasLimit - 1, data, gasPrice: BigInt('1000000000') }, - { common: customCommon } + { common: customCommon }, ).sign(A.privateKey) const tx2ExceedsBlockGasLimit = createLegacyTx( { gasLimit: 21000, to: B.address, nonce: 1, gasPrice: BigInt('1000000000') }, - { common: customCommon } + { common: customCommon }, ).sign(A.privateKey) await txPool.add(tx1FillsBlockGasLimit) await txPool.add(tx2ExceedsBlockGasLimit) diff --git a/packages/client/test/miner/pendingBlock.spec.ts b/packages/client/test/miner/pendingBlock.spec.ts index fd4f87ca1b..331c899804 100644 --- a/packages/client/test/miner/pendingBlock.spec.ts +++ b/packages/client/test/miner/pendingBlock.spec.ts @@ -107,7 +107,7 @@ describe('[PendingBlock]', async () => { nonce = 0, value = 1, gasPrice = 1000000000, - gasLimit = 100000 + gasLimit = 100000, ) => { const txData = { nonce, @@ -150,7 +150,7 @@ describe('[PendingBlock]', async () => { assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after build' + 'should reset the pending payload after build', ) }) @@ -171,10 +171,10 @@ describe('[PendingBlock]', async () => { const payload = pendingBlock.pendingPayloads.get(bytesToHex(payloadId)) assert.equal( (payload as any).transactions.filter( - (tx: TypedTransaction) => bytesToHex(tx.hash()) === bytesToHex(txA011.hash()) + (tx: TypedTransaction) => bytesToHex(tx.hash()) === bytesToHex(txA011.hash()), ).length, 1, - 'txA011 should be in block' + 'txA011 should be in block', ) txB011.common.setHardfork(Hardfork.Paris) @@ -187,16 +187,16 @@ describe('[PendingBlock]', async () => { assert.equal(block?.transactions.length, 2, 'should include txs from pool') assert.equal( (payload as any).transactions.filter( - (tx: TypedTransaction) => bytesToHex(tx.hash()) === bytesToHex(txB011.hash()) + (tx: TypedTransaction) => bytesToHex(tx.hash()) === bytesToHex(txB011.hash()), ).length, 1, - 'txB011 should be in block' + 'txB011 should be in block', ) pendingBlock.pruneSetToMax(0) assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after build' + 'should reset the pending payload after build', ) }) @@ -213,7 +213,7 @@ describe('[PendingBlock]', async () => { assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after stopping' + 'should reset the pending payload after stopping', ) }) @@ -242,7 +242,7 @@ describe('[PendingBlock]', async () => { gasPrice: 1000000000, nonce: 2, }, - { common } + { common }, ).sign(A.privateKey) await txPool.add(txA03) const pendingBlock = new PendingBlock({ config, txPool, skipHardForkValidation: true }) @@ -259,14 +259,14 @@ describe('[PendingBlock]', async () => { assert.equal( block?.transactions.length, 2, - 'should include txs from pool that fit in the block' + 'should include txs from pool that fit in the block', ) assert.equal(receipts.length, 2, 'receipts should match number of transactions') pendingBlock.pruneSetToMax(0) assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after build' + 'should reset the pending payload after build', ) // reset gas Limit @@ -286,7 +286,7 @@ describe('[PendingBlock]', async () => { gasPrice: 1000000000, nonce: 2, }, - { common } + { common }, ).sign(A.privateKey) await txPool.add(txA03) const pendingBlock = new PendingBlock({ config, txPool, skipHardForkValidation: true }) @@ -301,14 +301,14 @@ describe('[PendingBlock]', async () => { assert.equal( block?.transactions.length, 2, - 'should include txs from pool that fit in the block' + 'should include txs from pool that fit in the block', ) assert.equal(receipts.length, 2, 'receipts should match number of transactions') pendingBlock.pruneSetToMax(0) assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after build' + 'should reset the pending payload after build', ) }) @@ -327,14 +327,14 @@ describe('[PendingBlock]', async () => { assert.equal( block.transactions.length, 0, - 'should not include tx with sender that has insufficient funds' + 'should not include tx with sender that has insufficient funds', ) assert.equal(receipts.length, 0, 'receipts should match number of transactions') pendingBlock.pruneSetToMax(0) assert.equal( pendingBlock.pendingPayloads.size, 0, - 'should reset the pending payload after build' + 'should reset the pending payload after build', ) }) @@ -350,7 +350,7 @@ describe('[PendingBlock]', async () => { } catch (err: any) { assert.equal( err.message, - 'cannot get iterator head: blockchain has no getTotalDifficulty function' + 'cannot get iterator head: blockchain has no getTotalDifficulty function', ) } }) @@ -391,7 +391,7 @@ describe('[PendingBlock]', async () => { to: randomBytes(20), nonce: BigInt(x), }, - { common } + { common }, ).sign(A.privateKey) await txPool.add(txA01) } @@ -405,7 +405,7 @@ describe('[PendingBlock]', async () => { to: randomBytes(20), nonce: BigInt(3), }, - { common } + { common }, ).sign(A.privateKey) await txPool.add(txNorm) @@ -464,7 +464,7 @@ describe('[PendingBlock]', async () => { to: randomBytes(20), nonce: BigInt(0), }, - { common } + { common }, ).sign(A.privateKey) await txPool.add(missingBlobTx) diff --git a/packages/client/test/net/peer/peer.spec.ts b/packages/client/test/net/peer/peer.spec.ts index 54ff58a5b6..c703effd5b 100644 --- a/packages/client/test/net/peer/peer.spec.ts +++ b/packages/client/test/net/peer/peer.spec.ts @@ -28,13 +28,13 @@ describe('[Peer]', () => { assert.equal( peer.toString(true), 'id=0123456789abcdef address=address0 transport=transport0 inbound=true', - 'correct full id string' + 'correct full id string', ) peer.inbound = false assert.equal( peer.toString(), 'id=01234567 address=address0 transport=transport0 inbound=false', - 'correct short id string' + 'correct short id string', ) }) }) diff --git a/packages/client/test/net/peer/rlpxpeer.spec.ts b/packages/client/test/net/peer/rlpxpeer.spec.ts index e664039871..65525ffe18 100644 --- a/packages/client/test/net/peer/rlpxpeer.spec.ts +++ b/packages/client/test/net/peer/rlpxpeer.spec.ts @@ -52,7 +52,7 @@ describe('[RlpxPeer]', async () => { { name: 'les', version: 4, length: 23 }, { name: 'snap', version: 1, length: 8 }, ], - 'correct capabilities' + 'correct capabilities', ) }) @@ -95,10 +95,10 @@ describe('[RlpxPeer]', async () => { }) peer.config.events.on(Event.PEER_CONNECTED, (peer) => - assert.equal(peer.id, 'abcdef0123', 'got connected') + assert.equal(peer.id, 'abcdef0123', 'got connected'), ) peer.config.events.on(Event.PEER_DISCONNECTED, (rlpxPeer) => - assert.equal(rlpxPeer.pooled, false, 'got disconnected') + assert.equal(rlpxPeer.pooled, false, 'got disconnected'), ) peer.rlpx!.events.emit('peer:error', rlpxPeer, new Error('err0')) peer.rlpx!.events.emit('peer:added', rlpxPeer) diff --git a/packages/client/test/net/peerpool.spec.ts b/packages/client/test/net/peerpool.spec.ts index 70339910ec..a066c3531d 100644 --- a/packages/client/test/net/peerpool.spec.ts +++ b/packages/client/test/net/peerpool.spec.ts @@ -82,7 +82,7 @@ describe('should get idle peers', () => { assert.equal( pool.idle((p: any) => p.id > 1), peers[1], - 'correct idle peer with filter' + 'correct idle peer with filter', ) }) }) diff --git a/packages/client/test/net/protocol/ethprotocol.spec.ts b/packages/client/test/net/protocol/ethprotocol.spec.ts index 01dd00fe1e..fb6ef7ce84 100644 --- a/packages/client/test/net/protocol/ethprotocol.spec.ts +++ b/packages/client/test/net/protocol/ethprotocol.spec.ts @@ -59,7 +59,7 @@ describe('[EthProtocol]', () => { genesisHash: '0xbb', latestBlock: hexToBytes('0x0a'), }, - 'encode status' + 'encode status', ) const status = p.decodeStatus({ chainId: [0x01], @@ -72,7 +72,7 @@ describe('[EthProtocol]', () => { status.td === BigInt(100) && status.bestHash === '0xaa' && status.genesisHash === '0xbb', - 'decode status' + 'decode status', ) }) @@ -129,7 +129,7 @@ describe('[EthProtocol]', () => { gasLimit: 100, value: 6, }, - { common: config.chainCommon } + { common: config.chainCommon }, ) const res = p.encode(p.messages.filter((message) => message.name === 'PooledTransactions')[0], { reqId: BigInt(1), @@ -184,10 +184,10 @@ describe('[EthProtocol]', () => { assert.equal(bytesToBigInt(res[0]), BigInt(1), 'correctly encoded reqId') const expectedSerializedReceipts = [ hexToBytes( - '0x02f9016d0164b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f866f864940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a001010101010101010101010101010101010101010101010101010101010101018a00000000000000000000' + '0x02f9016d0164b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f866f864940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a001010101010101010101010101010101010101010101010101010101010101018a00000000000000000000', ), hexToBytes( - '0xf9016f808203e8b9010001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101f866f864940101010101010101010101010101010101010101f842a00101010101010101010101010101010101010101010101010101010101010101a001010101010101010101010101010101010101010101010101010101010101018a00000000000000000000' + '0xf9016f808203e8b9010001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101f866f864940101010101010101010101010101010101010101f842a00101010101010101010101010101010101010101010101010101010101010101a001010101010101010101010101010101010101010101010101010101010101018a00000000000000000000', ), ] assert.deepEqual(res[1], expectedSerializedReceipts, 'correctly encoded receipts') @@ -225,7 +225,7 @@ describe('[EthProtocol]', () => { const eip1559Tx = createTxFromTxData({ type: 2 }, { common: config.chainCommon }) const blobTx = createTxFromTxData( { type: 3, to: Address.zero(), blobVersionedHashes: [hexToBytes(`0x01${'00'.repeat(31)}`)] }, - { common: config.chainCommon } + { common: config.chainCommon }, ) const res = p.encode(p.messages.filter((message) => message.name === 'Transactions')[0], [ legacyTx, @@ -239,7 +239,7 @@ describe('[EthProtocol]', () => { const decoded = p.decode( p.messages.filter((message) => message.name === 'Transactions')[0], - res + res, ) assert.deepEqual(decoded[0].type, legacyTx.type, 'decoded legacy tx correctly') assert.deepEqual(decoded[1].type, eip2929Tx.type, 'decoded eip2929 tx correctly') @@ -259,23 +259,23 @@ describe('[EthProtocol]', () => { const fakeHash = fakeTx.hash() const encoded = p.encode( p.messages.filter((message) => message.name === 'NewPooledTransactionHashes')[0], - [fakeHash] + [fakeHash], ) const encodedEth68 = p.encode( p.messages.filter((message) => message.name === 'NewPooledTransactionHashes')[0], - [[fakeTx.type], [fakeTx.serialize().byteLength], [fakeHash]] + [[fakeTx.type], [fakeTx.serialize().byteLength], [fakeHash]], ) assert.deepEqual(encoded[0], fakeHash, 'encoded hash correctly with pre-eth/68 format') assert.deepEqual(encodedEth68[2][0], fakeHash, 'encoded hash correctly with eth/68 format') const decoded = p.decode( p.messages.filter((message) => message.name === 'NewPooledTransactionHashes')[0], - encoded + encoded, ) const decodedEth68 = p.decode( p.messages.filter((message) => message.name === 'NewPooledTransactionHashes')[0], - encodedEth68 + encodedEth68, ) assert.deepEqual(decoded[0], fakeHash, 'decoded hash correctly with pre-eth/68 format') assert.deepEqual(decodedEth68[2][0], fakeHash, 'decoded hash correctly with eth/68 format') diff --git a/packages/client/test/net/protocol/lesprotocol.spec.ts b/packages/client/test/net/protocol/lesprotocol.spec.ts index e147f4b5b7..e142c9cdf3 100644 --- a/packages/client/test/net/protocol/lesprotocol.spec.ts +++ b/packages/client/test/net/protocol/lesprotocol.spec.ts @@ -82,7 +82,7 @@ describe('[LesProtocol]', () => { bytesToHex(status['flowControl/MRC'][0][0]) === '0x02' && bytesToHex(status['flowControl/MRC'][0][1]) === '0x0a' && bytesToHex(status['flowControl/MRC'][0][2]) === '0x0a', - 'encode status' + 'encode status', ) status = { ...status, chainId: [0x01] } status = p.decodeStatus(status) @@ -105,7 +105,7 @@ describe('[LesProtocol]', () => { status.mrc['2'].req === 10 && status.mrc.GetBlockHeaders.base === 10 && status.mrc.GetBlockHeaders.req === 10, - 'decode status' + 'decode status', ) }) }) diff --git a/packages/client/test/net/protocol/snapprotocol.spec.ts b/packages/client/test/net/protocol/snapprotocol.spec.ts index 3f6a7d6bf2..43b30fda1f 100644 --- a/packages/client/test/net/protocol/snapprotocol.spec.ts +++ b/packages/client/test/net/protocol/snapprotocol.spec.ts @@ -57,34 +57,34 @@ describe('[SnapProtocol]', () => { origin, limit, bytes, - } + }, ) assert.ok( JSON.stringify(payload[0]) === JSON.stringify(bigIntToBytes(BigInt(1))), - 'correctly encoded reqId' + 'correctly encoded reqId', ) assert.ok( JSON.stringify(payload[1]) === JSON.stringify(setLengthLeft(root, 32)), - 'correctly encoded root' + 'correctly encoded root', ) assert.ok(JSON.stringify(payload[2]) === JSON.stringify(origin), 'correctly encoded origin') assert.ok(JSON.stringify(payload[3]) === JSON.stringify(limit), 'correctly encoded limit') assert.ok( JSON.stringify(payload[4]) === JSON.stringify(bigIntToBytes(bytes)), - 'correctly encoded bytes' + 'correctly encoded bytes', ) assert.ok(payload) const res = p.decode( p.messages.filter((message) => message.name === 'GetAccountRange')[0], - payload + payload, ) assert.ok(JSON.stringify(res.reqId) === JSON.stringify(reqId), 'correctly decoded reqId') assert.ok( JSON.stringify(res.root) === JSON.stringify(setLengthLeft(root, 32)), - 'correctly decoded root' + 'correctly decoded root', ) assert.ok(JSON.stringify(res.origin) === JSON.stringify(origin), 'correctly decoded origin') assert.ok(JSON.stringify(res.limit) === JSON.stringify(limit), 'correctly decoded limit') @@ -100,7 +100,7 @@ describe('[SnapProtocol]', () => { const data = RLP.decode(hexToBytes(contractAccountRangeRLP)) as unknown const { reqId, accounts, proof } = p.decode( p.messages.filter((message) => message.name === 'AccountRange')[0], - data + data, ) assert.ok(reqId === BigInt(1), 'reqId should be 1') assert.ok(accounts.length === 2, 'accounts should be 2') @@ -114,23 +114,23 @@ describe('[SnapProtocol]', () => { assert.ok( bytesToHex(secondAccount[2]) === '0x3dc6d3cfdc6210b8591ea852961d880821298c7891dea399e02d87550af9d40e', - 'storageHash of the second account' + 'storageHash of the second account', ) assert.ok( bytesToHex(secondAccount[3]) === '0xe68fe0bb7c4a483affd0f19cc2b989105242bd6b256c6de3afd738f8acd80c66', - 'codeHash of the second account' + 'codeHash of the second account', ) const payload = RLP.encode( p.encode(p.messages.filter((message) => message.name === 'AccountRange')[0], { reqId, accounts, proof, - }) + }), ) assert.ok( contractAccountRangeRLP === bytesToHex(payload), - 'Re-encoded payload should match with original' + 'Re-encoded payload should match with original', ) }) @@ -144,7 +144,7 @@ describe('[SnapProtocol]', () => { const fullData = pFull.decode( pFull.messages.filter((message) => message.name === 'AccountRange')[0], - resData + resData, ) const { accounts: accountsFull } = fullData assert.ok(accountsFull.length === 3, '3 accounts should be decoded in accountsFull') @@ -156,11 +156,11 @@ describe('[SnapProtocol]', () => { // we shpuld get slim format const slimPayload = pFull.encode( pFull.messages.filter((message) => message.name === 'AccountRange')[0], - fullData + fullData, ) const { accounts: accountsSlim } = pSlim.decode( pSlim.messages.filter((message) => message.name === 'AccountRange')[0], - slimPayload + slimPayload, ) // 3 accounts are there in accountRangeRLP @@ -179,13 +179,13 @@ describe('[SnapProtocol]', () => { const reqData = RLP.decode(hexToBytes(getAccountRangeRLP)) const { root: stateRoot } = p.decode( p.messages.filter((message) => message.name === 'GetAccountRange')[0], - reqData + reqData, ) // accountRangeRLP is the corresponding response to getAccountRangeRLP const resData = RLP.decode(hexToBytes(accountRangeRLP)) const { accounts, proof } = p.decode( p.messages.filter((message) => message.name === 'AccountRange')[0], - resData + resData, ) try { @@ -199,7 +199,7 @@ describe('[SnapProtocol]', () => { } assert.ok( equalsBytes(keccak256(proof[0]), stateRoot), - 'Proof should link to the requested stateRoot' + 'Proof should link to the requested stateRoot', ) }) @@ -226,38 +226,38 @@ describe('[SnapProtocol]', () => { origin, limit, bytes, - } + }, ) assert.ok( JSON.stringify(payload[0]) === JSON.stringify(bigIntToBytes(BigInt(1))), - 'correctly encoded reqId' + 'correctly encoded reqId', ) assert.ok( JSON.stringify(payload[1]) === JSON.stringify(setLengthLeft(root, 32)), - 'correctly encoded root' + 'correctly encoded root', ) assert.ok(JSON.stringify(payload[2]) === JSON.stringify(accounts), 'correctly encoded accounts') assert.ok(JSON.stringify(payload[3]) === JSON.stringify(origin), 'correctly encoded origin') assert.ok(JSON.stringify(payload[4]) === JSON.stringify(limit), 'correctly encoded limit') assert.ok( JSON.stringify(payload[5]) === JSON.stringify(bigIntToBytes(bytes)), - 'correctly encoded bytes' + 'correctly encoded bytes', ) assert.ok(payload) const res = p.decode( p.messages.filter((message) => message.name === 'GetStorageRanges')[0], - payload + payload, ) assert.ok(JSON.stringify(res.reqId) === JSON.stringify(reqId), 'correctly decoded reqId') assert.ok( JSON.stringify(res.root) === JSON.stringify(setLengthLeft(root, 32)), - 'correctly decoded root' + 'correctly decoded root', ) assert.ok( JSON.stringify(res.accounts) === JSON.stringify(accounts), - 'correctly decoded accounts' + 'correctly decoded accounts', ) assert.ok(JSON.stringify(res.origin) === JSON.stringify(origin), 'correctly decoded origin') assert.ok(JSON.stringify(res.limit) === JSON.stringify(limit), 'correctly decoded limit') @@ -274,14 +274,14 @@ describe('[SnapProtocol]', () => { const data = RLP.decode(hexToBytes(storageRangesRLP)) as unknown const { reqId, slots, proof } = p.decode( p.messages.filter((message) => message.name === 'StorageRanges')[0], - data + data, ) assert.ok(reqId === BigInt(1), 'correctly decoded reqId') assert.ok(slots.length === 1 && slots[0].length === 3, 'correctly decoded slots') const { hash, body } = slots[0][2] assert.ok( bytesToHex(hash) === '0x60264186ee63f748d340388f07b244d96d007fff5cbc397bbd69f8747c421f79', - 'Slot 3 key' + 'Slot 3 key', ) assert.ok(bytesToHex(body) === '0x8462b66ae7', 'Slot 3 value') @@ -290,11 +290,11 @@ describe('[SnapProtocol]', () => { reqId, slots, proof, - }) + }), ) assert.ok( storageRangesRLP === bytesToHex(payload), - 'Re-encoded payload should match with original' + 'Re-encoded payload should match with original', ) }) @@ -307,7 +307,7 @@ describe('[SnapProtocol]', () => { const accountsData = RLP.decode(hexToBytes(contractAccountRangeRLP)) const { accounts } = p.decode( p.messages.filter((message) => message.name === 'AccountRange')[0], - accountsData + accountsData, ) const lastAccount = accounts[accounts.length - 1] @@ -315,7 +315,7 @@ describe('[SnapProtocol]', () => { const data = RLP.decode(hexToBytes(storageRangesRLP)) const { proof, slots } = p.decode( p.messages.filter((message) => message.name === 'StorageRanges')[0], - data + data, ) // storageRangesRLP response is to the lastAccount's slots so slots[0] are the slots of // lastAccount @@ -333,14 +333,14 @@ describe('[SnapProtocol]', () => { proof, { useKeyHashingFunction: keccak256, - } + }, ) } catch (e) { assert.fail(`StorageRange proof verification failed with message=${(e as Error).message}`) } assert.ok( equalsBytes(keccak256(proof[0]), lastAccountStorageRoot), - 'Proof should link to the accounts storageRoot' + 'Proof should link to the accounts storageRoot', ) }) @@ -363,18 +363,18 @@ describe('[SnapProtocol]', () => { assert.ok( JSON.stringify(payload[0]) === JSON.stringify(bigIntToBytes(BigInt(1))), - 'correctly encoded reqId' + 'correctly encoded reqId', ) assert.ok(JSON.stringify(payload[1]) === JSON.stringify(hashes), 'correctly encoded hashes') assert.ok( JSON.stringify(payload[2]) === JSON.stringify(bigIntToBytes(bytes)), - 'correctly encoded bytes' + 'correctly encoded bytes', ) assert.ok(payload) const res = p.decode( p.messages.filter((message) => message.name === 'GetByteCodes')[0], - payload + payload, ) assert.ok(JSON.stringify(res.reqId) === JSON.stringify(reqId), 'correctly decoded reqId') @@ -391,7 +391,7 @@ describe('[SnapProtocol]', () => { const codesRes = RLP.decode(hexToBytes(byteCodesRLP)) const { reqId, codes } = p.decode( p.messages.filter((message) => message.name === 'ByteCodes')[0], - codesRes + codesRes, ) assert.ok(reqId === BigInt(1), 'reqId should be 1') @@ -401,7 +401,7 @@ describe('[SnapProtocol]', () => { p.encode(p.messages.filter((message) => message.name === 'ByteCodes')[0], { reqId, codes, - }) + }), ) assert.ok(byteCodesRLP === bytesToHex(payload), 'Re-encoded payload should match with original') }) @@ -415,13 +415,13 @@ describe('[SnapProtocol]', () => { const codesReq = RLP.decode(hexToBytes(getByteCodesRLP)) const { hashes } = p.decode( p.messages.filter((message) => message.name === 'GetByteCodes')[0], - codesReq + codesReq, ) const codeHash = hashes[0] const codesRes = RLP.decode(hexToBytes(byteCodesRLP)) const { codes } = p.decode( p.messages.filter((message) => message.name === 'ByteCodes')[0], - codesRes + codesRes, ) const code = codes[0] assert.ok(equalsBytes(keccak256(code), codeHash), 'Code should match the requested codeHash') @@ -446,19 +446,19 @@ describe('[SnapProtocol]', () => { assert.ok( JSON.stringify(payload[0]) === JSON.stringify(bigIntToBytes(reqId)), - 'correctly encoded reqId' + 'correctly encoded reqId', ) assert.ok(JSON.stringify(payload[1]) === JSON.stringify(root), 'correctly encoded root') assert.ok(JSON.stringify(payload[2]) === JSON.stringify(paths), 'correctly encoded paths') assert.ok( JSON.stringify(payload[3]) === JSON.stringify(bigIntToBytes(bytes)), - 'correctly encoded bytes' + 'correctly encoded bytes', ) assert.ok(payload) const res = p.decode( p.messages.filter((message) => message.name === 'GetTrieNodes')[0], - payload + payload, ) assert.ok(JSON.stringify(res.reqId) === JSON.stringify(reqId), 'correctly decoded reqId') @@ -476,7 +476,7 @@ describe('[SnapProtocol]', () => { const nodesRes = RLP.decode(hexToBytes(trieNodesRLP)) as unknown const { reqId, nodes } = p.decode( p.messages.filter((message) => message.name === 'TrieNodes')[0], - nodesRes + nodesRes, ) assert.ok(reqId === BigInt(1), 'reqId should be 1') @@ -494,7 +494,7 @@ describe('[SnapProtocol]', () => { p.encode(p.messages.filter((message) => message.name === 'TrieNodes')[0], { reqId, nodes, - }) + }), ) assert.ok(trieNodesRLP === bytesToHex(payload), 'Re-encoded payload should match with original') }) diff --git a/packages/client/test/net/server/rlpxserver.spec.ts b/packages/client/test/net/server/rlpxserver.spec.ts index f00b0cd07a..4db0ab7e59 100644 --- a/packages/client/test/net/server/rlpxserver.spec.ts +++ b/packages/client/test/net/server/rlpxserver.spec.ts @@ -46,7 +46,7 @@ vi.doMock('@ethereumjs/devp2p', () => { } }) -const { RlpxServer } = await import('../../../src/net/server/rlpxserver') +const { RlpxServer } = await import('../../../src/net/server/rlpxserver.js') describe('[RlpxServer]', async () => { it('should initialize correctly', async () => { const config = new Config({ accountCache: 10000, storageCache: 1000 }) @@ -60,7 +60,7 @@ describe('[RlpxServer]', async () => { assert.deepEqual( server.bootnodes, [multiaddr('/ip4/10.0.0.1/tcp/1234'), multiaddr('/ip4/10.0.0.2/tcp/1234')], - 'bootnodes split' + 'bootnodes split', ) }) @@ -89,7 +89,7 @@ describe('[RlpxServer]', async () => { } server.rlpx = { destroy: vi.fn() } server.config.events.on(Event.PEER_ERROR, (err: any) => - assert.equal(err.message, 'err0', 'got error') + assert.equal(err.message, 'err0', 'got error'), ) await server.start() expect((server as any).initDpt).toHaveBeenCalled() @@ -172,7 +172,7 @@ describe('should return rlpx server info with ip4 as default', async () => { listenAddr: '0.0.0.0:30303', ports: { discovery: 30303, listener: 30303 }, }, - 'get nodeInfo' + 'get nodeInfo', ) }) await server.stop() @@ -227,7 +227,7 @@ describe('should return rlpx server info with ip6', async () => { listenAddr: '[::]:30303', ports: { discovery: 30303, listener: 30303 }, }, - 'get nodeInfo' + 'get nodeInfo', ) }) await server.stop() @@ -278,7 +278,7 @@ describe('should init dpt', async () => { config.events.on(Event.SERVER_ERROR, (err) => it('should throw', async () => { assert.equal(err.message, 'err0', 'got error') - }) + }), ) server['dpt']?.events.emit('error', new Error('err0')) }) @@ -323,22 +323,22 @@ describe('should init rlpx', async () => { config.events.on(Event.PEER_CONNECTED, (peer) => it('should connect', async () => { assert.ok(peer instanceof RlpxPeer, 'connected') - }) + }), ) config.events.on(Event.PEER_DISCONNECTED, (peer) => it('should disconnect', async () => { assert.equal(peer.id, '01', 'disconnected') - }) + }), ) config.events.on(Event.SERVER_ERROR, (err) => it('should throw error', async () => { assert.equal(err.message, 'err0', 'got error') - }) + }), ) config.events.on(Event.SERVER_LISTENING, (info) => it('should listen', async () => { assert.deepEqual(info, { transport: 'rlpx', url: 'enode://ff@0.0.0.0:30303' }, 'listening') - }) + }), ) server.rlpx!.events.emit('peer:added', rlpxPeer) ;(server as any).peers.set('01', { id: '01' } as any) diff --git a/packages/client/test/rpc/debug/getRawBlock.spec.ts b/packages/client/test/rpc/debug/getRawBlock.spec.ts index 86102288a2..4e560c185b 100644 --- a/packages/client/test/rpc/debug/getRawBlock.spec.ts +++ b/packages/client/test/rpc/debug/getRawBlock.spec.ts @@ -17,7 +17,7 @@ const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, - { common } + { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') const transactions = [mockedTx1] @@ -41,7 +41,7 @@ const block = { } const genesisBlockHash = hexToBytes( - '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5' + '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5', ) const genesisBlock = { hash: () => genesisBlockHash, @@ -83,7 +83,7 @@ describe(method, async () => { assert.equal( res.result, bytesToHex(genesisBlock.serialize()), - 'should return the genesis block as earliest' + 'should return the genesis block as earliest', ) }) @@ -118,8 +118,8 @@ describe(method, async () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"' - ) + 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"', + ), ) }) }) @@ -131,7 +131,7 @@ describe('call with block with blob txs', () => { header: { number: 1, parentHash: genesisBlock.header.hash() }, transactions: [mockedBlobTx3], }, - { common } + { common }, ) const manager = createManager(await createClient({ chain: createChain(block1 as any) })) const rpc = getRpcClient(startRPC(manager.getMethods())) @@ -140,7 +140,7 @@ describe('call with block with blob txs', () => { assert.equal( res.result, bytesToHex(block1.serialize()), - 'block body contains a transaction with the blobVersionedHashes field' + 'block body contains a transaction with the blobVersionedHashes field', ) }) }) diff --git a/packages/client/test/rpc/debug/getRawHeader.spec.ts b/packages/client/test/rpc/debug/getRawHeader.spec.ts index 27a2a7e67e..bd86b30f3c 100644 --- a/packages/client/test/rpc/debug/getRawHeader.spec.ts +++ b/packages/client/test/rpc/debug/getRawHeader.spec.ts @@ -17,7 +17,7 @@ const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, - { common } + { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') const transactions = [mockedTx1] @@ -41,7 +41,7 @@ const block = { } const genesisBlockHash = hexToBytes( - '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5' + '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5', ) const genesisBlock = { hash: () => genesisBlockHash, @@ -76,7 +76,7 @@ describe(method, async () => { assert.equal( res.result, bytesToHex(genesisBlock.header.serialize()), - 'should return a valid block' + 'should return a valid block', ) }) @@ -88,7 +88,7 @@ describe(method, async () => { assert.equal( res.result, bytesToHex(genesisBlock.header.serialize()), - 'should return the genesis block as earliest' + 'should return the genesis block as earliest', ) }) @@ -123,8 +123,8 @@ describe(method, async () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"' - ) + 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"', + ), ) }) }) @@ -136,7 +136,7 @@ describe('call with block with blob txs', () => { header: { number: 1, parentHash: genesisBlock.header.hash() }, transactions: [mockedBlobTx3], }, - { common } + { common }, ) const manager = createManager(await createClient({ chain: createChain(block1 as any) })) const rpc = getRpcClient(startRPC(manager.getMethods())) @@ -145,7 +145,7 @@ describe('call with block with blob txs', () => { assert.equal( res.result, bytesToHex(block1.header.serialize()), - 'block body contains a transaction with the blobVersionedHashes field' + 'block body contains a transaction with the blobVersionedHashes field', ) }) }) diff --git a/packages/client/test/rpc/debug/getRawReceipts.spec.ts b/packages/client/test/rpc/debug/getRawReceipts.spec.ts index 7d23ce7775..ef90f66552 100644 --- a/packages/client/test/rpc/debug/getRawReceipts.spec.ts +++ b/packages/client/test/rpc/debug/getRawReceipts.spec.ts @@ -38,7 +38,7 @@ describe(method, () => { gasPrice: 100, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx]) const res0 = await rpc.request(method, [bytesToHex(tx.hash())]) @@ -56,7 +56,7 @@ describe(method, () => { it('call with 1559 tx', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) // construct tx @@ -67,7 +67,7 @@ describe(method, () => { maxPriorityFeePerGas: 10, to: '0x1230000000000000000000000000000000000321', }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx]) @@ -134,7 +134,7 @@ describe(method, () => { to: randomBytes(20), nonce: 0n, }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx], true) diff --git a/packages/client/test/rpc/debug/getRawTransaction.spec.ts b/packages/client/test/rpc/debug/getRawTransaction.spec.ts index 19b65e6aac..155ea6479d 100644 --- a/packages/client/test/rpc/debug/getRawTransaction.spec.ts +++ b/packages/client/test/rpc/debug/getRawTransaction.spec.ts @@ -20,7 +20,7 @@ describe(method, () => { // construct tx const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -38,7 +38,7 @@ describe(method, () => { it('call with 1559 tx', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) // construct tx @@ -49,7 +49,7 @@ describe(method, () => { maxPriorityFeePerGas: 10, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) diff --git a/packages/client/test/rpc/debug/storageRangeAt.spec.ts b/packages/client/test/rpc/debug/storageRangeAt.spec.ts index 8f55a24f20..17eb9e18b0 100644 --- a/packages/client/test/rpc/debug/storageRangeAt.spec.ts +++ b/packages/client/test/rpc/debug/storageRangeAt.spec.ts @@ -98,7 +98,7 @@ describe(method, () => { value: 0, data: storageBytecode, }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) const vmCopy = await execution.vm.shallowCopy() @@ -127,7 +127,7 @@ describe(method, () => { nonce: 1, data: updateBytecode, }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) await blockBuilder.addTransaction(secondTx, { skipHardForkValidation: true }) @@ -142,7 +142,7 @@ describe(method, () => { nonce: 2, data: noStorageBytecode, }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) const thirdResult = await blockBuilder.addTransaction(thirdTx, { skipHardForkValidation: true }) @@ -175,27 +175,27 @@ describe(method, () => { assert.equal( storageRange.storage[bytesToHex(firstVariableHash)].value, '0x43', - 'First variable correctly included.' + 'First variable correctly included.', ) const secondVariableHash = keccak256(setLengthLeft(hexToBytes('0x01'), 32)) assert.equal( storageRange.storage[bytesToHex(secondVariableHash)].value, '0x01', - 'Second variable correctly included.' + 'Second variable correctly included.', ) const thirdVariableHash = keccak256(setLengthLeft(hexToBytes('0x02'), 32)) assert.equal( storageRange.storage[bytesToHex(thirdVariableHash)].value, '0x02', - 'Third variable correctly included.' + 'Third variable correctly included.', ) assert.equal( Object.keys(storageRange.storage).length, 3, - 'Call returned the correct number of key value pairs.' + 'Call returned the correct number of key value pairs.', ) }) @@ -219,7 +219,7 @@ describe(method, () => { assert.equal( storageRange.storage[bytesToHex(hashedKey)].value, '0x42', - 'Old value was correctly reported.' + 'Old value was correctly reported.', ) }) @@ -241,7 +241,7 @@ describe(method, () => { assert.equal( Object.keys(storageRange.storage).length, 2, - 'Call returned the correct number of key value pairs.' + 'Call returned the correct number of key value pairs.', ) }) @@ -263,7 +263,7 @@ describe(method, () => { assert.equal( Object.keys(storageRange.storage).length, 0, - 'Call returned the correct number of key value pairs.' + 'Call returned the correct number of key value pairs.', ) assert.isNull(storageRange.nextKey, 'nextKey was correctly set to null.') @@ -291,12 +291,12 @@ describe(method, () => { assert.equal( Object.keys(storageRange.storage).length, 2, - 'Call returned the correct number of key value pairs.' + 'Call returned the correct number of key value pairs.', ) assert.isUndefined( storageRange.storage[bytesToHex(smallestHashedKey)], - 'Smallest hashed key was correctly excluded from result.' + 'Smallest hashed key was correctly excluded from result.', ) }) @@ -399,8 +399,8 @@ describe(method, () => { assert.equal(res.error.code, INTERNAL_ERROR) assert.ok( res.error.message.includes( - 'txIndex cannot be larger than the number of transactions in the block.' - ) + 'txIndex cannot be larger than the number of transactions in the block.', + ), ) }) diff --git a/packages/client/test/rpc/debug/traceCall.spec.ts b/packages/client/test/rpc/debug/traceCall.spec.ts index 23348f588b..9476c8e943 100644 --- a/packages/client/test/rpc/debug/traceCall.spec.ts +++ b/packages/client/test/rpc/debug/traceCall.spec.ts @@ -60,7 +60,7 @@ describe('trace a call', async () => { value: 10000, data: '0x60AA', }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) tx.getSenderAddress = () => { return dummy.addr @@ -103,7 +103,7 @@ describe('trace a call', async () => { }, ], }, - 'produced a correct trace' + 'produced a correct trace', ) }) }) diff --git a/packages/client/test/rpc/debug/traceTransaction.spec.ts b/packages/client/test/rpc/debug/traceTransaction.spec.ts index 024a20a276..60f0719406 100644 --- a/packages/client/test/rpc/debug/traceTransaction.spec.ts +++ b/packages/client/test/rpc/debug/traceTransaction.spec.ts @@ -32,7 +32,7 @@ describe(method, () => { res = await rpc.request(method, ['0xabcd', { tracerConfig: { some: 'value' } }]) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes('custom tracers and tracer configurations are not implemented') + res.error.message.includes('custom tracers and tracer configurations are not implemented'), ) res = await rpc.request(method, ['0xabcd', { tracer: 'someTracer' }]) @@ -59,7 +59,7 @@ describe(method, () => { value: 10000, data: '0x60AA', }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) tx.getSenderAddress = () => { return dummy.addr @@ -88,7 +88,7 @@ describe(method, () => { value: 10000, data: '0x560FAA', }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) tx.getSenderAddress = () => { return dummy.addr @@ -117,7 +117,7 @@ describe(method, () => { value: 10000, data: '0x604260005260206000F3', }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) tx.getSenderAddress = () => { return dummy.addr @@ -131,7 +131,7 @@ describe(method, () => { assert.equal( res.result.structLogs[5].memory[0], '0x0000000000000000000000000000000000000000000000000000000000000042', - 'produced a trace with correct memory value returned' + 'produced a trace with correct memory value returned', ) }) @@ -150,7 +150,7 @@ describe(method, () => { value: 10000, data: '0x600F6000', }, - { common, freeze: false } + { common, freeze: false }, ).sign(dummy.privKey) tx.getSenderAddress = () => { return dummy.addr diff --git a/packages/client/test/rpc/engine/CLConnectionManager.spec.ts b/packages/client/test/rpc/engine/CLConnectionManager.spec.ts index 49e0d67ff2..6051ed54de 100644 --- a/packages/client/test/rpc/engine/CLConnectionManager.spec.ts +++ b/packages/client/test/rpc/engine/CLConnectionManager.spec.ts @@ -149,7 +149,7 @@ describe('updates status correctly', async () => { assert.equal( manager['connectionStatus'], ConnectionStatus.Connected, - 'connection status updated correctly' + 'connection status updated correctly', ) }) }) @@ -165,7 +165,7 @@ describe('updates connection status correctly', async () => { assert.equal( manager['connectionStatus'], ConnectionStatus.Disconnected, - 'should disconnect from CL' + 'should disconnect from CL', ) }) it('should change status to uncertain', () => { @@ -175,7 +175,7 @@ describe('updates connection status correctly', async () => { assert.equal( manager['connectionStatus'], ConnectionStatus.Uncertain, - 'should update status to uncertain' + 'should update status to uncertain', ) }) diff --git a/packages/client/test/rpc/engine/exchangeCapabilities.spec.ts b/packages/client/test/rpc/engine/exchangeCapabilities.spec.ts index 358a1f0c60..e1a2db4656 100644 --- a/packages/client/test/rpc/engine/exchangeCapabilities.spec.ts +++ b/packages/client/test/rpc/engine/exchangeCapabilities.spec.ts @@ -14,7 +14,7 @@ describe(method, () => { assert.equal( res.result.findIndex((el: string) => el === 'engine_exchangeCapabilities'), -1, - 'should not include engine_exchangeCapabilities in response' + 'should not include engine_exchangeCapabilities in response', ) }) }) diff --git a/packages/client/test/rpc/engine/forkchoiceUpdatedV1.spec.ts b/packages/client/test/rpc/engine/forkchoiceUpdatedV1.spec.ts index 3b3a14f777..421e78fbe8 100644 --- a/packages/client/test/rpc/engine/forkchoiceUpdatedV1.spec.ts +++ b/packages/client/test/rpc/engine/forkchoiceUpdatedV1.spec.ts @@ -42,7 +42,7 @@ function createBlock(parentBlock: Block) { gasLimit: parentBlock.header.gasLimit, }, }, - { common } + { common }, ) return block } @@ -60,8 +60,8 @@ describe(method, () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - "invalid argument 0 for key 'headBlockHash': hex string without 0x prefix" - ) + "invalid argument 0 for key 'headBlockHash': hex string without 0x prefix", + ), ) }) @@ -76,8 +76,8 @@ describe(method, () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - "invalid argument 0 for key 'finalizedBlockHash': invalid block hash" - ) + "invalid argument 0 for key 'finalizedBlockHash': invalid block hash", + ), ) }) @@ -103,7 +103,7 @@ describe(method, () => { assert.equal(res.result.payloadStatus.status, 'VALID') assert.equal( res.result.payloadStatus.latestValidHash, - '0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a' + '0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a', ) assert.equal(res.result.payloadStatus.validationError, null) assert.notEqual(res.result.payloadId, null) @@ -118,7 +118,7 @@ describe(method, () => { const res = await rpc.request(method, invalidTimestampPayload) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes('invalid timestamp in payloadAttributes, got 0, need at least 1') + res.error.message.includes('invalid timestamp in payloadAttributes, got 0, need at least 1'), ) }) @@ -175,7 +175,7 @@ describe(method, () => { extraData: new Uint8Array(97), }, } as BlockData, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) await chain.putBlocks([newBlock]) @@ -317,7 +317,7 @@ describe(method, () => { } const canonicalPayload = canonical.map( - (e) => blockToExecutionPayload(e, BigInt(0)).executionPayload + (e) => blockToExecutionPayload(e, BigInt(0)).executionPayload, ) const reorgPayload = reorg.map((e) => blockToExecutionPayload(e, BigInt(0)).executionPayload) @@ -357,7 +357,7 @@ describe(method, () => { } const canonicalPayload = canonical.map( - (e) => blockToExecutionPayload(e, BigInt(0)).executionPayload + (e) => blockToExecutionPayload(e, BigInt(0)).executionPayload, ) const reorgPayload = reorg.map((e) => blockToExecutionPayload(e, BigInt(0)).executionPayload) diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts index 182e2dca70..c43e167931 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts @@ -53,7 +53,7 @@ describe(method, () => { maxPriorityFeePerGas: 100000000n, gasLimit: 30000000n, }, - { common } + { common }, ).sign(pkey) const tx2 = createTxFromTxData( { @@ -64,27 +64,27 @@ describe(method, () => { gasLimit: 30000000n, nonce: 1n, }, - { common } + { common }, ).sign(pkey) const block = createBlockFromBlockData( { transactions: [tx], header: BlockHeader.fromHeaderData( { parentHash: chain.genesis.hash(), number: 1n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const block2 = createBlockFromBlockData( { transactions: [tx2], header: BlockHeader.fromHeaderData( { parentHash: block.hash(), number: 2n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) await chain.putBlocks([block, block2], true) @@ -96,7 +96,7 @@ describe(method, () => { assert.equal( res.result[0].transactions[0], bytesToHex(tx.serialize()), - 'got expected transaction from first payload' + 'got expected transaction from first payload', ) assert.equal(res.result[1], null, 'got null for block not found in chain') assert.equal(res.result.length, 3, 'length of response matches number of block hashes sent') @@ -120,7 +120,7 @@ describe(method, () => { { engine: true, hardfork: Hardfork.London, - } + }, ) const rpc = getRpcClient(server) common.setHardfork(Hardfork.London) @@ -139,7 +139,7 @@ describe(method, () => { maxPriorityFeePerGas: 100000000n, gasLimit: 30000000n, }, - { common } + { common }, ).sign(pkey) const tx2 = createTxFromTxData( { @@ -150,27 +150,27 @@ describe(method, () => { gasLimit: 30000000n, nonce: 1n, }, - { common } + { common }, ).sign(pkey) const block = createBlockFromBlockData( { transactions: [tx], header: BlockHeader.fromHeaderData( { parentHash: chain.genesis.hash(), number: 1n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const block2 = createBlockFromBlockData( { transactions: [tx2], header: BlockHeader.fromHeaderData( { parentHash: block.hash(), number: 2n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) await chain.putBlocks([block, block2], true) @@ -182,7 +182,7 @@ describe(method, () => { assert.equal( res.result[0].withdrawals, null, - 'got null for withdrawals field on pre-Shanghai block' + 'got null for withdrawals field on pre-Shanghai block', ) // Restore setStateRoot diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts index 02384549d2..45c4226068 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts @@ -55,7 +55,7 @@ describe(method, () => { maxPriorityFeePerGas: 100000000n, gasLimit: 30000000n, }, - { common } + { common }, ).sign(pkey) const tx2 = createTxFromTxData( { @@ -66,27 +66,27 @@ describe(method, () => { gasLimit: 30000000n, nonce: 1n, }, - { common } + { common }, ).sign(pkey) const block = createBlockFromBlockData( { transactions: [tx], header: BlockHeader.fromHeaderData( { parentHash: chain.genesis.hash(), number: 1n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const block2 = createBlockFromBlockData( { transactions: [tx2], header: BlockHeader.fromHeaderData( { parentHash: block.hash(), number: 2n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) await chain.putBlocks([block, block2], true) @@ -95,19 +95,19 @@ describe(method, () => { assert.equal( res.result[0].transactions[0], bytesToHex(tx.serialize()), - 'got expected transaction from first payload' + 'got expected transaction from first payload', ) assert.equal( res.result.length, 2, - 'length of response matches start of range up to highest known block' + 'length of response matches start of range up to highest known block', ) const res2 = await rpc.request(method, ['0x3', '0x2']) assert.equal( res2.result.length, 0, - 'got empty array when start of requested range is beyond current chain head' + 'got empty array when start of requested range is beyond current chain head', ) }) @@ -137,7 +137,7 @@ describe(method, () => { maxPriorityFeePerGas: 100000000n, gasLimit: 30000000n, }, - { common } + { common }, ).sign(pkey) const tx2 = createTxFromTxData( { @@ -148,27 +148,27 @@ describe(method, () => { gasLimit: 30000000n, nonce: 1n, }, - { common } + { common }, ).sign(pkey) const block = createBlockFromBlockData( { transactions: [tx], header: BlockHeader.fromHeaderData( { parentHash: chain.genesis.hash(), number: 1n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const block2 = createBlockFromBlockData( { transactions: [tx2], header: BlockHeader.fromHeaderData( { parentHash: block.hash(), number: 2n }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) await chain.putBlocks([block, block2], true) diff --git a/packages/client/test/rpc/engine/getPayloadV3.spec.ts b/packages/client/test/rpc/engine/getPayloadV3.spec.ts index 0edae358fa..def3e58408 100644 --- a/packages/client/test/rpc/engine/getPayloadV3.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadV3.spec.ts @@ -106,7 +106,7 @@ describe(method, () => { gasLimit: 30000000n, to: Address.zero(), }, - { common } + { common }, ).sign(pkey) await service.txPool.add(tx, true) @@ -116,14 +116,14 @@ describe(method, () => { assert.equal( executionPayload.blockHash, '0x8c71ad199a3dda94de6a1c31cc50a26b1f03a8a4924e9ea3fd7420c6411cac42', - 'built expected block' + 'built expected block', ) assert.equal(executionPayload.excessBlobGas, '0x0', 'correct execess blob gas') assert.equal(executionPayload.blobGasUsed, '0x20000', 'correct blob gas used') const { commitments, proofs, blobs } = blobsBundle assert.ok( commitments.length === proofs.length && commitments.length === blobs.length, - 'equal commitments, proofs and blobs' + 'equal commitments, proofs and blobs', ) assert.equal(blobs.length, 1, '1 blob should be returned') assert.equal(proofs[0], bytesToHex(txProofs[0]), 'proof should match') diff --git a/packages/client/test/rpc/engine/kaustinen6.spec.ts b/packages/client/test/rpc/engine/kaustinen6.spec.ts index 4ad0f3b2b2..4b7dab2c55 100644 --- a/packages/client/test/rpc/engine/kaustinen6.spec.ts +++ b/packages/client/test/rpc/engine/kaustinen6.spec.ts @@ -39,7 +39,7 @@ const originalValidate = (BlockHeader as any).prototype._consensusFormatValidati async function fetchExecutionPayload( peerBeaconUrl: string, - slot: number | string + slot: number | string, ): Promise { let beaconPayload: BeaconPayloadJson | undefined = undefined try { @@ -55,7 +55,7 @@ async function runBlock( { chain, rpc, common }: { chain: Chain; rpc: HttpClient; common: Common }, { execute, parent }: { execute: any; parent: any }, isBeaconData: boolean, - context: any + context: any, ) { const blockCache = chain.blockCache diff --git a/packages/client/test/rpc/engine/newPayloadV1.spec.ts b/packages/client/test/rpc/engine/newPayloadV1.spec.ts index d2b6754909..df1155e379 100644 --- a/packages/client/test/rpc/engine/newPayloadV1.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV1.spec.ts @@ -27,8 +27,8 @@ describe(method, () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - "invalid argument 0 for key 'parentHash': hex string without 0x prefix" - ) + "invalid argument 0 for key 'parentHash': hex string without 0x prefix", + ), ) }) @@ -39,7 +39,7 @@ describe(method, () => { const res = await rpc.request(method, blockDataWithInvalidBlockHash) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes("invalid argument 0 for key 'blockHash': invalid block hash") + res.error.message.includes("invalid argument 0 for key 'blockHash': invalid block hash"), ) }) @@ -145,7 +145,7 @@ describe(method, () => { const expectedError = 'Invalid tx at index 0: Error: Invalid serialized tx input: must be array' assert.ok( res.result.validationError.includes(expectedError), - `should error with - ${expectedError}` + `should error with - ${expectedError}`, ) }) @@ -162,7 +162,7 @@ describe(method, () => { value: 1, to: Address.fromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), }, - { common } + { common }, ) const transactions = [bytesToHex(tx.serialize())] @@ -180,7 +180,7 @@ describe(method, () => { it('call with valid data & valid transaction', async () => { const accountPk = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const accountAddress = Address.fromPrivateKey(accountPk) const newGenesisJSON = { @@ -201,7 +201,7 @@ describe(method, () => { value: 6, gasLimit: 53_000, }, - { common } + { common }, ).sign(accountPk) const transactions = [bytesToHex(tx.serialize())] const blockDataWithValidTransaction = { @@ -220,7 +220,7 @@ describe(method, () => { it('call with too many transactions', async () => { const accountPk = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const accountAddress = Address.fromPrivateKey(accountPk) const newGenesisJSON = { @@ -245,7 +245,7 @@ describe(method, () => { value: 6, gasLimit: 53_000, }, - { common } + { common }, ).sign(accountPk) return bytesToHex(tx.serialize()) diff --git a/packages/client/test/rpc/engine/newPayloadV2.spec.ts b/packages/client/test/rpc/engine/newPayloadV2.spec.ts index 16ccb21d08..f11aaad90f 100644 --- a/packages/client/test/rpc/engine/newPayloadV2.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV2.spec.ts @@ -27,8 +27,8 @@ describe(`${method}: call with executionPayloadV1`, () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - "invalid argument 0 for key 'parentHash': hex string without 0x prefix" - ) + "invalid argument 0 for key 'parentHash': hex string without 0x prefix", + ), ) }) @@ -39,7 +39,7 @@ describe(`${method}: call with executionPayloadV1`, () => { const res = await rpc.request(method, blockDataWithInvalidBlockHash) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes("invalid argument 0 for key 'blockHash': invalid block hash") + res.error.message.includes("invalid argument 0 for key 'blockHash': invalid block hash"), ) }) @@ -143,7 +143,7 @@ describe(`${method}: call with executionPayloadV1`, () => { const expectedError = 'Invalid tx at index 0: Error: Invalid serialized tx input: must be array' assert.ok( res.result.validationError.includes(expectedError), - `should error with - ${expectedError}` + `should error with - ${expectedError}`, ) }) @@ -160,7 +160,7 @@ describe(`${method}: call with executionPayloadV1`, () => { value: 1, to: Address.fromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), }, - { common } + { common }, ) const transactions = [bytesToHex(tx.serialize())] @@ -177,7 +177,7 @@ describe(`${method}: call with executionPayloadV1`, () => { it('call with valid data & valid transaction', async () => { const accountPk = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const accountAddress = Address.fromPrivateKey(accountPk) const newGenesisJSON = { @@ -198,7 +198,7 @@ describe(`${method}: call with executionPayloadV1`, () => { value: 6, gasLimit: 53_000, }, - { common } + { common }, ).sign(accountPk) const transactions = [bytesToHex(tx.serialize())] const blockDataWithValidTransaction = { diff --git a/packages/client/test/rpc/engine/newPayloadV3.spec.ts b/packages/client/test/rpc/engine/newPayloadV3.spec.ts index 33c98e9bbc..75303d7629 100644 --- a/packages/client/test/rpc/engine/newPayloadV3.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV3.spec.ts @@ -28,7 +28,7 @@ describe(`${method}: call with executionPayloadV3`, () => { const res = await rpc.request(method, [validBlock, [], parentBeaconBlockRoot]) assert.equal(res.error.code, UNSUPPORTED_FORK) assert.ok( - res.error.message.includes('NewPayloadV{1|2} MUST be used before Cancun is activated') + res.error.message.includes('NewPayloadV{1|2} MUST be used before Cancun is activated'), ) }) diff --git a/packages/client/test/rpc/engine/newPayloadV3VersionedHashes.spec.ts b/packages/client/test/rpc/engine/newPayloadV3VersionedHashes.spec.ts index 39451b9c32..4f4880a4d1 100644 --- a/packages/client/test/rpc/engine/newPayloadV3VersionedHashes.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV3VersionedHashes.spec.ts @@ -42,7 +42,7 @@ describe(`${method}: Cancun validations`, () => { assert.equal(res.result.status, 'INVALID') assert.equal( res.result.validationError, - 'Error verifying blobVersionedHashes: expected=0 received=2' + 'Error verifying blobVersionedHashes: expected=0 received=2', ) const txString = @@ -83,7 +83,7 @@ describe(`${method}: Cancun validations`, () => { res = await rpc.request(method, blockDataMissingParentBeaconRoot) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes('missing value for required argument parentBeaconBlockRoot') + res.error.message.includes('missing value for required argument parentBeaconBlockRoot'), ) const blockDataExtraMissingHashes1 = [ @@ -105,7 +105,7 @@ describe(`${method}: Cancun validations`, () => { assert.equal(res.result.status, 'INVALID') assert.equal( res.result.validationError, - 'Error verifying blobVersionedHashes: expected=2 received=1' + 'Error verifying blobVersionedHashes: expected=2 received=1', ) const blockDataExtraMisMatchingHashes1 = [ @@ -127,7 +127,7 @@ describe(`${method}: Cancun validations`, () => { assert.equal(res.result.status, 'INVALID') assert.equal( res.result.validationError, - 'Error verifying blobVersionedHashes: mismatch at index=1 expected=0x0131…52c5 received=0x3456…' + 'Error verifying blobVersionedHashes: mismatch at index=1 expected=0x0131…52c5 received=0x3456…', ) const blockDataMatchingVersionedHashes = [ diff --git a/packages/client/test/rpc/engine/newPayloadV4.spec.ts b/packages/client/test/rpc/engine/newPayloadV4.spec.ts index 598dec3ca5..a46038ebd4 100644 --- a/packages/client/test/rpc/engine/newPayloadV4.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV4.spec.ts @@ -107,15 +107,15 @@ describe(`${method}: call with executionPayloadV4`, () => { const { executionPayload } = res.result assert.ok( executionPayload.depositRequests?.length === 1, - 'depositRequests should have 1 deposit request' + 'depositRequests should have 1 deposit request', ) assert.ok( executionPayload.withdrawalRequests !== undefined, - 'depositRequests field should be received' + 'depositRequests field should be received', ) assert.ok( executionPayload.consolidationRequests !== undefined, - 'consolidationRequests field should be received' + 'consolidationRequests field should be received', ) res = await rpc.request(method, [executionPayload, [], parentBeaconBlockRoot]) diff --git a/packages/client/test/rpc/engine/preimages.spec.ts b/packages/client/test/rpc/engine/preimages.spec.ts index 9081ccd97e..9e06517a2e 100644 --- a/packages/client/test/rpc/engine/preimages.spec.ts +++ b/packages/client/test/rpc/engine/preimages.spec.ts @@ -50,7 +50,7 @@ async function genBlockWithdrawals(blockNumber: number) { } }) const withdrawalsRoot = bytesToHex( - await genWithdrawalsTrieRoot(withdrawals.map(Withdrawal.fromWithdrawalData)) + await genWithdrawalsTrieRoot(withdrawals.map(Withdrawal.fromWithdrawalData)), ) return { withdrawals, withdrawalsRoot } @@ -66,7 +66,7 @@ async function runBlock( receiptTrie: PrefixedHexString gasUsed: PrefixedHexString coinbase: PrefixedHexString - } + }, ) { const { transactions, parentHash, blockNumber, stateRoot, receiptTrie, gasUsed, coinbase } = runData @@ -116,7 +116,7 @@ describe(`valid verkle network setup`, async () => { { engine: true, savePreimages: true, - } + }, ) ;(chain.blockchain as any).validateHeader = () => {} @@ -252,12 +252,12 @@ describe(`valid verkle network setup`, async () => { for (const preimage of preimages) { const preimageBytes = hexToBytes(preimage) const savedPreimage = await execution.preimagesManager!.getPreimage( - keccak256(preimageBytes) + keccak256(preimageBytes), ) assert.isNotNull(savedPreimage, `Missing preimage for ${preimage}`) assert.ok( savedPreimage !== null && equalsBytes(savedPreimage, preimageBytes), - `Incorrect preimage for ${preimage}` + `Incorrect preimage for ${preimage}`, ) } parentHash = blockHash diff --git a/packages/client/test/rpc/engine/withdrawals.spec.ts b/packages/client/test/rpc/engine/withdrawals.spec.ts index c2616a4437..e46f000c89 100644 --- a/packages/client/test/rpc/engine/withdrawals.spec.ts +++ b/packages/client/test/rpc/engine/withdrawals.spec.ts @@ -105,12 +105,12 @@ for (const { name, withdrawals, withdrawalsRoot, gethBlockRlp } of testCases) { it(name, async () => { // check withdrawals root computation const computedWithdrawalsRoot = bytesToHex( - await genWithdrawalsTrieRoot(withdrawals.map(Withdrawal.fromWithdrawalData), new Trie()) + await genWithdrawalsTrieRoot(withdrawals.map(Withdrawal.fromWithdrawalData), new Trie()), ) assert.equal( withdrawalsRoot, computedWithdrawalsRoot, - 'withdrawalsRoot compuation should match' + 'withdrawalsRoot compuation should match', ) const { server } = await setupChain(genesisJSON, 'post-merge', { engine: true }) const rpc = getRpcClient(server) @@ -120,7 +120,7 @@ for (const { name, withdrawals, withdrawalsRoot, gethBlockRlp } of testCases) { ]) assert.equal(res.error.code, INVALID_PARAMS) assert.ok( - res.error.message.includes('PayloadAttributesV2 MUST be used after Shanghai is activated') + res.error.message.includes('PayloadAttributesV2 MUST be used after Shanghai is activated'), ) res = await rpc.request('engine_forkchoiceUpdatedV2', [ @@ -139,7 +139,7 @@ for (const { name, withdrawals, withdrawalsRoot, gethBlockRlp } of testCases) { assert.equal( executionPayload!.withdrawals!.length, withdrawals.length, - 'withdrawals should match' + 'withdrawals should match', ) assert.equal(blockValue, '0x0', 'No value should be returned') payload = executionPayload @@ -149,7 +149,7 @@ for (const { name, withdrawals, withdrawalsRoot, gethBlockRlp } of testCases) { assert.equal( payload!.stateRoot, '0x23eadd91fca55c0e14034e4d63b2b3ed43f2e807b6bf4d276b784ac245e7fa3f', - 'stateRoot should match' + 'stateRoot should match', ) } diff --git a/packages/client/test/rpc/eth/blobBaseFee.spec.ts b/packages/client/test/rpc/eth/blobBaseFee.spec.ts index b4c9bbe01e..5a2dc594fc 100644 --- a/packages/client/test/rpc/eth/blobBaseFee.spec.ts +++ b/packages/client/test/rpc/eth/blobBaseFee.spec.ts @@ -25,7 +25,7 @@ const accountAddress = Address.fromPrivateKey(privateKey) const produceBlockWith4844Tx = async ( execution: VMExecution, chain: Chain, - blobsCount: number[] + blobsCount: number[], ) => { const kzg = await loadKZG() // 4844 sample blob @@ -75,8 +75,8 @@ const produceBlockWith4844Tx = async ( kzgCommitments, maxFeePerBlobGas: BigInt(1000), }, - { common: vmCopy.common } - ).sign(privateKey) + { common: vmCopy.common }, + ).sign(privateKey), ) nonce++ } diff --git a/packages/client/test/rpc/eth/call.spec.ts b/packages/client/test/rpc/eth/call.spec.ts index e516875ad1..a2d7613d0e 100644 --- a/packages/client/test/rpc/eth/call.spec.ts +++ b/packages/client/test/rpc/eth/call.spec.ts @@ -64,7 +64,7 @@ describe(method, () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx @@ -104,21 +104,21 @@ describe(method, () => { assert.equal( res.result, bytesToHex(execResult.returnValue), - 'should return the correct return value' + 'should return the correct return value', ) res = await rpc.request(method, [{ ...estimateTxData }, 'latest']) assert.equal( res.result, bytesToHex(execResult.returnValue), - 'should return the correct return value with no gas limit provided' + 'should return the correct return value with no gas limit provided', ) res = await rpc.request(method, [{ gasLimit, data }, 'latest']) assert.equal( res.result, bytesToHex(result.results[0].execResult.returnValue), - `should let run call without 'to' for contract creation` + `should let run call without 'to' for contract creation`, ) }) diff --git a/packages/client/test/rpc/eth/chainId.spec.ts b/packages/client/test/rpc/eth/chainId.spec.ts index a827c875a2..3b106d425e 100644 --- a/packages/client/test/rpc/eth/chainId.spec.ts +++ b/packages/client/test/rpc/eth/chainId.spec.ts @@ -23,7 +23,7 @@ describe(method, () => { it('returns 3 for Goerli', async () => { const manager = createManager( - await createClient({ opened: true, commonChain: new Common({ chain: Chain.Goerli }) }) + await createClient({ opened: true, commonChain: new Common({ chain: Chain.Goerli }) }), ) const rpc = getRpcClient(startRPC(manager.getMethods())) diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index a584855504..a31fc8f10c 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -73,7 +73,7 @@ describe( gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx @@ -114,7 +114,7 @@ describe( assert.equal( res.result, '0x' + totalGasSpent.toString(16), - 'should return the correct gas estimate' + 'should return the correct gas estimate', ) // Test without blockopt as its optional and should default to latest @@ -122,7 +122,7 @@ describe( assert.equal( res2.result, '0x' + totalGasSpent.toString(16), - 'should return the correct gas estimate' + 'should return the correct gas estimate', ) // Setup chain to run an EIP1559 tx const service = client.services[0] as FullEthereumService @@ -141,10 +141,10 @@ describe( common: service.chain.config.chainCommon, skipConsensusFormatValidation: true, calcDifficultyFromHeader: headBlock.header, - } + }, ), }, - { common: service.chain.config.chainCommon } + { common: service.chain.config.chainCommon }, ) vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) @@ -158,7 +158,7 @@ describe( assert.equal( EIP1559res.result, '0x' + totalGasSpent.toString(16), - 'should return the correct gas estimate for EIP1559 tx' + 'should return the correct gas estimate for EIP1559 tx', ) // Test EIP1559 tx with no maxFeePerGas @@ -174,7 +174,7 @@ describe( assert.equal( EIP1559reqNoGas.result, '0x' + totalGasSpent.toString(16), - 'should return the correct gas estimate' + 'should return the correct gas estimate', ) // Test legacy tx with London head block @@ -184,7 +184,7 @@ describe( assert.equal( legacyTxNoGas.result, '0x' + totalGasSpent.toString(16), - 'should return the correct gas estimate' + 'should return the correct gas estimate', ) }) @@ -214,5 +214,5 @@ describe( assert.ok(res.error.message.includes('"pending" is not yet supported')) }) }, - 20000 + 20000, ) diff --git a/packages/client/test/rpc/eth/gasPrice.spec.ts b/packages/client/test/rpc/eth/gasPrice.spec.ts index 4516d91d79..d2e0ea922a 100644 --- a/packages/client/test/rpc/eth/gasPrice.spec.ts +++ b/packages/client/test/rpc/eth/gasPrice.spec.ts @@ -23,7 +23,7 @@ describe(method, () => { // construct tx const tx = createLegacyTx( { gasLimit: 21000, gasPrice: GAS_PRICE, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -32,7 +32,7 @@ describe(method, () => { assert.equal( res.result, intToHex(GAS_PRICE), - 'should return the correct suggested gas price with 1 legacy transaction' + 'should return the correct suggested gas price with 1 legacy transaction', ) }) @@ -46,7 +46,7 @@ describe(method, () => { averageGasPrice += BigInt(gasPrice) const tx = createLegacyTx( { nonce: i, gasLimit: 21000, gasPrice, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) } @@ -56,7 +56,7 @@ describe(method, () => { assert.equal( res.result, bigIntToHex(averageGasPrice), - 'should return the correct gas price with multiple legacy transactions' + 'should return the correct gas price with multiple legacy transactions', ) }) @@ -68,11 +68,11 @@ describe(method, () => { const tx1 = createLegacyTx( { gasLimit: 21000, gasPrice: G1, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) const tx2 = createLegacyTx( { nonce: 1, gasLimit: 21000, gasPrice: G2, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx1, tx2]) @@ -82,14 +82,14 @@ describe(method, () => { assert.equal( res.result, intToHex(Math.trunc(averageGasPrice)), - 'should return the correct gas price with multiple legacy transactions in a block' + 'should return the correct gas price with multiple legacy transactions in a block', ) }) it('call with 1559 transaction data', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) const tx = create1559FeeMarketTx( @@ -99,7 +99,7 @@ describe(method, () => { maxFeePerGas: 975000000, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -110,14 +110,14 @@ describe(method, () => { assert.equal( res.result, bigIntToHex(gasPrice), - 'should return the correct gas price with 1 1559 transaction' + 'should return the correct gas price with 1 1559 transaction', ) }) it('call with multiple 1559 transactions', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) const maxPriority1 = 10 @@ -129,7 +129,7 @@ describe(method, () => { maxFeePerGas: 975000000, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) const tx2 = create1559FeeMarketTx( { @@ -139,7 +139,7 @@ describe(method, () => { maxFeePerGas: 975000000, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx1, tx2]) @@ -151,7 +151,7 @@ describe(method, () => { assert.equal( res.result, bigIntToHex(gasPrice), - 'should return the correct gas price with 1 1559 transaction' + 'should return the correct gas price with 1 1559 transaction', ) }) @@ -171,7 +171,7 @@ describe(method, () => { gasPrice: firstBlockGasPrice, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) } else { tx = createLegacyTx( @@ -181,7 +181,7 @@ describe(method, () => { gasPrice, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) } await runBlockWithTxs(chain, execution, [tx!]) @@ -197,7 +197,7 @@ describe(method, () => { assert.equal( res.result, bigIntToHex(gasPrice), - 'should return the correct gas price for 21 blocks' + 'should return the correct gas price for 21 blocks', ) }) }) diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index 9afbc079c8..2598d61a2f 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -44,7 +44,7 @@ describe( assert.equal( res.result, bigIntToHex(genesisBalance), - 'should return the correct genesis balance' + 'should return the correct genesis balance', ) // construct block with tx @@ -64,7 +64,7 @@ describe( assert.equal( res.result, bigIntToHex(expectedNewBalance), - 'should return the correct balance after a tx' + 'should return the correct balance after a tx', ) // verify we can query with "earliest" @@ -72,7 +72,7 @@ describe( assert.equal( res.result, bigIntToHex(genesisBalance), - "should return the correct balance with 'earliest'" + "should return the correct balance with 'earliest'", ) // verify we can query with a past block number @@ -80,7 +80,7 @@ describe( assert.equal( res.result, bigIntToHex(genesisBalance), - 'should return the correct balance with a past block number' + 'should return the correct balance with a past block number', ) // call with height that exceeds chain height @@ -108,5 +108,5 @@ describe( assert.ok(res.error.message.includes('"pending" is not yet supported')) }) }, - 40000 + 40000, ) diff --git a/packages/client/test/rpc/eth/getBlockByHash.spec.ts b/packages/client/test/rpc/eth/getBlockByHash.spec.ts index 5416ada56d..f737b4f428 100644 --- a/packages/client/test/rpc/eth/getBlockByHash.spec.ts +++ b/packages/client/test/rpc/eth/getBlockByHash.spec.ts @@ -33,7 +33,7 @@ describe(method, () => { assert.equal( typeof res.result.transactions[0], 'string', - 'should return only the hashes of the transactions' + 'should return only the hashes of the transactions', ) }) diff --git a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts index 8b631dd738..2e21890b93 100644 --- a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts @@ -17,7 +17,7 @@ const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, - { common } + { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') const transactions = [mockedTx1] @@ -41,7 +41,7 @@ const block = { function createChain(headBlock = block) { const genesisBlockHash = hexToBytes( - '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5' + '0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5', ) const genesisBlock = { hash: () => genesisBlockHash, @@ -86,7 +86,7 @@ describe(method, async () => { assert.equal( typeof res.result.transactions[0], 'string', - 'should return only the hashes of the transactions' + 'should return only the hashes of the transactions', ) }) @@ -134,8 +134,8 @@ describe(method, async () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"' - ) + 'invalid argument 0: block option must be a valid 0x-prefixed block hash or hex integer, or "latest", "earliest" or "pending"', + ), ) }) @@ -172,7 +172,7 @@ describe(method, async () => { header: { number: 1, parentHash: genesisBlock.header.hash() }, transactions: [mockedBlobTx3], }, - { common } + { common }, ) const manager = createManager(await createClient({ chain: createChain(block1 as any) })) const rpc = getRpcClient(startRPC(manager.getMethods())) @@ -181,7 +181,7 @@ describe(method, async () => { assert.equal( res.result.transactions[0].blobVersionedHashes.length, 1, - 'block body contains a transaction with the blobVersionedHashes field' + 'block body contains a transaction with the blobVersionedHashes field', ) }) }) diff --git a/packages/client/test/rpc/eth/getBlockReceipts.spec.ts b/packages/client/test/rpc/eth/getBlockReceipts.spec.ts index 7234049067..f43a975597 100644 --- a/packages/client/test/rpc/eth/getBlockReceipts.spec.ts +++ b/packages/client/test/rpc/eth/getBlockReceipts.spec.ts @@ -34,7 +34,7 @@ describe(method, () => { gasPrice: 100, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) const tx2 = createLegacyTx( { @@ -43,7 +43,7 @@ describe(method, () => { to: '0x0000000000000000000000000000000000000000', nonce: 1, }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx, tx2]) const res0 = await rpc.request(method, [bytesToHex(tx.hash())]) @@ -55,7 +55,7 @@ describe(method, () => { it('call with 1559 tx', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) // construct tx @@ -66,7 +66,7 @@ describe(method, () => { maxPriorityFeePerGas: 10, to: '0x1230000000000000000000000000000000000321', }, - { common } + { common }, ).sign(dummy.privKey) const tx1 = create1559FeeMarketTx( { @@ -76,7 +76,7 @@ describe(method, () => { to: '0x1230000000000000000000000000000000000321', nonce: 1, }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx, tx1]) @@ -137,7 +137,7 @@ describe(method, () => { to: randomBytes(20), nonce: 0n, }, - { common } + { common }, ).sign(dummy.privKey) const block = await runBlockWithTxs(chain, execution, [tx], true) diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index 1e06d6157f..ae29e1c366 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -51,7 +51,7 @@ describe(method, () => { gasLimit: 2000000, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx @@ -107,7 +107,7 @@ describe(method, () => { gasLimit: 2000000, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx block.transactions[1] = tx2 diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index cc6e678865..e214c0c882 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -77,7 +77,7 @@ describe(method, () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx @@ -91,7 +91,7 @@ describe(method, () => { const expectedContractAddress = Address.generate(address, BigInt(0)) assert.ok( createdAddress!.equals(expectedContractAddress), - 'should match the expected contract address' + 'should match the expected contract address', ) // verify contract has code diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index 211140087b..3ead5e1ff6 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -28,7 +28,7 @@ const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3 const pKeyAddress = Address.fromPrivateKey(privateKey) const privateKey4844 = hexToBytes( - '0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8' + '0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8', ) const p4844Address = Address.fromPrivateKey(privateKey4844) @@ -68,7 +68,7 @@ const produceBlockWithTx = async ( execution: VMExecution, chain: Chain, maxPriorityFeesPerGas: bigint[] = [BigInt(0xff)], - gasLimits: bigint[] = [BigInt(0xfffff)] + gasLimits: bigint[] = [BigInt(0xfffff)], ) => { const { vm } = execution const account = await vm.stateManager.getAccount(pKeyAddress) @@ -99,8 +99,8 @@ const produceBlockWithTx = async ( nonce, data: '0xFE', }, - { common: vmCopy.common } - ).sign(privateKey) + { common: vmCopy.common }, + ).sign(privateKey), ) nonce++ } @@ -119,7 +119,7 @@ const produceBlockWithTx = async ( const produceBlockWith4844Tx = async ( execution: VMExecution, chain: Chain, - blobsCount: number[] + blobsCount: number[], ) => { const kzg = await loadKZG() // 4844 sample blob @@ -169,8 +169,8 @@ const produceBlockWith4844Tx = async ( kzgCommitments, maxFeePerBlobGas: BigInt(1000), }, - { common: vmCopy.common } - ).sign(privateKey4844) + { common: vmCopy.common }, + ).sign(privateKey4844), ) nonce++ } @@ -198,13 +198,13 @@ describe(method, () => { const [firstBaseFee, previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [ string, string, - string + string, ] const increase = Number( (1000n * (bytesToBigInt(hexToBytes(nextBaseFee)) - bytesToBigInt(hexToBytes(previousBaseFee)))) / - bytesToBigInt(hexToBytes(previousBaseFee)) + bytesToBigInt(hexToBytes(previousBaseFee)), ) / 1000 // Note: this also ensures that block 2,3 are returned, since gas of block 0 -> 1 and 1 -> 2 does not change @@ -239,7 +239,7 @@ describe(method, () => { Number( (1000n * (bytesToBigInt(hexToBytes(nextBaseFee)) - bytesToBigInt(hexToBytes(previousBaseFee)))) / - bytesToBigInt(hexToBytes(previousBaseFee)) + bytesToBigInt(hexToBytes(previousBaseFee)), ) / 1000 assert.equal(decrease, -0.125) @@ -323,12 +323,12 @@ describe(method, () => { assert.equal( parseInt(res.result.reward[0][0]), 0, - 'Should return 0 for empty block reward percentiles' + 'Should return 0 for empty block reward percentiles', ) assert.equal( res.result.reward[0][1], '0x0', - 'Should return 0 for empty block reward percentiles' + 'Should return 0 for empty block reward percentiles', ) }) it(`${method}: should generate reward percentiles`, async () => { @@ -385,7 +385,7 @@ describe(method, () => { const res = await rpc.request(method, ['0x1', 'latest', [10, 20, 60, 100]]) const expected = [priorityFees[0], priorityFees[0], priorityFees[1], priorityFees[1]].map( - bigIntToHex + bigIntToHex, ) assert.deepEqual(res.result.reward[0], expected) @@ -442,6 +442,6 @@ describe(method, () => { }, { timeout: 60000, - } + }, ) }) diff --git a/packages/client/test/rpc/eth/getLogs.spec.ts b/packages/client/test/rpc/eth/getLogs.spec.ts index 2cdd054f59..c433cddea8 100644 --- a/packages/client/test/rpc/eth/getLogs.spec.ts +++ b/packages/client/test/rpc/eth/getLogs.spec.ts @@ -23,7 +23,7 @@ const method = 'eth_getLogs' ``` */ const logExampleBytecode = hexToBytes( - '0x608060405234801561001057600080fd5b50610257806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c010000000000000000000000000000000000000000000000000000000090048063aefb4f0a1461004d575b600080fd5b610067600480360381019061006291906100de565b610069565b005b60005b858110156100c1578284867fbf642f3055e2ef2589825c2c0dd4855c1137a63f6260d9d112629e5cd034a3eb856040516100a69190610168565b60405180910390a480806100b99061018d565b91505061006c565b505050505050565b6000813590506100d88161020a565b92915050565b600080600080600060a086880312156100fa576100f9610205565b5b6000610108888289016100c9565b9550506020610119888289016100c9565b945050604061012a888289016100c9565b935050606061013b888289016100c9565b925050608061014c888289016100c9565b9150509295509295909350565b61016281610183565b82525050565b600060208201905061017d6000830184610159565b92915050565b6000819050919050565b600061019882610183565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156101cb576101ca6101d6565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61021381610183565b811461021e57600080fd5b5056fea2646970667358221220b98f45f4d4112e71fd287ab0ce7cc1872e53b463eb0abf1182b892192d3d8a1d64736f6c63430008070033' + '0x608060405234801561001057600080fd5b50610257806100206000396000f3fe608060405234801561001057600080fd5b5060043610610048576000357c010000000000000000000000000000000000000000000000000000000090048063aefb4f0a1461004d575b600080fd5b610067600480360381019061006291906100de565b610069565b005b60005b858110156100c1578284867fbf642f3055e2ef2589825c2c0dd4855c1137a63f6260d9d112629e5cd034a3eb856040516100a69190610168565b60405180910390a480806100b99061018d565b91505061006c565b505050505050565b6000813590506100d88161020a565b92915050565b600080600080600060a086880312156100fa576100f9610205565b5b6000610108888289016100c9565b9550506020610119888289016100c9565b945050604061012a888289016100c9565b935050606061013b888289016100c9565b925050608061014c888289016100c9565b9150509295509295909350565b61016281610183565b82525050565b600060208201905061017d6000830184610159565b92915050565b6000819050919050565b600061019882610183565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156101cb576101ca6101d6565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b61021381610183565b811461021e57600080fd5b5056fea2646970667358221220b98f45f4d4112e71fd287ab0ce7cc1872e53b463eb0abf1182b892192d3d8a1d64736f6c63430008070033', ) describe(method, async () => { @@ -38,7 +38,7 @@ describe(method, async () => { data: logExampleBytecode, nonce: 0, }, - { common } + { common }, ).sign(dummy.privKey) const tx2 = createLegacyTx( { @@ -46,7 +46,7 @@ describe(method, async () => { data: logExampleBytecode, nonce: 1, }, - { common } + { common }, ).sign(dummy.privKey) const contractAddr1 = Address.generate(dummy.addr, BigInt(0)) @@ -54,7 +54,7 @@ describe(method, async () => { // construct txs to emit the logs // data calls log(logCount: 10, num1: 1, num2: 2, num3: 3, num4: 4) const data = hexToBytes( - '0xaefb4f0a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004' + '0xaefb4f0a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004', ) const tx3 = createLegacyTx( { @@ -63,7 +63,7 @@ describe(method, async () => { to: contractAddr1, nonce: 2, }, - { common } + { common }, ).sign(dummy.privKey) const tx4 = createLegacyTx( { @@ -72,7 +72,7 @@ describe(method, async () => { to: contractAddr2, nonce: 3, }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx1, tx2, tx3, tx4]) @@ -94,7 +94,7 @@ describe(method, async () => { ) { assert.ok( true, - `should return the correct logs (fromBlock/toBlock as 'earliest' and 'latest')` + `should return the correct logs (fromBlock/toBlock as 'earliest' and 'latest')`, ) } else { assert.fail(`should return the correct logs (fromBlock/toBlock as 'earliest' and 'latest')`) @@ -105,7 +105,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (fromBlock/toBlock as block numbers)' + 'should return the correct logs (fromBlock/toBlock as block numbers)', ) // test filtering by single address @@ -137,7 +137,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (filter by topic - empty means anything)' + 'should return the correct logs (filter by topic - empty means anything)', ) // test filtering by topics (exact match) @@ -147,7 +147,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (filter by topic - exact match)' + 'should return the correct logs (filter by topic - exact match)', ) // test filtering by topics (exact match for second topic) @@ -157,7 +157,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (filter by topic - exact match for second topic)' + 'should return the correct logs (filter by topic - exact match for second topic)', ) // test filtering by topics (A or B in first position) @@ -177,7 +177,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (filter by topic - A or B in first position)' + 'should return the correct logs (filter by topic - A or B in first position)', ) // test filtering by topics (null means anything) @@ -190,7 +190,7 @@ describe(method, async () => { assert.equal( res.result.length, 20, - 'should return the correct logs (filter by topic - null means anything)' + 'should return the correct logs (filter by topic - null means anything)', ) // test filtering by blockHash @@ -234,8 +234,8 @@ describe(method, async () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - 'Can only specify a blockHash if fromBlock or toBlock are not provided' - ) + 'Can only specify a blockHash if fromBlock or toBlock are not provided', + ), ) res = await rpc.request(method, [ @@ -247,8 +247,8 @@ describe(method, async () => { assert.equal(res.error.code, INVALID_PARAMS) assert.ok( res.error.message.includes( - 'Can only specify a blockHash if fromBlock or toBlock are not provided' - ) + 'Can only specify a blockHash if fromBlock or toBlock are not provided', + ), ) // unknown address diff --git a/packages/client/test/rpc/eth/getProof.spec.ts b/packages/client/test/rpc/eth/getProof.spec.ts index b9e2f41d1d..84f52a7db8 100644 --- a/packages/client/test/rpc/eth/getProof.spec.ts +++ b/packages/client/test/rpc/eth/getProof.spec.ts @@ -140,7 +140,7 @@ describe(method, async () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx @@ -172,7 +172,7 @@ describe(method, async () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: block.header } + { common, calcDifficultyFromHeader: block.header }, ) block2.transactions[0] = storeTx diff --git a/packages/client/test/rpc/eth/getStorageAt.spec.ts b/packages/client/test/rpc/eth/getStorageAt.spec.ts index fe30e8ba1a..e5d3784ead 100644 --- a/packages/client/test/rpc/eth/getStorageAt.spec.ts +++ b/packages/client/test/rpc/eth/getStorageAt.spec.ts @@ -41,7 +41,7 @@ describe(method, async () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = signedTx @@ -65,7 +65,7 @@ describe(method, async () => { assert.equal( res.result, emptySlotStr, - 'should not have new slot value for block that is addressed by "earliest" tag and is older than latest' + 'should not have new slot value for block that is addressed by "earliest" tag and is older than latest', ) // call with integer for block number to see if getStorageAt allows addressing blocks by number index @@ -73,7 +73,7 @@ describe(method, async () => { assert.equal( res.result, expectedSlotValue, - 'should return the correct slot value when addressing the latest block by integer index' + 'should return the correct slot value when addressing the latest block by integer index', ) // call with unsupported block argument diff --git a/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts b/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts index 5a97a2950e..7feabc0fd3 100644 --- a/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionByBlockHashAndIndex.spec.ts @@ -18,11 +18,11 @@ async function setUp() { nonce: 0, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey), createLegacyTx( { gasLimit: 21000, gasPrice: 50, nonce: 1, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey), ] diff --git a/packages/client/test/rpc/eth/getTransactionByHash.spec.ts b/packages/client/test/rpc/eth/getTransactionByHash.spec.ts index 9a5fa3981a..4004a50748 100644 --- a/packages/client/test/rpc/eth/getTransactionByHash.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionByHash.spec.ts @@ -20,7 +20,7 @@ describe(method, () => { // construct tx const tx = createLegacyTx( { gasLimit: 2000000, gasPrice: 100, to: '0x0000000000000000000000000000000000000000' }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -39,7 +39,7 @@ describe(method, () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), 'powLondon', - { txLookupLimit: 0 } + { txLookupLimit: 0 }, ) const rpc = getRpcClient(server) // construct tx @@ -50,7 +50,7 @@ describe(method, () => { maxPriorityFeePerGas: 10, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -67,7 +67,7 @@ describe(method, () => { assert.equal( res.result.hash, bytesToHex(tx.hash()), - 'should return the correct tx when txLookupLimit=0' + 'should return the correct tx when txLookupLimit=0', ) }) diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index b58383b877..fbb77b7608 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -57,7 +57,7 @@ describe(method, () => { gasLimit: 2000000, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) block.transactions[0] = tx diff --git a/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts b/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts index 8f4ff58727..07a80b5aa3 100644 --- a/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionReceipt.spec.ts @@ -32,7 +32,7 @@ describe(method, () => { gasPrice: 100, to: '0x0000000000000000000000000000000000000000', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -45,7 +45,7 @@ describe(method, () => { it('call with 1559 tx', async () => { const { chain, common, execution, server } = await setupChain( gethGenesisStartLondon(pow), - 'powLondon' + 'powLondon', ) const rpc = getRpcClient(server) // construct tx @@ -56,7 +56,7 @@ describe(method, () => { maxPriorityFeePerGas: 10, to: '0x1230000000000000000000000000000000000321', }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx]) @@ -117,7 +117,7 @@ describe(method, () => { to: randomBytes(20), nonce: 0n, }, - { common } + { common }, ).sign(dummy.privKey) await runBlockWithTxs(chain, execution, [tx], true) diff --git a/packages/client/test/rpc/eth/sendRawTransaction.spec.ts b/packages/client/test/rpc/eth/sendRawTransaction.spec.ts index 0d2de1b69e..c4254395c5 100644 --- a/packages/client/test/rpc/eth/sendRawTransaction.spec.ts +++ b/packages/client/test/rpc/eth/sendRawTransaction.spec.ts @@ -56,7 +56,7 @@ describe(method, () => { assert.equal( res.result, '0xd7217a7d3251880051783f305a3536e368c604aa1f1602e6cd107eb7b87129da', - 'should return the correct tx hash' + 'should return the correct tx hash', ) // Restore setStateRoot @@ -84,7 +84,7 @@ describe(method, () => { assert.equal( res.result, '0xf6798d5ed936a464ef4f49dd5a3abe1ad6947364912bd47c5e56781125d44ac3', - 'local tx with lower gasprice than minimum gasprice added to pool' + 'local tx with lower gasprice than minimum gasprice added to pool', ) // Restore setStateRoot @@ -122,8 +122,8 @@ describe(method, () => { assert.equal(res.error.code, INTERNAL_ERROR) assert.ok( res.error.message.includes( - 'client is not aware of the current chain height yet (give sync some more time)' - ) + 'client is not aware of the current chain height yet (give sync some more time)', + ), ) }) @@ -245,7 +245,7 @@ describe(method, () => { maxPriorityFeePerGas: 1000000n, to: randomBytes(20), }, - { common } + { common }, ).sign(pk) const replacementTx = create4844BlobTx( @@ -260,7 +260,7 @@ describe(method, () => { maxPriorityFeePerGas: 10000000n, to: randomBytes(20), }, - { common } + { common }, ).sign(pk) const vm = (client.services.find((s) => s.name === 'eth') as FullEthereumService).execution.vm await vm.stateManager.putAccount(tx.getSenderAddress(), new Account()) diff --git a/packages/client/test/rpc/eth/syncing.spec.ts b/packages/client/test/rpc/eth/syncing.spec.ts index 1945cf933e..89f55855fb 100644 --- a/packages/client/test/rpc/eth/syncing.spec.ts +++ b/packages/client/test/rpc/eth/syncing.spec.ts @@ -43,7 +43,7 @@ describe(method, () => { const rpcServer = startRPC(manager.getMethods()) const rpc = getRpcClient(rpcServer) const sync = client.services[0].synchronizer! - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ latest: () => { return @@ -65,7 +65,7 @@ describe(method, () => { const rpcServer = startRPC(manager.getMethods()) const rpc = getRpcClient(rpcServer) const sync = client.services[0].synchronizer as FullSynchronizer - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ latest: () => { return { diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 1fa17f829c..551daab306 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -60,7 +60,7 @@ type createClientArgs = { export function startRPC( methods: any, opts: StartRPCOpts = { port: 0 }, - withEngineMiddleware?: WithEngineMiddleware + withEngineMiddleware?: WithEngineMiddleware, ) { const { port, wsServer } = opts const server = new RPCServer(methods) @@ -123,7 +123,7 @@ export async function createClient(clientOpts: Partial = {}) { if ((chain as any)._headers !== undefined) { ;(chain as any)._headers.latest = BlockHeader.fromHeaderData( { withdrawalsRoot: common.isActivatedEIP(4895) ? KECCAK256_RLP : undefined }, - { common } + { common }, ) } @@ -280,7 +280,7 @@ export async function runBlockWithTxs( chain: Chain, execution: VMExecution, txs: TypedTransaction[], - fromEngine = false + fromEngine = false, ) { const { vm } = execution // build block with tx diff --git a/packages/client/test/rpc/net/version.spec.ts b/packages/client/test/rpc/net/version.spec.ts index c57f6d8069..8e07bf368d 100644 --- a/packages/client/test/rpc/net/version.spec.ts +++ b/packages/client/test/rpc/net/version.spec.ts @@ -12,7 +12,7 @@ function compareResult(result: any, chainId: any) { assert.equal( result, chainId, - `should be the correct chain ID (expected: ${chainId}, received: ${result})` + `should be the correct chain ID (expected: ${chainId}, received: ${result})`, ) } @@ -28,7 +28,7 @@ describe(method, () => { it('call on holesky', async () => { const manager = createManager( - await createClient({ opened: true, commonChain: new Common({ chain: Chain.Holesky }) }) + await createClient({ opened: true, commonChain: new Common({ chain: Chain.Holesky }) }), ) const rpc = getRpcClient(startRPC(manager.getMethods())) @@ -42,7 +42,7 @@ describe(method, () => { it('call on goerli', async () => { const manager = createManager( - await createClient({ opened: true, commonChain: new Common({ chain: Chain.Goerli }) }) + await createClient({ opened: true, commonChain: new Common({ chain: Chain.Goerli }) }), ) const rpc = getRpcClient(startRPC(manager.getMethods())) diff --git a/packages/client/test/rpc/txpool/content.spec.ts b/packages/client/test/rpc/txpool/content.spec.ts index d96485f403..bf95e680fa 100644 --- a/packages/client/test/rpc/txpool/content.spec.ts +++ b/packages/client/test/rpc/txpool/content.spec.ts @@ -40,7 +40,7 @@ describe(method, () => { gasLimit, }, }, - { common, calcDifficultyFromHeader: parent } + { common, calcDifficultyFromHeader: parent }, ) let ranBlock: Block | undefined = undefined @@ -63,10 +63,10 @@ describe(method, () => { common: service.chain.config.chainCommon, skipConsensusFormatValidation: true, calcDifficultyFromHeader: headBlock.header, - } + }, ), }, - { common: service.chain.config.chainCommon } + { common: service.chain.config.chainCommon }, ) vm.events.once('afterBlock', (result: any) => (ranBlock = result.block)) @@ -79,7 +79,7 @@ describe(method, () => { assert.equal( Object.keys(res.result.pending).length, 1, - 'received one pending transaction back from response' + 'received one pending transaction back from response', ) }) }) diff --git a/packages/client/test/rpc/validation.spec.ts b/packages/client/test/rpc/validation.spec.ts index b252433a34..932f37bf3b 100644 --- a/packages/client/test/rpc/validation.spec.ts +++ b/packages/client/test/rpc/validation.spec.ts @@ -52,15 +52,15 @@ describe(prefix, () => { // valid // zero address assert.ok( - validatorResult(validators.address(['0x0000000000000000000000000000000000000000'], 0)) + validatorResult(validators.address(['0x0000000000000000000000000000000000000000'], 0)), ) // lowercase address assert.ok( - validatorResult(validators.address(['0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270'], 0)) + validatorResult(validators.address(['0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270'], 0)), ) // checksummed address assert.ok( - validatorResult(validators.address(['0xa7d8d9ef8D8Ce8992Df33D8b8CF4Aebabd5bD270'], 0)) + validatorResult(validators.address(['0xa7d8d9ef8D8Ce8992Df33D8b8CF4Aebabd5bD270'], 0)), ) // invalid @@ -70,23 +70,23 @@ describe(prefix, () => { assert.notOk(validatorResult(validators.address(['0x1'], 0))) // invalid length: 38 chars assert.notOk( - validatorResult(validators.address(['0x00000000000000000000000000000000000000'], 0)) + validatorResult(validators.address(['0x00000000000000000000000000000000000000'], 0)), ) // invalidlength: 39 chars assert.notOk( - validatorResult(validators.address(['0x000000000000000000000000000000000000000'], 0)) + validatorResult(validators.address(['0x000000000000000000000000000000000000000'], 0)), ) // invalidlength: 41 chars assert.notOk( - validatorResult(validators.address(['0x00000000000000000000000000000000000000000'], 0)) + validatorResult(validators.address(['0x00000000000000000000000000000000000000000'], 0)), ) // invalid length: 42 chars assert.notOk( - validatorResult(validators.address(['0x00000000000000000000000000000000000000000'], 0)) + validatorResult(validators.address(['0x00000000000000000000000000000000000000000'], 0)), ) // invalid character assert.notOk( - validatorResult(validators.address(['0x62223651d6a33d58be70eb9876c3caf7096169ez'], 0)) + validatorResult(validators.address(['0x62223651d6a33d58be70eb9876c3caf7096169ez'], 0)), ) assert.ok(validatorResult(validators.bytes8([bytesToHex(randomBytes(8))], 0))) assert.ok(validatorResult(validators.bytes8([bytes(8)], 0))) @@ -228,59 +228,59 @@ describe(prefix, () => { validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a249'], - 0 - ) - ) + 0, + ), + ), ) assert.ok( validatorResult( validators.blockHash( ['0xf79d019c58d58a4efcfdf100c9596dd38014dcec6cf6f52000d4fae4e139b703'], - 0 - ) - ) + 0, + ), + ), ) // invalid length assert.notOk( validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a2'], - 0 - ) - ) + 0, + ), + ), ) assert.notOk( validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a24'], - 0 - ) - ) + 0, + ), + ), ) assert.notOk( validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a2499'], - 0 - ) - ) + 0, + ), + ), ) assert.notOk( validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a24999'], - 0 - ) - ) + 0, + ), + ), ) // invalid character assert.notOk( validatorResult( validators.blockHash( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66z249'], - 0 - ) - ) + 0, + ), + ), ) }) @@ -293,9 +293,9 @@ describe(prefix, () => { validatorResult( validators.blockOption( ['0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a249'], - 0 - ) - ) + 0, + ), + ), ) assert.ok(validatorResult(validators.blockOption(['0x1'], 0))) assert.ok(validatorResult(validators.blockOption(['0x01'], 0))) @@ -312,9 +312,9 @@ describe(prefix, () => { validatorResult( validators.blockOption( ['573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a249'], - 0 - ) - ) + 0, + ), + ), ) }) @@ -463,14 +463,14 @@ describe(prefix, () => { gas: '0xcf08', }, ], - 0 - ) - ) + 0, + ), + ), ) assert.ok( validatorResult( - validators.transaction(['to'])([{ to: '0x0000000000000000000000000000000000000000' }], 0) - ) + validators.transaction(['to'])([{ to: '0x0000000000000000000000000000000000000000' }], 0), + ), ) // invalid @@ -489,17 +489,17 @@ describe(prefix, () => { from: '0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a249', }, ], - 0 - ) - ) + 0, + ), + ), ) assert.notOk( validatorResult( validators.transaction(['to'])( [{ from: '0x573155e65afb5cc55035aa9113d29d4ca3625454b33d32b2dff7b6673c66a249' }], - 0 - ) - ) + 0, + ), + ), ) assert.notOk(validatorResult(validators.transaction([])([{ gas: '12' }], 0))) assert.notOk(validatorResult(validators.transaction([])([{ gasPrice: '12' }], 0))) @@ -525,22 +525,22 @@ describe(prefix, () => { hex: '0x1', }, ], - 0 - ) - ) + 0, + ), + ), ) // invalid assert.notOk( - validatorResult(validators.object({ address: validators.address })([{ address: '0x0' }], 0)) + validatorResult(validators.object({ address: validators.address })([{ address: '0x0' }], 0)), ) assert.notOk( validatorResult( - validators.object({ blockHash: validators.blockHash })([{ blockHash: '0x0' }], 0) - ) + validators.object({ blockHash: validators.blockHash })([{ blockHash: '0x0' }], 0), + ), ) assert.notOk( - validatorResult(validators.object({ bool: validators.bool })([{ bool: '0x0' }], 0)) + validatorResult(validators.object({ bool: validators.bool })([{ bool: '0x0' }], 0)), ) assert.notOk(validatorResult(validators.object({ hex: validators.hex })([{ hex: '1' }], 0))) }) @@ -557,37 +557,37 @@ describe(prefix, () => { '0xda4a22ad0d0e9aff0846ca54225637ada5bf7a14', ], ], - 0 - ) - ) + 0, + ), + ), ) assert.ok( validatorResult( validators.array(validators.blockHash)( [['0xb6dbbc1c702583de187e1284a00a23f9d322bf96f70fd4968b6339d0ace066b3']], - 0 - ) - ) + 0, + ), + ), ) assert.ok(validatorResult(validators.array(validators.bool)([[true, false]], 0))) // invalid assert.notOk( - validatorResult(validators.array(validators.hex)([['0x0', '0x1', '0x2', 'true']], 0)) + validatorResult(validators.array(validators.hex)([['0x0', '0x1', '0x2', 'true']], 0)), ) assert.notOk( validatorResult( validators.array(validators.address)( [['0xb7e390864a90b7b923c9f9310c6f98aafe43f707', '0x0']], - 0 - ) - ) + 0, + ), + ), ) assert.notOk( - validatorResult(validators.array(validators.blockHash)([['0xb6dbbc1cd0ace066b3']], 0)) + validatorResult(validators.array(validators.blockHash)([['0xb6dbbc1cd0ace066b3']], 0)), ) assert.notOk( - validatorResult(validators.array(validators.bool)([['0x123', '0x456', '0x789']], 0)) + validatorResult(validators.array(validators.bool)([['0x123', '0x456', '0x789']], 0)), ) assert.notOk(validatorResult(validators.array(validators.bool)([[true, 'true']], 0))) }) @@ -667,15 +667,15 @@ describe(prefix, () => { validatorResult( validators.optional(validators.blockHash)( ['0x0000000000000000000000000000000000000000000000000000000000000000'], - 0 - ) - ) + 0, + ), + ), ) assert.ok( - validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))(['INVALID'], 0)) + validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))(['INVALID'], 0)), ) assert.ok( - validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))([''], 0)) + validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))([''], 0)), ) assert.ok(validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))([], 0))) @@ -683,7 +683,7 @@ describe(prefix, () => { assert.notOk(validatorResult(validators.optional(validators.bool)(['hey'], 0))) assert.notOk(validatorResult(validators.optional(validators.blockHash)(['0x0'], 0))) assert.notOk( - validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))(['ANOTHER'], 0)) + validatorResult(validators.optional(validators.values(['VALID', 'INVALID']))(['ANOTHER'], 0)), ) }) @@ -696,35 +696,35 @@ describe(prefix, () => { validators.either( validators.bool, validators.hex, - validators.array(validators.hex) - )([['0xaaa']], 0) - ) + validators.array(validators.hex), + )([['0xaaa']], 0), + ), ) assert.ok( validatorResult( validators.either(validators.bool, validators.blockHash)( ['0x0000000000000000000000000000000000000000000000000000000000000000'], - 0 - ) - ) + 0, + ), + ), ) // invalid assert.notOk( - validatorResult(validators.either(validators.bool, validators.blockHash)(['0xabc'], 0)) + validatorResult(validators.either(validators.bool, validators.blockHash)(['0xabc'], 0)), ) assert.notOk(validatorResult(validators.either(validators.bool, validators.hex)(['abc'], 0))) assert.notOk( - validatorResult(validators.either(validators.hex, validators.blockHash)([true], 0)) + validatorResult(validators.either(validators.hex, validators.blockHash)([true], 0)), ) assert.notOk( validatorResult( validators.either( validators.hex, validators.blockHash, - validators.array(validators.hex) - )([[false]], 0) - ) + validators.array(validators.hex), + )([[false]], 0), + ), ) }) }) diff --git a/packages/client/test/rpc/web3/sha3.spec.ts b/packages/client/test/rpc/web3/sha3.spec.ts index 31706682fa..03896efd0c 100644 --- a/packages/client/test/rpc/web3/sha3.spec.ts +++ b/packages/client/test/rpc/web3/sha3.spec.ts @@ -8,7 +8,7 @@ function compareErrorCode(error: any, errorCode: any) { assert.equal( error.code, errorCode, - `should return the correct error code (expected: ${errorCode}, received: ${error.code})` + `should return the correct error code (expected: ${errorCode}, received: ${error.code})`, ) } @@ -26,7 +26,7 @@ describe(method, () => { assert.equal( result, '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad', - 'should return the correct hash value' + 'should return the correct hash value', ) }) diff --git a/packages/client/test/service/fullethereumservice.spec.ts b/packages/client/test/service/fullethereumservice.spec.ts index 03336d3e68..0915fdb095 100644 --- a/packages/client/test/service/fullethereumservice.spec.ts +++ b/packages/client/test/service/fullethereumservice.spec.ts @@ -136,7 +136,7 @@ describe('should start/stop', async () => { describe('should correctly handle GetBlockHeaders', async () => { const config = new Config({ accountCache: 10000, storageCache: 1000 }) vi.unmock('../../src/blockchain') - await import('../../src/blockchain') + await import('../../src/blockchain/index.js') const chain = await Chain.create({ config }) chain.getHeaders = () => [{ number: 1n }] as any const service = new FullEthereumService({ config, chain }) @@ -152,12 +152,12 @@ describe('should correctly handle GetBlockHeaders', async () => { it('should send empty headers', () => { assert.ok( title === 'BlockHeaders' && msg.headers.length === 0, - 'sent empty headers when block height is too high' + 'sent empty headers when block height is too high', ) }) }, } as any, - } as any + } as any, ) ;(service.chain as any)._headers = { height: 5n, @@ -177,12 +177,12 @@ describe('should correctly handle GetBlockHeaders', async () => { it('should send 1 header', () => { assert.ok( title === 'BlockHeaders' && msg.headers.length === 1, - 'sent 1 header when requested' + 'sent 1 header when requested', ) }) }, } as any, - } as any + } as any, ) }) @@ -204,7 +204,7 @@ describe('should call handleNewBlock on NewBlock and handleNewBlockHashes on New await service.switchToBeaconSync() assert.ok( (service.synchronizer as BeaconSynchronizer).type === 'beacon', - 'switched to BeaconSynchronizer' + 'switched to BeaconSynchronizer', ) assert.ok(service.beaconSync, 'can access BeaconSynchronizer') }) @@ -282,7 +282,7 @@ describe('should handle Transactions', async () => { data: [createTxFromTxData({ type: 2 })], }, 'eth', - undefined as any + undefined as any, ) }) @@ -306,7 +306,7 @@ describe('should handle NewPooledTransactionHashes', async () => { eth: { versions: [66], }, - } as any + } as any, ) }) @@ -330,7 +330,7 @@ describe('should handle GetPooledTransactions', async () => { }) }, } as any, - } as any + } as any, ) }) @@ -344,7 +344,7 @@ describe('should handle decoding NewPooledTransactionHashes with eth/68 message ;(service.txPool as any).handleAnnouncedTxHashes = ( hashes: Uint8Array[], _peer: any, - _pool: any + _pool: any, ) => { it('should get correct tx hash from eth68 message', () => { assert.deepEqual(hashes[0], txHash) @@ -358,7 +358,7 @@ describe('should handle decoding NewPooledTransactionHashes with eth/68 message eth: { versions: [67, 68], }, - } as any + } as any, ) }) @@ -381,7 +381,7 @@ describe.skip('should handle structuring NewPooledTransactionHashes with eth/68 }, }, } as any, - ] + ], ) }) diff --git a/packages/client/test/service/lightethereumservice.spec.ts b/packages/client/test/service/lightethereumservice.spec.ts index cec1e520bc..ede731051b 100644 --- a/packages/client/test/service/lightethereumservice.spec.ts +++ b/packages/client/test/service/lightethereumservice.spec.ts @@ -1,6 +1,6 @@ import { assert, describe, expect, it, vi } from 'vitest' -import { Chain } from '../../src/blockchain/chain' +import { Chain } from '../../src/blockchain/chain.js' import { Config } from '../../src/config.js' import { LesProtocol } from '../../src/net/protocol/index.js' import { RlpxServer } from '../../src/net/server/index.js' diff --git a/packages/client/test/sim/4844-blobpost.spec.ts b/packages/client/test/sim/4844-blobpost.spec.ts index 237098b5aa..68c41c4ec5 100644 --- a/packages/client/test/sim/4844-blobpost.spec.ts +++ b/packages/client/test/sim/4844-blobpost.spec.ts @@ -17,7 +17,7 @@ import type { PrefixedHexString } from '@ethereumjs/util' const pkey = hexToBytes( (process.env.PRIVATE_KEY as PrefixedHexString) ?? - '0xae557af4ceefda559c924516cabf029bedc36b68109bf8d6183fe96e04121f4e' + '0xae557af4ceefda559c924516cabf029bedc36b68109bf8d6183fe96e04121f4e', ) const sender = bytesToHex(privateToAddress(pkey)) const rpcUrl = @@ -68,7 +68,7 @@ describe(`running txes on ${rpcUrl}`, async () => { const nonceFetch = await client.request( 'eth_getTransactionCount', [sender.toString(), 'latest'], - 2.0 + 2.0, ) const nonce = Number(nonceFetch.result) assert.ok(true, `fetched ${sender}'s nonce=${nonce} for blob txs`) @@ -86,7 +86,7 @@ describe(`running txes on ${rpcUrl}`, async () => { gasLimit: BigInt(process.env.GAS_LIMIT ?? 0xffffffn), blobSize: Number(process.env.BLOB_SIZE ?? 4096), }, - { common } + { common }, ) const txHashes = [] for (const txn of txns) { @@ -101,7 +101,7 @@ describe(`running txes on ${rpcUrl}`, async () => { } assert.ok(true, `posted txs=${txHashes.length}`) }, - 10 * 60_000 + 10 * 60_000, ) it('cleanup', async () => { diff --git a/packages/client/test/sim/4844-devnet.spec.ts b/packages/client/test/sim/4844-devnet.spec.ts index c0c4cf225d..b482324020 100644 --- a/packages/client/test/sim/4844-devnet.spec.ts +++ b/packages/client/test/sim/4844-devnet.spec.ts @@ -63,7 +63,7 @@ describe('sharding/eip4844 hardfork tests', async () => { pkey, '0x3dA33B9A0894b908DdBb00d96399e506515A1009', undefined, - { common } + { common }, ) const eth2res = await (await fetch('http://127.0.0.1:9596/eth/v1/beacon/headers')).json() @@ -98,7 +98,7 @@ describe('sharding/eip4844 hardfork tests', async () => { assert.equal( eth2kzgs[0], bytesToHex(txResult.tx.kzgCommitments![0]), - 'found expected blob commitments on CL' + 'found expected blob commitments on CL', ) }, 60_000) @@ -119,7 +119,7 @@ describe('sharding/eip4844 hardfork tests', async () => { gasLimit: BigInt(1000000) as any, blobSize: 4096, }, - { common } + { common }, ) const txHashes = [] for (const txn of txns) { @@ -138,7 +138,7 @@ describe('sharding/eip4844 hardfork tests', async () => { const block1 = await client.request( 'eth_getBlockByHash', [txReceipt.result.blockHash, false], - 2.0 + 2.0, ) // next block will have the excessBlobGas done = false @@ -153,14 +153,14 @@ describe('sharding/eip4844 hardfork tests', async () => { } assert.ok(BigInt(block2.result.excessBlobGas) > 0n, 'block1 has excess blob gas > 0') }, - 10 * 60_000 + 10 * 60_000, ) it('point precompile contract test', async () => { const nonce = await client.request( 'eth_getTransactionCount', [sender.toString(), 'latest'], - 2.0 + 2.0, ) /* Data is contract deployment code for the below contract borrowed from the 4844-interop repo @@ -179,7 +179,7 @@ describe('sharding/eip4844 hardfork tests', async () => { const txData = { data: hexToBytes( - '0xf9031103830186a0830f42408080b902c0608060405234801561001057600080fd5b50604051610260380380610260833981810160405281019061003291906101ca565b60008060c0835160145afa61004657600080fd5b50610213565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100b38261006a565b810181811067ffffffffffffffff821117156100d2576100d161007b565b5b80604052505050565b60006100e561004c565b90506100f182826100aa565b919050565b600067ffffffffffffffff8211156101115761011061007b565b5b61011a8261006a565b9050602081019050919050565b60005b8381101561014557808201518184015260208101905061012a565b83811115610154576000848401525b50505050565b600061016d610168846100f6565b6100db565b90508281526020810184848401111561018957610188610065565b5b610194848285610127565b509392505050565b600082601f8301126101b1576101b0610060565b5b81516101c184826020860161015a565b91505092915050565b6000602082840312156101e0576101df610056565b5b600082015167ffffffffffffffff8111156101fe576101fd61005b565b5b61020a8482850161019c565b91505092915050565b603f806102216000396000f3fe6080604052600080fdfea2646970667358221220cbb964afe0f584a89b887bf992e18697c0ebd77a40a102c121f54213f23d4d9464736f6c634300080f00330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000212340000000000000000000000000000000000000000000000000000000000001ba002e89a44a4e4da739fed1ed658079a75dbcb59eebbd8ea0cb11f88a41d611dfaa025fe1645a1d3c9828be471fac5cd3e4be59c90ea304c94d774ff88c84349d8db' + '0xf9031103830186a0830f42408080b902c0608060405234801561001057600080fd5b50604051610260380380610260833981810160405281019061003291906101ca565b60008060c0835160145afa61004657600080fd5b50610213565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100b38261006a565b810181811067ffffffffffffffff821117156100d2576100d161007b565b5b80604052505050565b60006100e561004c565b90506100f182826100aa565b919050565b600067ffffffffffffffff8211156101115761011061007b565b5b61011a8261006a565b9050602081019050919050565b60005b8381101561014557808201518184015260208101905061012a565b83811115610154576000848401525b50505050565b600061016d610168846100f6565b6100db565b90508281526020810184848401111561018957610188610065565b5b610194848285610127565b509392505050565b600082601f8301126101b1576101b0610060565b5b81516101c184826020860161015a565b91505092915050565b6000602082840312156101e0576101df610056565b5b600082015167ffffffffffffffff8111156101fe576101fd61005b565b5b61020a8482850161019c565b91505092915050565b603f806102216000396000f3fe6080604052600080fdfea2646970667358221220cbb964afe0f584a89b887bf992e18697c0ebd77a40a102c121f54213f23d4d9464736f6c634300080f00330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000212340000000000000000000000000000000000000000000000000000000000001ba002e89a44a4e4da739fed1ed658079a75dbcb59eebbd8ea0cb11f88a41d611dfaa025fe1645a1d3c9828be471fac5cd3e4be59c90ea304c94d774ff88c84349d8db', ), nonce: BigInt(nonce.result), gasLimit: 0xffffff, @@ -192,7 +192,7 @@ describe('sharding/eip4844 hardfork tests', async () => { const txResult = await client.request( 'eth_sendRawTransaction', [bytesToHex(tx.serialize())], - 2.0 + 2.0, ) let receipt = await client.request('eth_getTransactionReceipt', [txResult.result], 2.0) while (receipt.result === null) { @@ -201,7 +201,7 @@ describe('sharding/eip4844 hardfork tests', async () => { } assert.ok( receipt.result.contractAddress !== undefined, - 'successfully deployed contract that calls precompile' + 'successfully deployed contract that calls precompile', ) }, 60_000) /* diff --git a/packages/client/test/sim/beaconsync.spec.ts b/packages/client/test/sim/beaconsync.spec.ts index 7611183123..01c4b8d5f1 100644 --- a/packages/client/test/sim/beaconsync.spec.ts +++ b/packages/client/test/sim/beaconsync.spec.ts @@ -89,7 +89,7 @@ describe('simple mainnet test run', async () => { assert.equal( EOATransferToBalance, BigInt(balance.result), - `fetched ${EOATransferToAccount} balance=${EOATransferToBalance}` + `fetched ${EOATransferToAccount} balance=${EOATransferToBalance}`, ) balance = await client.request('eth_getBalance', [EOATransferToAccount, 'latest']) @@ -107,10 +107,10 @@ describe('simple mainnet test run', async () => { balance = await client.request('eth_getBalance', [sender, 'latest']) assert.ok( balance.result !== undefined, - 'remaining sender balance after transfers and gas fee' + 'remaining sender balance after transfers and gas fee', ) }, - 2 * 60_000 + 2 * 60_000, ) it.skipIf(process.env.BEACON_SYNC === undefined)( @@ -127,7 +127,7 @@ describe('simple mainnet test run', async () => { common, customGenesisState, [nodeInfo.enode], - peerBeaconUrl + peerBeaconUrl, ).catch((e) => { console.log(e) return null @@ -152,7 +152,7 @@ describe('simple mainnet test run', async () => { assert.fail('could not connect to geth peer in 10 seconds') } }, - 60_000 + 60_000, ) it.skipIf(process.env.BEACON_SYNC === undefined)( @@ -170,7 +170,7 @@ describe('simple mainnet test run', async () => { assert.equal( ['SYNCED', 'VALID'].includes(syncResponse.syncState), true, - 'beaconSyncRelayer should have synced client' + 'beaconSyncRelayer should have synced client', ) await ejsClient.stop() assert.ok(true, 'completed beacon sync') @@ -182,7 +182,7 @@ describe('simple mainnet test run', async () => { assert.fail('ethereumjs client not setup properly for beacon sync') } }, - 10 * 60_000 + 10 * 60_000, ) it('network cleanup', async () => { @@ -201,7 +201,7 @@ async function createBeaconSyncClient( customGenesisState?: any, bootnodes?: any, peerBeaconUrl?: any, - datadir?: any + datadir?: any, ) { // Turn on `debug` logs, defaults to all client logging debug.enable(process.env.DEBUG_SYNC ?? '') diff --git a/packages/client/test/sim/eof.spec.ts b/packages/client/test/sim/eof.spec.ts index 33401e9e2b..b44ad8700a 100644 --- a/packages/client/test/sim/eof.spec.ts +++ b/packages/client/test/sim/eof.spec.ts @@ -87,7 +87,7 @@ describe('EOF ephemeral hardfork tests', async () => { assert.equal( code.result, '0XEF00010100010200010000AA'.toLowerCase(), - 'deposited valid EOF1 code' + 'deposited valid EOF1 code', ) }) // ------------EIP 3860 tests------------------------------- @@ -105,7 +105,7 @@ describe('EOF ephemeral hardfork tests', async () => { const push0res = await runTx('0x5F') assert.ok( BigInt(push1res.gasUsed) > BigInt(push0res.gasUsed), - 'PUSH1 transaction costs higher gas than PUSH0' + 'PUSH1 transaction costs higher gas than PUSH0', ) }) // ------------EIP 3651 tests------------------------------- @@ -129,18 +129,18 @@ describe('EOF ephemeral hardfork tests', async () => { */ const contractAddress = ( await runTx( - '0x608060405234801561001057600080fd5b5061021d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635caba0a41461003b578063e178495614610057575b600080fd5b6100556004803603810190610050919061011b565b610061565b005b61005f6100b4565b005b7fe37f346e484eff2a55fc81911c0cd6f3f9403f2c3d4c34f3b705adaf5e15620f818273ffffffffffffffffffffffffffffffffffffffff16316040516100a9929190610166565b60405180910390a150565b7fe37f346e484eff2a55fc81911c0cd6f3f9403f2c3d4c34f3b705adaf5e15620f414173ffffffffffffffffffffffffffffffffffffffff16316040516100fc929190610166565b60405180910390a1565b600081359050610115816101d0565b92915050565b600060208284031215610131576101306101cb565b5b600061013f84828501610106565b91505092915050565b6101518161018f565b82525050565b610160816101c1565b82525050565b600060408201905061017b6000830185610148565b6101886020830184610157565b9392505050565b600061019a826101a1565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b6101d98161018f565b81146101e457600080fd5b5056fea2646970667358221220d00dedb6dcbb511fab3ae484199f836b4c36119fb6faec1baee5e29db1ead12864736f6c63430008070033' + '0x608060405234801561001057600080fd5b5061021d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635caba0a41461003b578063e178495614610057575b600080fd5b6100556004803603810190610050919061011b565b610061565b005b61005f6100b4565b005b7fe37f346e484eff2a55fc81911c0cd6f3f9403f2c3d4c34f3b705adaf5e15620f818273ffffffffffffffffffffffffffffffffffffffff16316040516100a9929190610166565b60405180910390a150565b7fe37f346e484eff2a55fc81911c0cd6f3f9403f2c3d4c34f3b705adaf5e15620f414173ffffffffffffffffffffffffffffffffffffffff16316040516100fc929190610166565b60405180910390a1565b600081359050610115816101d0565b92915050565b600060208284031215610131576101306101cb565b5b600061013f84828501610106565b91505092915050565b6101518161018f565b82525050565b610160816101c1565b82525050565b600060408201905061017b6000830185610148565b6101886020830184610157565b9392505050565b600061019a826101a1565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600080fd5b6101d98161018f565b81146101e457600080fd5b5056fea2646970667358221220d00dedb6dcbb511fab3ae484199f836b4c36119fb6faec1baee5e29db1ead12864736f6c63430008070033', ) ).contractAddress const readWarmCoinbase = await runTx('0xe1784956', contractAddress) const readCold = await runTx( '0x5caba0a40000000000000000000000004242424242424242424242424242424242424242', - contractAddress + contractAddress, ) assert.ok( BigInt(readCold.gasUsed) > BigInt(readWarmCoinbase.gasUsed), - 'read cold storage tx should have higher cumulative gas than than read coinbase tx' + 'read cold storage tx should have higher cumulative gas than than read coinbase tx', ) }) diff --git a/packages/client/test/sim/mainnet.spec.ts b/packages/client/test/sim/mainnet.spec.ts index 459a5c0614..f21262f476 100644 --- a/packages/client/test/sim/mainnet.spec.ts +++ b/packages/client/test/sim/mainnet.spec.ts @@ -75,7 +75,7 @@ describe('simple mainnet test run', async () => { const latestBlock = await client.request('eth_getBlockByNumber', ['latest', false]) blockHashes.push(latestBlock.result.hash) }, - 2 * 60_000 + 2 * 60_000, ) it('Validate execution hashes present in beacon headers', async () => { @@ -84,7 +84,7 @@ describe('simple mainnet test run', async () => { 'http://127.0.0.1:9596', 1, parseInt(eth2res.data[0].header.message.slot), - blockHashes + blockHashes, ) }, 60_000) diff --git a/packages/client/test/sim/simutils.ts b/packages/client/test/sim/simutils.ts index 252ea2decc..2ddba64f10 100644 --- a/packages/client/test/sim/simutils.ts +++ b/packages/client/test/sim/simutils.ts @@ -19,11 +19,11 @@ import { execSync, spawn } from 'node:child_process' import * as net from 'node:net' import qs from 'qs' -import { EthereumClient } from '../../src/client' +import { EthereumClient } from '../../src/client.js' import { Config } from '../../src/config.js' -import { LevelDB } from '../../src/execution/level' -import { RPCManager } from '../../src/rpc' -import { Event } from '../../src/types' +import { LevelDB } from '../../src/execution/level.js' +import { RPCManager } from '../../src/rpc/index.js' +import { Event } from '../../src/types.js' import type { Common } from '@ethereumjs/common' import type { TransactionType, TxData, TxOptions } from '@ethereumjs/tx' @@ -117,7 +117,7 @@ export async function validateBlockHashesInclusionInBeacon( beaconUrl: string, from: number, to: number, - blockHashes: string[] + blockHashes: string[], ) { const executionHashes: string[] = [] for (let i = from; i <= to; i++) { @@ -147,7 +147,7 @@ type RunOpts = { export function runNetwork( network: string, client: Client, - { filterKeywords, filterOutWords, withPeer }: RunOpts + { filterKeywords, filterOutWords, withPeer }: RunOpts, ): () => Promise { const runProc = spawn('test/sim/single-run.sh', [], { env: { @@ -255,7 +255,7 @@ export function runNetwork( export async function startNetwork( network: string, client: Client, - opts: RunOpts + opts: RunOpts, ): Promise<{ teardownCallBack: () => Promise; result: string }> { let teardownCallBack if (opts.externalRun === undefined) { @@ -271,7 +271,7 @@ export async function runTxHelper( opts: { client: Client; common: Common; sender: string; pkey: Uint8Array }, data: PrefixedHexString | '', to?: PrefixedHexString, - value?: bigint + value?: bigint, ) { const { client, common, sender, pkey } = opts const nonce = BigInt((await client.request('eth_getTransactionCount', [sender, 'latest'])).result) @@ -289,7 +289,7 @@ export async function runTxHelper( to, value, }, - { common } + { common }, ).sign(pkey) const res = await client.request('eth_sendRawTransaction', [bytesToHex(tx.serialize())], 2.0) @@ -316,7 +316,7 @@ export const runBlobTx = async ( pkey: Uint8Array, to?: PrefixedHexString, value?: bigint, - opts?: TxOptions + opts?: TxOptions, ) => { const blobs = getBlobs(bytesToHex(randomBytes(blobSize))) const commitments = blobsToCommitments(kzg, blobs) @@ -383,7 +383,7 @@ export const createBlobTxs = async ( gasLimit: bigint blobSize: number }, - opts?: TxOptions + opts?: TxOptions, ) => { const txHashes: string[] = [] const blobSize = txMeta.blobSize ?? 2 ** 17 - 1 @@ -432,17 +432,17 @@ export async function createInlineClient( config: any, common: any, customGenesisState: any, - datadir: any = Config.DATADIR_DEFAULT + datadir: any = Config.DATADIR_DEFAULT, ) { config.events.setMaxListeners(50) const chainDB = new Level( - `${datadir}/${common.chainName()}/chainDB` + `${datadir}/${common.chainName()}/chainDB`, ) const stateDB = new Level( - `${datadir}/${common.chainName()}/stateDB` + `${datadir}/${common.chainName()}/stateDB`, ) const metaDB = new Level( - `${datadir}/${common.chainName()}/metaDB` + `${datadir}/${common.chainName()}/metaDB`, ) const blockchain = await createBlockchain({ @@ -506,7 +506,7 @@ export async function setupEngineUpdateRelay(client: EthereumClient, peerBeaconU !['SYNCING', 'VALID', 'ACCEPTED'].includes(newPayloadRes.status) ) { throw Error( - `newPayload error: status${newPayloadRes.status} validationError=${newPayloadRes.validationError} error=${newPayloadRes.error}` + `newPayload error: status${newPayloadRes.status} validationError=${newPayloadRes.validationError} error=${newPayloadRes.error}`, ) } @@ -545,7 +545,7 @@ export async function setupEngineUpdateRelay(client: EthereumClient, peerBeaconU const beaconHead = await (await fetch(`${peerBeaconUrl}/eth/v2/beacon/blocks/head`)).json() const payload = executionPayloadFromBeaconPayload( - beaconHead.data.message.body.execution_payload + beaconHead.data.message.body.execution_payload, ) const finalizedBlockHash = beaconFinalized.data.finalized_header.execution.block_hash diff --git a/packages/client/test/sim/snapsync.spec.ts b/packages/client/test/sim/snapsync.spec.ts index e8aded7d90..89ae5e2422 100644 --- a/packages/client/test/sim/snapsync.spec.ts +++ b/packages/client/test/sim/snapsync.spec.ts @@ -22,9 +22,9 @@ import { setupEngineUpdateRelay, startNetwork, waitForELStart, -} from './simutils' +} from './simutils.js' -import type { EthereumClient } from '../../src/client' +import type { EthereumClient } from '../../src/client.js' import type { DefaultStateManager } from '@ethereumjs/statemanager' import type { PrefixedHexString } from '@ethereumjs/util' @@ -92,7 +92,7 @@ describe('simple mainnet test run', async () => { assert.equal( EOATransferToBalance, BigInt(balance.result), - `fetched ${EOATransferToAccount} balance=${EOATransferToBalance}` + `fetched ${EOATransferToAccount} balance=${EOATransferToBalance}`, ) balance = await client.request('eth_getBalance', [EOATransferToAccount, 'latest']) @@ -110,11 +110,11 @@ describe('simple mainnet test run', async () => { balance = await client.request('eth_getBalance', [sender, 'latest']) assert.ok( balance.result !== undefined, - 'remaining sender balance after transfers and gas fee' + 'remaining sender balance after transfers and gas fee', ) senderBalance = BigInt(balance.result) }, - 2 * 60_000 + 2 * 60_000, ) it.skipIf(process.env.SNAP_SYNC === undefined)( @@ -135,7 +135,7 @@ describe('simple mainnet test run', async () => { customGenesisState, [nodeInfo.enode], peerBeaconUrl, - '' + '', ).catch((e) => { console.log(e) return null @@ -162,7 +162,7 @@ describe('simple mainnet test run', async () => { assert.fail('could not connect to geth peer in 10 seconds') } }, - 60_000 + 60_000, ) it.skipIf(process.env.SNAP_SYNC === undefined)( @@ -201,7 +201,7 @@ describe('simple mainnet test run', async () => { assert.fail('ethereumjs client not setup properly for snap sync') } }, - 10 * 60_000 + 10 * 60_000, ) it.skipIf(stateManager !== undefined)('should match entire state', async () => { @@ -222,7 +222,7 @@ describe('simple mainnet test run', async () => { assert.equal( account?.balance, BigInt(customGenesisState[addressString][0]), - `${addressString} balance should match` + `${addressString} balance should match`, ) } }) @@ -244,7 +244,7 @@ async function createSnapClient( customGenesisState: any, bootnodes: any, peerBeaconUrl: any, - datadir: any + datadir: any, ) { // Turn on `debug` logs, defaults to all client logging debug.enable(process.env.DEBUG_SNAP ?? '') @@ -272,7 +272,7 @@ async function createSnapClient( config.events.once( Event.SYNC_SNAPSYNC_COMPLETE, (stateRoot: Uint8Array, stateManager: DefaultStateManager) => - resolve([stateRoot, stateManager]) + resolve([stateRoot, stateManager]), ) }) diff --git a/packages/client/test/sync/beaconsync.spec.ts b/packages/client/test/sync/beaconsync.spec.ts index 81173704eb..722f2f6104 100644 --- a/packages/client/test/sync/beaconsync.spec.ts +++ b/packages/client/test/sync/beaconsync.spec.ts @@ -30,7 +30,7 @@ describe('[BeaconSynchronizer]', async () => { ReverseBlockFetcher.prototype.destroy = td.func() vi.doMock('../../src/sync/fetcher/reverseblockfetcher.js', () => - td.constructor(ReverseBlockFetcher) + td.constructor(ReverseBlockFetcher), ) const { BeaconSynchronizer } = await import('../../src/sync/beaconsync.js') @@ -132,11 +132,11 @@ describe('[BeaconSynchronizer]', async () => { const pool = new PeerPool() as any const chain = await Chain.create({ config }) const skeleton = new Skeleton({ chain, config, metaDB: new MemoryLevel() }) - skeleton['getSyncStatus'] = td.func() + skeleton['getSyncStatus'] = td.func<(typeof skeleton)['getSyncStatus']>() await skeleton.open() const sync = new BeaconSynchronizer({ config, pool, chain, execution, skeleton }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ latest: () => { return { @@ -186,10 +186,10 @@ describe('[BeaconSynchronizer]', async () => { const pool = new PeerPool() as any const chain = await Chain.create({ config }) const skeleton = new Skeleton({ chain, config, metaDB: new MemoryLevel() }) - skeleton['getSyncStatus'] = td.func() + skeleton['getSyncStatus'] = td.func<(typeof skeleton)['getSyncStatus']>() await skeleton.open() const sync = new BeaconSynchronizer({ config, pool, chain, execution, skeleton }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ latest: () => { return { @@ -238,7 +238,7 @@ describe('[BeaconSynchronizer]', async () => { assert.notOk(await sync.extendChain(gapBlock), 'should not extend chain with gapped block') assert.ok( await sync.setHead(gapBlock), - 'should be able to set and update head with gapped block' + 'should be able to set and update head with gapped block', ) assert.equal(skeleton.bounds().head, BigInt(18), 'head should update with gapped block') await sync.stop() @@ -256,7 +256,7 @@ describe('[BeaconSynchronizer]', async () => { assert.equal( await sync.syncWithPeer({} as any), false, - `syncWithPeer should return false as nothing to sync` + `syncWithPeer should return false as nothing to sync`, ) await sync.stop() await sync.close() diff --git a/packages/client/test/sync/fetcher/accountfetcher.spec.ts b/packages/client/test/sync/fetcher/accountfetcher.spec.ts index 949262c9ff..86a9da8c1b 100644 --- a/packages/client/test/sync/fetcher/accountfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/accountfetcher.spec.ts @@ -19,10 +19,10 @@ export const _accountRangeRLP = '0xf90b7c01f88aeda0000001907a67cf7ece54c42262997b2f19041a4d99466b94b8c12f225827e239cb80872386f26fc100008080eda00000107c642e29a6b613205c923ac3a4cf0cf1704ae9a8bef2784caba060f4b7cb07870e22e1219054118080eda000001d26422787b6d40c0c0c2df85757c5ad4a3e367831e932fa24f34da43d57cb80872386f26fc100008080f90aecb90214f90211a0b3f22b069c398ded55d4ce421b06f6b4d5e13cb53ad1c6220276b2b3a078937ba08a54e492e7b9ef911b4a299487a12390ccd81a087398af7106e00b81a791868da0a323a93f5791d4c39e1496e4856f9233e5e86070c722efde613219aca834bde3a0d8c11a8fc2eba0b47de9d5b207b702a8bd62609e9c2504aaa444fd2e98e31deaa0dbfc625e370fa89cb7b123550ef6fd637687b9e9a7c8556bd41bcd4226226095a094fe5f6ac37c805917beefa220d7c6b3bd50848322f6342e940cc047c9b6a8ffa074af7e57b9c59e06a2e478610d56ab39004cda3109cfd953dc8b1d168c453cbca0d58f31d0ecce773d610aa5d12f7cc2f4ca992db4ce2e154c13a12cb4bb567816a0b26a7d9776165bb52e793df6a77d4032164d788bf9954c9cac289ea0786da2fda043804bd146f583b183dc267b36bbe55f63daa36fd6cbdafce48ce451a444b4eca0fc724e8bb65724450eb3966d8672330c8e49a94c6ceaed06174a2322aafee105a02ccb0445b0a4028f167e425b57cb9462cc6caceda0c3cfb5363f08614314a77ca0c64db3edb50609b6de331f00ba1f455113d1388e9eb5f50f5420983012d62b7da0168c680c03ef3fbcc36a6c1ddd9bf7d46b5fd5ee34dd7048320223c8bbe412f9a05747d2eb930bffce317c253e3889a7db57c87dcc55f1f1f77b3d02fc82bc6bcfa0997073e1664f9cbbcfd968277856596c325a6b83887f4ad007c3b93e1133c65280b90214f90211a0b3e6ec5fa09062b280599994d38261cae87ab198ed1b3a7d7003a277ffc735dfa01bac91007228f4fa15ac9c2a4822b7d4103eafae61dd3db30eb830e31de9cddfa0809973bebc62f48fb834336800b1ce8e1b2128ee5824645464b6c09ddd381578a0f8d54e19e888fc01cd5069bfcddb7ee78a4afdec24aa03822d9fd5356a3c109fa08a61ea95c616906799398778b28f0e8a19f6569f885e4b4f1192f3e9f690cefea09aa53cd259b1df9650222dc285236399da685b7350312a3ac0a07a86bef64d5ea01596637937233489a70e114c23818e3512b3c2abf621d142c14a9b9a3afb09d1a0e8a8bcda78ae77bee956389dff38a10c8c1565bc1a85064da6cd8ba606b9aa35a04ae4b4bfbfb97f5b4e178f8c30a6d93ffd6614c8b4d0b44df31b653a3a1e4f0fa0a4e3413e6ee6c5886ed346827ee0cce05a8e4f799b005aacf002a17e6d93e5aaa09a3e6d344bbd2496bf8fa84abc96a3d5f363ba03103edff2164244bb020c52a2a0998f39835105197f860930b46adad4527f5a9ef31c4744476718b910ffc5e586a01cec4592958b5aefe25bea6a49a11089e798d96aebc2be7fce0f1772146d18aea0d7c178ed5bcf822d22f9ed3ca8c95e5144ee0a9fbae901b21da002e2c3c0415ea0a9d5c5c67326f4154449575827ab68ea47c7c8931490160a7a299f829a670476a074814ffe69da7e253de29fc7d5eb57291a67bd6f16cb52175106b7cbd3b19c8f80b90214f90211a0947eec1b645849d129fb8c65cd06bd52526fb2399d1660ee5108fc4698e809aaa02735f6cbb0e10514b1515826ae1c539850543dbe162badaf2efa51b1a353ca1ca0fde2642bcc8db8d6d6e42731eeae2045fc30b84c6efdc420ce8cee5d537b648fa071e7887ca31ae375838ceeed57165f5592a9e6cae9beb070e92a4f5d5aec5014a0f81f4b4d5e2c52373b8884b398838941df0b16177aa4ea8494b183176cf7d526a0dc6ecec073532c8f9581ece75cb4eea83a40ba0210cc10ef0fd8b27a102a028fa0426f18f1de1bc9b665e9efb45d6547e88e35a267d7ec9197ae97052d1be59ab9a0d6aad68bece934d578e18eb3acd147490bc6cc01e646f1d8618a747526eae4f5a04ffee6f8660794981b15fda1ceafef98db853bfc31c029db7cb515bb34bb5572a0da2497fed45626b94c1eb910c9eedc9c26a4ff5b56b709b96d5a567991ebe2aca021b3bfcd8aa97eb8d9a3ce258389603564f01d6f485899a9f6e0a00d85dc00dfa0339e45f0407ad527a899a2e06e17330c2cfe25b81689dcffd20c166ef256fbc6a0dafd25416aaf44a8bfa1a6bf2b0cc563f9be84b9b3b8bf307983252d7cd63c51a0191504034adb55fe0926c7c4066654739af3e1c9c4173f4d90fa2e1df62a99cca0504e2144c1a889e48cd5a6baa17e39b6a176dbf41147dd171f2673c5c9d849dba04850f33ad929cb1a07136f162e33a5df0f65c48f359637774e7c8ebabe90eb7080b90214f90211a05d16e93a6e58a13a7c7dde40d0c543b9d63d029ec0da5efb4be34cd4ce672181a089cbb0e940fb7bb395091e3b665755be6b51292fba7a7bc39904568c63a907e1a050314b93f73fed553cd9dee63dc1fe9b789f9b9e111a659ff4e4c91c8167a63ca04444bd2a1bb78a83b66a36a09076b2b49eade4e2e8c8ef91538117525893841aa0abde6220817f3608bdfec46ebed292c464ee1d2c58d0b43286b8617bb4cb49d9a07257eff6aebb380db4c75752a84c6b2d0bb86bb190cef2a58829497997262b6aa0a0d4ab9d93be97287f29637a9b16fb8a6c8cd3bc29786b64343113b95a4153ffa0f0d479377ce4c0f31185c45319f915532cea13e97d5abfc939b75b642b5b47bba0eb96a911347f5321e03f1602a041ce82ec29bb4b322faa9f999cf02bb0c7a932a047b6c76ffeb29b4e3c3c09749289213395c8b0126dbd8acee45c6d32d2a0ab5fa0ca462e8ff237f9e56698ca416fac835ed37bc90683d363effe7ec9dacb4963fba0d385f828becce3665e070b645df25dec507a7c6c3813591e3436147be0becc75a0537a7451522228feca0ceb55374615e8396229e1c7a6b0ae16fb49cd8e6ed7a9a0b96561ab484f67b604d2dc46ac170750b321334aabcfb6b212a906e1cb5b3532a09f64f7c76e201d48b4bc1fb02f7e052a5a1bf05b2c59f3c969c8d2d6b373b3dca0398a988af30676952fcf1a968ac530b30dbe32922efe8c27acb9025adcaf1a5180b90134f90131a0b2151043be015f98b1b249180bfac505781022ede708f533f373b2d612837df7a0031e6ffe32d313f0cd57b4bebbf6fcacf83c366157846040108d198129d99a5aa0bfca4f79ac9eb24bcbdbd94fc49c0ca30a6399a2071e4ab3024e1aae0159a31180808080a0f1a2c911436f5bf1aa936e140b17399f7c092ad64a8ab839057a67fc6923a318a0e648ced926c977b0dcc17452361ac43e53f839b8e485a288e93fb667573ae088a0808107d197eb28741f8cec92b6fa76957fa6928b00f4b7301d464809519258098080a02c7ac441b072bbe33030110dccfdda0de6705c4bdb2c94594e10c2fb8687c41080a0162e8104a86bd043ca2fac0c5d56181127c7b24f6c10fefb90c27064b4edeff8a0376bcbdd3b7503a144b9016159b7e2cd074c9566b843cb834123057c61adbd2e80b870f86e9e31907a67cf7ece54c42262997b2f19041a4d99466b94b8c12f225827e239b84df84b80872386f26fc10000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470b873f871a0a75a6fa397f39292a3bb4fdb84463908c473bad9a0206bd00964adabd7a4b589808080808080808080808080a0ea5b9774dfc3fd50b359b86fa49a57fce0186593cf89d865e279413b63947bed80a0a0747bb1023533b4f9cdaa7c845609975d413348fc5f185a120037dccdf3584c80b870f86e9e2026422787b6d40c0c0c2df85757c5ad4a3e367831e932fa24f34da43d57b84df84b80872386f26fc10000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' export const _zeroElementProofRoot = hexToBytes( - '0xe794e45a596856bcd5412788f46752a559a4aa89fe556ab26a8c2cf0fc24cb5e' + '0xe794e45a596856bcd5412788f46752a559a4aa89fe556ab26a8c2cf0fc24cb5e', ) export const _zeroElementProofOrigin = bytesToBigInt( - hexToBytes('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa') + hexToBytes('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa'), ) export const _zeroElementProof = [ '0xf90211a07d363fdc4ad4413321005a1981d415a872aed14651c159bea575d713fb1d1fd8a0d51e3a39747ab080d602e8dff07ed7fdf18fd5dd480b85ec8d5ebd86475481fba0382fbb965c19798b116e1b32ad64d99bdf09f8f4ed4c83e1b388ffad0ee8bc62a02ff7448b0092b7926a01bbb4f72e6f38366fdf109f3e9f8ac0794af3dc0e3de4a05db544523b1c10f8aead4252bff05665b8c7d21f02a102b51ac79acb6b3d2854a0cb0c46c37d6b44be6ff2204c4f4cea393099fefeae88cf5aa88195da74cca13fa0b459b6b3672dab2bb058e561761a0838e349d1dd1292dda31245e8404ec844eaa082cbce67bd082cb430296662fb1f32aabe866dee947970877abaf4233eb0fb48a0828820316cc02bfefd899aba41340659fd06df1e0a0796287ec2a4110239f6d2a0be88e4724326382a8b56e2328eeef0ad51f18d5bae0e84296afe14c4028c4af9a0c14e9060c6b3784e35b9e6ae2ad2984142a75910ccc89eb89dc1e2f44b6c58c2a091467954490d127631d2a2f39a6edabd702153de817fe8da2ab9a30513e5c6dda01c00f6abbb9bcb3ae9b12c887bc3ea3b13dba33a5dbad455c24778fa7d3ab01ea0899f71abb18c6c956118bf567fac629b75f7e9526873e429d3d8abb6dbb58021a00fd717235298742623c0b3cafb3e4bd86c0b5ab1f71097b4dd19f3d6925d758da011e10e11fa54a847669b26adaf1b5cbe7736eafde6c552b9b6158fe12307e60680', @@ -38,7 +38,7 @@ describe('[AccountFetcher]', async () => { PeerPool.prototype.idle = td.func() PeerPool.prototype.ban = td.func() - const { AccountFetcher } = await import('../../../src/sync/fetcher/accountfetcher') + const { AccountFetcher } = await import('../../../src/sync/fetcher/accountfetcher.js') it('should start/stop', async () => { const config = new Config({ maxPerRequest: 5 }) @@ -89,7 +89,7 @@ describe('[AccountFetcher]', async () => { assert.deepEqual( fetcher.highestKnownHash, highestReceivedHash, - 'highest known hash correctly updated' + 'highest known hash correctly updated', ) }) @@ -204,7 +204,7 @@ describe('[AccountFetcher]', async () => { const result = (await fetcher.request(job as any)) as any assert.ok( JSON.stringify(result[0]) === JSON.stringify({ skipped: true }), - 'skipped fetching task with limit lower than highest known key hash' + 'skipped fetching task with limit lower than highest known key hash', ) }) @@ -280,7 +280,7 @@ describe('[AccountFetcher]', async () => { const ret = await fetcher.request(job as any) assert.ok( ret?.completed === true, - 'should handle peer that is signaling that an empty range has been requested with no elements remaining to the right' + 'should handle peer that is signaling that an empty range has been requested with no elements remaining to the right', ) }) @@ -319,7 +319,7 @@ describe('[AccountFetcher]', async () => { const ret = await fetcher.request(job as any) assert.ok( ret?.completed === undefined, - 'proof verification should fail if elements still remain to the right of the proof' + 'proof verification should fail if elements still remain to the right of the proof', ) }) @@ -333,10 +333,10 @@ describe('[AccountFetcher]', async () => { pool, root: hexToBytes('0x39ed8daab7679c0b1b7cf3667c50108185d4d9d1431c24a1c35f696a58277f8f'), first: bytesToBigInt( - hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001') + hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001'), ), count: bytesToBigInt( - hexToBytes('0x000010c6f7a0b5ed8d36b4c7f34938583621fafc8b0079a2834d26fa3fcc9ea9') + hexToBytes('0x000010c6f7a0b5ed8d36b4c7f34938583621fafc8b0079a2834d26fa3fcc9ea9'), ), }) assert.ok(fetcher.storageFetcher !== undefined, 'storageFetcher should be created') @@ -345,7 +345,7 @@ describe('[AccountFetcher]', async () => { const resData = RLP.decode(hexToBytes(_accountRangeRLP)) const { accounts, proof } = p.decode( p.messages.filter((message) => message.name === 'AccountRange')[0], - resData + resData, ) const mockedGetAccountRange = vi.fn(() => { return { @@ -365,7 +365,7 @@ describe('[AccountFetcher]', async () => { assert.ok(results !== undefined, 'Proof verification is completed without errors') assert.ok( fetcher.process(job as any, results!) !== undefined, - 'Response should be processed properly' + 'Response should be processed properly', ) // mock storageFetches's enqueue so to not having a hanging storage fetcher diff --git a/packages/client/test/sync/fetcher/blockfetcher.spec.ts b/packages/client/test/sync/fetcher/blockfetcher.spec.ts index f7c7e0f0b9..e21c0adeca 100644 --- a/packages/client/test/sync/fetcher/blockfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/blockfetcher.spec.ts @@ -71,7 +71,7 @@ describe('[BlockFetcher]', async () => { assert.equal( fetcher.first + fetcher.count - BigInt(1) === BigInt(15), true, - 'height should now be 15' + 'height should now be 15', ) // Clear fetcher queue for next test of gap when following head @@ -83,7 +83,7 @@ describe('[BlockFetcher]', async () => { assert.equal( (fetcher as any).in.length, 11, - '10 new tasks to catch up to head (1-49, 5 per request), 1 new task for subsequent block numbers (50-51)' + '10 new tasks to catch up to head (1-49, 5 per request), 1 new task for subsequent block numbers (50-51)', ) fetcher.destroy() @@ -104,7 +104,7 @@ describe('[BlockFetcher]', async () => { assert.deepEqual(fetcher.process({ task: { count: 2 } } as any, blocks), blocks, 'got results') assert.notOk( fetcher.process({ task: { count: 2 } } as any, { blocks: [] } as any), - 'bad results' + 'bad results', ) }) @@ -213,7 +213,7 @@ describe('[BlockFetcher]', async () => { const shanghaiHeader = BlockHeader.fromHeaderData( { number: 1, withdrawalsRoot: KECCAK256_RLP }, - { common: config.chainCommon, setHardfork: true } + { common: config.chainCommon, setHardfork: true }, ) const task = { count: 1, first: BigInt(1) } @@ -267,7 +267,7 @@ describe('store()', async () => { config.events.on(Event.SYNC_FETCHED_BLOCKS, () => it('should emit fetched blocks event', () => { assert.ok(true, 'store() emitted SYNC_FETCHED_BLOCKS event on putting blocks') - }) + }), ) await fetcher.store([]) }) diff --git a/packages/client/test/sync/fetcher/bytecodefetcher.spec.ts b/packages/client/test/sync/fetcher/bytecodefetcher.spec.ts index ba7e443e72..45cbba8132 100644 --- a/packages/client/test/sync/fetcher/bytecodefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/bytecodefetcher.spec.ts @@ -73,7 +73,7 @@ describe('[ByteCodeFetcher]', async () => { assert.deepEqual( (fetcher.process(job, ByteCodeResponse) as any)[0], fullResult[0], - 'got results' + 'got results', ) assert.notOk(fetcher.process({} as any, { ByteCodeResponse: [] } as any), 'bad results') }) diff --git a/packages/client/test/sync/fetcher/fetcher.spec.ts b/packages/client/test/sync/fetcher/fetcher.spec.ts index 8d22c2b351..868a669e4d 100644 --- a/packages/client/test/sync/fetcher/fetcher.spec.ts +++ b/packages/client/test/sync/fetcher/fetcher.spec.ts @@ -44,7 +44,7 @@ it('should handle failure', () => { ;(fetcher as any).running = true fetcher.next = td.func() config.events.on(Event.SYNC_FETCHER_ERROR, (err) => - assert.equal(err.message, 'err0', 'got error') + assert.equal(err.message, 'err0', 'got error'), ) ;(fetcher as any).failure(job as Job, new Error('err0')) assert.equal((fetcher as any).in.length, 1, 'enqueued job') @@ -131,7 +131,7 @@ describe('should re-enqueue on a non-fatal error', () => { ;(fetcher as any).running = true fetcher.store = td.func() td.when(fetcher.store(td.matchers.anything())).thenReject( - new Error('could not find parent header') + new Error('could not find parent header'), ) td.when(fetcher.processStoreError(td.matchers.anything(), td.matchers.anything())).thenReturn({ destroyFetcher: false, @@ -142,7 +142,7 @@ describe('should re-enqueue on a non-fatal error', () => { it('should step back', () => { assert.ok( (fetcher as any).in.peek().task.first === BigInt(1), - 'should step back for safeReorgDistance' + 'should step back for safeReorgDistance', ) }) }) diff --git a/packages/client/test/sync/fetcher/headerfetcher.spec.ts b/packages/client/test/sync/fetcher/headerfetcher.spec.ts index ed70d029a3..83eb52baca 100644 --- a/packages/client/test/sync/fetcher/headerfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/headerfetcher.spec.ts @@ -25,14 +25,14 @@ describe('[HeaderFetcher]', async () => { assert.deepEqual( fetcher.process( { task: { count: 2 }, peer: 'peer0' } as any, - { headers, bv: BigInt(1) } as any + { headers, bv: BigInt(1) } as any, ), headers as any, - 'got results' + 'got results', ) assert.notOk( fetcher.process({ task: { count: 2 } } as any, { headers: [], bv: BigInt(1) } as any), - 'bad results' + 'bad results', ) expect((fetcher as any).flow.handleReply).toHaveBeenCalledWith('peer0', 1) }) @@ -126,7 +126,7 @@ describe('store()', async () => { config.events.on(Event.SYNC_FETCHED_HEADERS, () => it('should emit event on put headers', () => { assert.ok(true, 'store() emitted SYNC_FETCHED_HEADERS event on putting headers') - }) + }), ) await fetcher.store([1 as any]) }) diff --git a/packages/client/test/sync/fetcher/reverseblockfetcher.spec.ts b/packages/client/test/sync/fetcher/reverseblockfetcher.spec.ts index ca63d3c87a..71fde3f121 100644 --- a/packages/client/test/sync/fetcher/reverseblockfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/reverseblockfetcher.spec.ts @@ -89,7 +89,7 @@ describe('[ReverseBlockFetcher]', async () => { assert.deepEqual(fetcher.process({ task: { count: 2 } } as any, blocks), blocks, 'got results') assert.notOk( fetcher.process({ task: { count: 2 } } as any, { blocks: [] } as any), - 'bad results' + 'bad results', ) }) @@ -197,31 +197,31 @@ describe('[ReverseBlockFetcher]', async () => { }) const block47 = createBlockFromBlockData( { header: { number: BigInt(47), difficulty: BigInt(1) } }, - { setHardfork: true } + { setHardfork: true }, ) const block48 = createBlockFromBlockData( { header: { number: BigInt(48), parentHash: block47.hash(), difficulty: BigInt(1) }, }, - { setHardfork: true } + { setHardfork: true }, ) const block49 = createBlockFromBlockData( { header: { number: BigInt(49), parentHash: block48.hash(), difficulty: BigInt(1) }, }, - { setHardfork: true } + { setHardfork: true }, ) const block4 = createBlockFromBlockData( { header: { number: BigInt(4), difficulty: BigInt(1) }, }, - { setHardfork: true } + { setHardfork: true }, ) const block5 = createBlockFromBlockData( { header: { number: BigInt(5), difficulty: BigInt(1), parentHash: block4.hash() }, }, - { setHardfork: true } + { setHardfork: true }, ) ;(skeleton as any).status.progress.subchains = [ { head: BigInt(100), tail: BigInt(50), next: block49.hash() }, @@ -232,12 +232,12 @@ describe('[ReverseBlockFetcher]', async () => { await fetcher.store([block49, block48]) assert.ok( (skeleton as any).status.progress.subchains.length === 1, - 'subchains should be merged' + 'subchains should be merged', ) assert.equal( (skeleton as any).status.progress.subchains[0].tail, BigInt(5), - 'subchain tail should be next segment' + 'subchain tail should be next segment', ) assert.notOk((fetcher as any).running, 'fetcher should stop') assert.equal((fetcher as any).in.length, 0, 'fetcher in should be cleared') @@ -269,7 +269,7 @@ describe('store()', async () => { assert.equal( err.message, `Blocks don't extend canonical subchain`, - 'store() threw on invalid block' + 'store() threw on invalid block', ) const { destroyFetcher, banPeer } = fetcher.processStoreError(err, { first: BigInt(10), @@ -283,7 +283,7 @@ describe('store()', async () => { config.events.on(Event.SYNC_FETCHED_BLOCKS, () => it('should emit event on put blocks', async () => { assert.ok(true, 'store() emitted SYNC_FETCHED_BLOCKS event on putting blocks') - }) + }), ) await fetcher.store([]) }) diff --git a/packages/client/test/sync/fetcher/storagefetcher.spec.ts b/packages/client/test/sync/fetcher/storagefetcher.spec.ts index ef4a920095..a1cb73eac4 100644 --- a/packages/client/test/sync/fetcher/storagefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/storagefetcher.spec.ts @@ -45,10 +45,10 @@ describe('[StorageFetcher]', async () => { storageRequests: [ { accountHash: hexToBytes( - '0x352a47fc6863b89a6b51890ef3c1550d560886c027141d2058ba1e2d4c66d99a' + '0x352a47fc6863b89a6b51890ef3c1550d560886c027141d2058ba1e2d4c66d99a', ), storageRoot: hexToBytes( - '0x556a482068355939c95a3412bdb21213a301483edb1b64402fb66ac9f3583599' + '0x556a482068355939c95a3412bdb21213a301483edb1b64402fb66ac9f3583599', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -62,10 +62,10 @@ describe('[StorageFetcher]', async () => { fetcher.enqueueByStorageRequestList([ { accountHash: hexToBytes( - '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1' + '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1', ), storageRoot: hexToBytes( - '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92' + '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -111,10 +111,10 @@ describe('[StorageFetcher]', async () => { storageRequests: [ { accountHash: hexToBytes( - '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1' + '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1', ), storageRoot: hexToBytes( - '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92' + '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -127,7 +127,7 @@ describe('[StorageFetcher]', async () => { assert.deepEqual( (fetcher.process(job, StorageDataResponse) as any)[0], fullResult[0], - 'got results' + 'got results', ) assert.throws(() => fetcher.process({} as any, { StorageDataResponse: [] } as any)) }) @@ -161,7 +161,7 @@ describe('[StorageFetcher]', async () => { { accountHash: hexToBytes(accountHashString), storageRoot: hexToBytes( - '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92' + '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92', ), first: BigInt(10), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -177,14 +177,14 @@ describe('[StorageFetcher]', async () => { assert.equal( JSON.stringify(fetcher.accountToHighestKnownHash.get(accountHashString)), JSON.stringify(utf8ToBytes(highestReceivedhash)), - 'should set new highest known hash' + 'should set new highest known hash', ) ;(job.task.storageRequests[0] as any).first = BigInt(3) ;(job.task.storageRequests[0] as any).count = BigInt(4) const result = (await fetcher.request(job as any)) as any assert.ok( JSON.stringify(result[0]) === JSON.stringify({ skipped: true }), - 'should skip fetching task with limit lower than highest known key hash' + 'should skip fetching task with limit lower than highest known key hash', ) StorageDataResponse.completed = true @@ -192,7 +192,7 @@ describe('[StorageFetcher]', async () => { assert.equal( fetcher.accountToHighestKnownHash.get(accountHashString), undefined, - 'should delete highest known hash for completed job' + 'should delete highest known hash for completed job', ) }) @@ -215,10 +215,10 @@ describe('[StorageFetcher]', async () => { storageRequests: [ { accountHash: hexToBytes( - '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1' + '0xe9a5016cb1a53dbc750d06e725514ac164231d71853cafdcbff42f5adb6ca6f1', ), storageRoot: hexToBytes( - '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92' + '0x69522138e4770e642ec8d7bd5e2b71a23fb732bb447cd4faf838b45cfe3b2a92', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -265,10 +265,10 @@ describe('[StorageFetcher]', async () => { storageRequests: [ { accountHash: hexToBytes( - '0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276' + '0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276', ), storageRoot: hexToBytes( - '0x4431bd7d69241190bb930b74485c1e31ff75552f67d758d0b6612e7bd9226121' + '0x4431bd7d69241190bb930b74485c1e31ff75552f67d758d0b6612e7bd9226121', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -278,7 +278,7 @@ describe('[StorageFetcher]', async () => { const resData = RLP.decode(hexToBytes(_storageRangesRLP)) as unknown const res = p.decode( p.messages.filter((message) => message.name === 'StorageRanges')[0], - resData + resData, ) const { reqId, slots, proof } = res const mockedGetStorageRanges = vi.fn((input) => { @@ -353,7 +353,7 @@ describe('[StorageFetcher]', async () => { const ret = await fetcher.request(job as any) assert.ok( ret?.completed === true, - 'should handle peer that is signaling that an empty range has been requested with no elements remaining to the right' + 'should handle peer that is signaling that an empty range has been requested with no elements remaining to the right', ) }) @@ -397,7 +397,7 @@ describe('[StorageFetcher]', async () => { const ret = await fetcher.request(job as any) assert.ok( ret?.completed === undefined, - 'proof verification should fail if elements still remain to the right of the proof' + 'proof verification should fail if elements still remain to the right of the proof', ) }) @@ -422,10 +422,10 @@ describe('[StorageFetcher]', async () => { storageRequests: [ { accountHash: hexToBytes( - '0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276' + '0x00009e5969eba9656d7e4dad5b0596241deb87c29bbab71c23b602c2b88a7276', ), storageRoot: hexToBytes( - '0x4431bd7d69241190bb930b74485c1e31ff75552f67d758d0b6612e7bd9226121' + '0x4431bd7d69241190bb930b74485c1e31ff75552f67d758d0b6612e7bd9226121', ), first: BigInt(0), count: BigInt(2) ** BigInt(256) - BigInt(1), @@ -435,7 +435,7 @@ describe('[StorageFetcher]', async () => { const resData = RLP.decode(hexToBytes(_storageRangesRLP)) as unknown const res = p.decode( p.messages.filter((message) => message.name === 'StorageRanges')[0], - resData + resData, ) const { reqId, slots, proof } = res const mockedGetStorageRanges = vi.fn().mockReturnValueOnce({ @@ -473,10 +473,10 @@ describe('[StorageFetcher]', async () => { const accResData = RLP.decode(hexToBytes(_accountRangeRLP)) as unknown const { proof: proofInvalid } = p.decode( p.messages.filter((message) => message.name === 'AccountRange')[0], - accResData + accResData, ) const dummyStorageRoot = hexToBytes( - '0x39ed8daab7679c0b1b7cf3667c50108185d4d9d1431c24a1c35f696a58277f8f' + '0x39ed8daab7679c0b1b7cf3667c50108185d4d9d1431c24a1c35f696a58277f8f', ) const dummyOrigin = new Uint8Array(32) try { @@ -488,7 +488,7 @@ describe('[StorageFetcher]', async () => { } catch (e) { assert.ok( true, - `verifyRangeProof correctly failed on invalid proof, Error: ${(e as Error).message}` + `verifyRangeProof correctly failed on invalid proof, Error: ${(e as Error).message}`, ) } @@ -497,7 +497,7 @@ describe('[StorageFetcher]', async () => { await fetcher.store([Object.create(null)] as any) assert.ok( fetcher['destroyWhenDone'] === false, - 'should still be open to enqueue and process new requests' + 'should still be open to enqueue and process new requests', ) fetcher.setDestroyWhenDone() assert.ok(fetcher['destroyWhenDone'] === true, 'should mark to close on finished') diff --git a/packages/client/test/sync/fetcher/trienodefetcher.spec.ts b/packages/client/test/sync/fetcher/trienodefetcher.spec.ts index 3f54b44b5e..64303e1d69 100644 --- a/packages/client/test/sync/fetcher/trienodefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/trienodefetcher.spec.ts @@ -44,7 +44,7 @@ describe('[TrieNodeFetcher]', async () => { assert.equal( (fetcher as any).pathToNodeRequestData.length, 1, - 'one node request has been added' + 'one node request has been added', ) void fetcher.fetch() @@ -77,7 +77,7 @@ describe('[TrieNodeFetcher]', async () => { assert.deepEqual( (fetcher.process(job, NodeDataResponse) as any)[0], fullResult[0], - 'got results' + 'got results', ) assert.notOk(fetcher.process({} as any, { NodeDataResponse: [] } as any), 'bad results') }) @@ -135,7 +135,7 @@ describe('[TrieNodeFetcher]', async () => { fetcher.requestedNodeToPath = new Map() fetcher.requestedNodeToPath.set( '9100b295173da75cf0f160214e47b480abc2c9d2fe11330fe8befa69aac69656', - '' + '', ) const resData = RLP.decode(hexToBytes(_trieNodesRLP)) as unknown @@ -160,7 +160,7 @@ describe('[TrieNodeFetcher]', async () => { assert.equal( requestResult[0][0], res.nodes[0], - 'Request phase should cross-validate received nodes with requested nodes' + 'Request phase should cross-validate received nodes with requested nodes', ) await fetcher.store(requestResult) @@ -170,7 +170,7 @@ describe('[TrieNodeFetcher]', async () => { assert.equal( children.length, fetcher.pathToNodeRequestData.length, - 'Should generate requests for all child nodes' + 'Should generate requests for all child nodes', ) }) it('should not throw if undefined', async () => { diff --git a/packages/client/test/sync/fullsync.spec.ts b/packages/client/test/sync/fullsync.spec.ts index 5dd4c104cf..f6acbb3da3 100644 --- a/packages/client/test/sync/fullsync.spec.ts +++ b/packages/client/test/sync/fullsync.spec.ts @@ -135,7 +135,7 @@ describe('[FullSynchronizer]', async () => { txPool, execution, }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ les: { status: { headNum: BigInt(2) } }, latest: () => { @@ -247,7 +247,7 @@ describe('[FullSynchronizer]', async () => { chain.putBlocks = vi.fn((input) => { assert.ok( JSON.stringify(input) === JSON.stringify([newBlock]), - 'putBlocks is called as expected' + 'putBlocks is called as expected', ) }) as any // NewBlock message from Peer 3 diff --git a/packages/client/test/sync/lightsync.spec.ts b/packages/client/test/sync/lightsync.spec.ts index 67cfc6c4de..b75f4eaff6 100644 --- a/packages/client/test/sync/lightsync.spec.ts +++ b/packages/client/test/sync/lightsync.spec.ts @@ -75,7 +75,7 @@ describe('[LightSynchronizer]', async () => { pool, chain, }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ les: { status: { headNum: BigInt(2) } }, latest: () => { @@ -118,7 +118,7 @@ describe('sync errors', async () => { pool, chain, }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ les: { status: { headNum: BigInt(2) } }, latest: () => { @@ -130,7 +130,7 @@ describe('sync errors', async () => { } as any) td.when(HeaderFetcher.prototype.fetch()).thenResolve(true) td.when(HeaderFetcher.prototype.fetch()).thenDo(() => - config.events.emit(Event.SYNC_FETCHED_HEADERS, [] as BlockHeader[]) + config.events.emit(Event.SYNC_FETCHED_HEADERS, [] as BlockHeader[]), ) config.logger.on('data', async (data) => { if ((data.message as string).includes('No headers fetched are applicable for import')) { @@ -168,7 +168,7 @@ describe('import headers', () => { pool, chain, }) - sync.best = td.func() + sync.best = td.func<(typeof sync)['best']>() td.when(sync.best()).thenResolve({ les: { status: { headNum: BigInt(2) } }, latest: () => { @@ -180,7 +180,7 @@ describe('import headers', () => { } as any) td.when(HeaderFetcher.prototype.fetch()).thenResolve(true) td.when(HeaderFetcher.prototype.fetch()).thenDo(() => - config.events.emit(Event.SYNC_FETCHED_HEADERS, [BlockHeader.fromHeaderData({})]) + config.events.emit(Event.SYNC_FETCHED_HEADERS, [BlockHeader.fromHeaderData({})]), ) config.logger.on('data', async (data) => { if ((data.message as string).includes('Imported headers count=1')) { diff --git a/packages/client/test/sync/skeleton.spec.ts b/packages/client/test/sync/skeleton.spec.ts index 8220a98316..3903edbbbe 100644 --- a/packages/client/test/sync/skeleton.spec.ts +++ b/packages/client/test/sync/skeleton.spec.ts @@ -22,19 +22,19 @@ const common = new Common({ chain: 1 }) const block49 = createBlockFromBlockData({ header: { number: 49 } }, { common }) const block49B = createBlockFromBlockData( { header: { number: 49, extraData: utf8ToBytes('B') } }, - { common } + { common }, ) const block50 = createBlockFromBlockData( { header: { number: 50, parentHash: block49.hash() } }, - { common } + { common }, ) const block50B = createBlockFromBlockData( { header: { number: 50, parentHash: block49.hash(), gasLimit: 999 } }, - { common } + { common }, ) const block51 = createBlockFromBlockData( { header: { number: 51, parentHash: block50.hash() } }, - { common } + { common }, ) describe('[Skeleton]/ startup scenarios ', () => { @@ -252,17 +252,17 @@ describe('[Skeleton] / initSync', async () => { const { progress } = skeleton['status'] if (progress.subchains.length !== testCase.newState.length) { assert.fail( - `test ${testCaseIndex}: subchain count mismatch: have ${progress.subchains.length}, want ${testCase.newState.length}` + `test ${testCaseIndex}: subchain count mismatch: have ${progress.subchains.length}, want ${testCase.newState.length}`, ) } for (const [i, subchain] of progress.subchains.entries()) { if (subchain.head !== testCase.newState[i].head) { assert.fail( - `test ${testCaseIndex}: subchain head mismatch: have ${subchain.head}, want ${testCase.newState[i].head}` + `test ${testCaseIndex}: subchain head mismatch: have ${subchain.head}, want ${testCase.newState[i].head}`, ) } else if (subchain.tail !== testCase.newState[i].tail) { assert.fail( - `test ${testCaseIndex}: subchain tail mismatch: have ${subchain.tail}, want ${testCase.newState[i].tail}` + `test ${testCaseIndex}: subchain tail mismatch: have ${subchain.tail}, want ${testCase.newState[i].tail}`, ) } else { assert.ok(true, `test ${testCaseIndex}: subchain[${i}] matched`) @@ -376,7 +376,7 @@ describe('[Skeleton] / setHead', async () => { assert.ok(true, `test ${testCaseIndex}: passed with correct error`) } else { assert.fail( - `test ${testCaseIndex}: received wrong error expected=${testCase.err?.message} actual=${error.message}` + `test ${testCaseIndex}: received wrong error expected=${testCase.err?.message} actual=${error.message}`, ) } } @@ -384,17 +384,17 @@ describe('[Skeleton] / setHead', async () => { const { progress } = skeleton['status'] if (progress.subchains.length !== testCase.newState.length) { assert.fail( - `test ${testCaseIndex}: subchain count mismatch: have ${progress.subchains.length}, want ${testCase.newState.length}` + `test ${testCaseIndex}: subchain count mismatch: have ${progress.subchains.length}, want ${testCase.newState.length}`, ) } for (const [i, subchain] of progress.subchains.entries()) { if (subchain.head !== testCase.newState[i].head) { assert.fail( - `test ${testCaseIndex}: subchain head mismatch: have ${subchain.head}, want ${testCase.newState[i].head}` + `test ${testCaseIndex}: subchain head mismatch: have ${subchain.head}, want ${testCase.newState[i].head}`, ) } else if (subchain.tail !== testCase.newState[i].tail) { assert.fail( - `test ${testCaseIndex}: subchain tail mismatch: have ${subchain.tail}, want ${testCase.newState[i].tail}` + `test ${testCaseIndex}: subchain tail mismatch: have ${subchain.tail}, want ${testCase.newState[i].tail}`, ) } else { assert.ok(true, `test ${testCaseIndex}: subchain[${i}] matched`) @@ -437,15 +437,15 @@ describe('[Skeleton] / setHead', async () => { const genesis = await chain.getBlock(BigInt(0)) const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesis.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block3 = createBlockFromBlockData( { header: { number: 3, difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) await skeleton.open() @@ -463,12 +463,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains.length, 1, - 'trivial subchain0 should have been created' + 'trivial subchain0 should have been created', ) assert.equal( skeleton['status'].progress.subchains[0]!.head, BigInt(0), - 'trivial subchain0 should have been created' + 'trivial subchain0 should have been created', ) try { @@ -484,12 +484,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains.length, 1, - 'trivial subchain should have been created' + 'trivial subchain should have been created', ) assert.equal( skeleton['status'].progress.subchains[0]!.head, BigInt(0), - 'trivial subchain0 should have been created' + 'trivial subchain0 should have been created', ) reorg = await skeleton.setHead(block1, true) @@ -497,12 +497,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains.length, 1, - 'subchain should have been created' + 'subchain should have been created', ) assert.equal( skeleton['status'].progress.subchains[0].head, BigInt(1), - 'head should be set to first block' + 'head should be set to first block', ) assert.equal(skeleton.isLinked(), true, 'subchain status should be linked') @@ -512,7 +512,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0].head, BigInt(2), - 'head should be set to first block' + 'head should be set to first block', ) assert.equal(skeleton.isLinked(), true, 'subchain status should stay linked') @@ -523,7 +523,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0].head, BigInt(2), - 'head should be set to second block' + 'head should be set to second block', ) assert.equal(skeleton.isLinked(), true, 'subchain status should stay linked') @@ -534,7 +534,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0].head, BigInt(3), - 'head should be set to third block' + 'head should be set to third block', ) assert.equal(skeleton.isLinked(), false, 'subchain status should not be linked anymore') }) @@ -549,23 +549,23 @@ describe('[Skeleton] / setHead', async () => { const genesis = await chain.getBlock(BigInt(0)) const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesis.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block3 = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block4 = createBlockFromBlockData( { header: { number: 4, parentHash: block3.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block5 = createBlockFromBlockData( { header: { number: 5, parentHash: block4.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) await skeleton.open() @@ -578,14 +578,14 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(4), - 'canonical height should update after being linked' + 'canonical height should update after being linked', ) await skeleton.setHead(block5, false) await wait(200) assert.equal( chain.blocks.height, BigInt(4), - 'canonical height should not change when setHead is set with force=false' + 'canonical height should not change when setHead is set with force=false', ) await skeleton.setHead(block5, true) await skeleton.blockingFillWithCutoff(10) @@ -594,7 +594,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(5), - 'canonical height should change when setHead is set with force=true' + 'canonical height should change when setHead is set with force=true', ) // unlink the skeleton for the below check to check all blocks cleared @@ -603,14 +603,14 @@ describe('[Skeleton] / setHead', async () => { assert.equal( (await skeleton.getBlock(block.header.number, true))?.hash(), undefined, - `skeleton block number=${block.header.number} should be cleaned up after filling canonical chain` + `skeleton block number=${block.header.number} should be cleaned up after filling canonical chain`, ) assert.equal( (await skeleton.getBlockByHash(block.hash(), true))?.hash(), undefined, `skeleton block hash=${short( - block.hash() - )} should be cleaned up after filling canonical chain` + block.hash(), + )} should be cleaned up after filling canonical chain`, ) } }) @@ -628,23 +628,23 @@ describe('[Skeleton] / setHead', async () => { const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesis.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block3 = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block4 = createBlockFromBlockData( { header: { number: 4, parentHash: block3.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block5 = createBlockFromBlockData( { header: { number: 5, parentHash: block4.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) await chain.putBlocks([block1, block2]) @@ -655,14 +655,14 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(4), - 'canonical height should update after being linked' + 'canonical height should update after being linked', ) await skeleton.setHead(block5, false) await wait(200) assert.equal( chain.blocks.height, BigInt(4), - 'canonical height should not change when setHead with force=false' + 'canonical height should not change when setHead with force=false', ) // test sethead and blockingFillWithCutoff true via forkchoice update @@ -672,7 +672,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(5), - 'canonical height should change when setHead with force=true' + 'canonical height should change when setHead with force=true', ) // unlink the skeleton for the below check to check all blocks cleared @@ -682,14 +682,14 @@ describe('[Skeleton] / setHead', async () => { assert.equal( (await skeleton.getBlock(block.header.number, true))?.hash(), undefined, - `skeleton block number=${block.header.number} should be cleaned up after filling canonical chain` + `skeleton block number=${block.header.number} should be cleaned up after filling canonical chain`, ) assert.equal( (await skeleton.getBlockByHash(block.hash(), true))?.hash(), undefined, `skeleton block hash=${short( - block.hash() - )} should be cleaned up after filling canonical chain` + block.hash(), + )} should be cleaned up after filling canonical chain`, ) } // restore linkedStatus @@ -697,15 +697,15 @@ describe('[Skeleton] / setHead', async () => { const block41 = createBlockFromBlockData( { header: { number: 4, parentHash: block3.hash(), difficulty: 101 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block51 = createBlockFromBlockData( { header: { number: 5, parentHash: block41.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block61 = createBlockFromBlockData( { header: { number: 6, parentHash: block51.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) await skeleton.setHead(block41, false) @@ -716,27 +716,27 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0]?.head, BigInt(6), - 'head should be correct' + 'head should be correct', ) assert.equal( skeleton['status'].progress.subchains[0]?.tail, BigInt(4), - 'tail should be backfilled' + 'tail should be backfilled', ) assert.equal(skeleton['status'].linked, true, 'should be linked') assert.equal(chain.blocks.height, BigInt(6), 'all blocks should be in chain') const block71 = createBlockFromBlockData( { header: { number: 7, parentHash: block61.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block81 = createBlockFromBlockData( { header: { number: 8, parentHash: block71.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block91 = createBlockFromBlockData( { header: { number: 9, parentHash: block81.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) // lets jump ahead and add the block 81 and 71 with annoucements and trigger tryTailBackfill @@ -745,12 +745,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0]?.head, BigInt(9), - 'head should be correct' + 'head should be correct', ) assert.equal( skeleton['status'].progress.subchains[0]?.tail, BigInt(9), - 'new subchain should be created' + 'new subchain should be created', ) await skeleton.setHead(block81, false) await skeleton.setHead(block71, false) @@ -759,12 +759,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( skeleton['status'].progress.subchains[0]?.head, BigInt(9), - 'head should be correct' + 'head should be correct', ) assert.equal( skeleton['status'].progress.subchains[0]?.tail, BigInt(7), - 'tail should be backfilled' + 'tail should be backfilled', ) assert.equal(skeleton['status'].linked, true, 'should be linked') // async wait needed here so the async fillCanonicalChain can fill the chain @@ -773,34 +773,34 @@ describe('[Skeleton] / setHead', async () => { assert.equal( equalsBytes(chain.blocks.latest!.hash(), block91.hash()), true, - 'correct head hash' + 'correct head hash', ) // do a very common reorg that happens in a network: reorged head block const block92 = createBlockFromBlockData( { header: { number: 9, parentHash: block81.hash(), difficulty: 101 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) const block102 = createBlockFromBlockData( { header: { number: 10, parentHash: block92.hash(), difficulty: 100 } }, - { common, setHardfork: true } + { common, setHardfork: true }, ) await skeleton.forkchoiceUpdate(block92) assert.equal( skeleton['status'].progress.subchains[0]?.head, BigInt(9), - 'head number should be same' + 'head number should be same', ) assert.equal( skeleton['status'].progress.subchains[0]?.tail, BigInt(9), - 'tail should be truncated to head' + 'tail should be truncated to head', ) assert.equal( equalsBytes(chain.blocks.latest!.hash(), block92.hash()), true, - 'correct reorged head hash' + 'correct reorged head hash', ) // should be able to build on top of the next block @@ -808,7 +808,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( equalsBytes(chain.blocks.latest!.hash(), block102.hash()), true, - 'continue reorged chain' + 'continue reorged chain', ) }) @@ -838,31 +838,31 @@ describe('[Skeleton] / setHead', async () => { const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesisBlock.hash(), difficulty: 100 } }, - { common } + { common }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common } + { common }, ) const block3PoW = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 100 } }, - { common } + { common }, ) const block3PoS = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 0 } }, - { common, setHardfork: BigInt(200) } + { common, setHardfork: BigInt(200) }, ) const block4InvalidPoS = createBlockFromBlockData( { header: { number: 4, parentHash: block3PoW.hash(), difficulty: 0 } }, - { common, setHardfork: BigInt(200) } + { common, setHardfork: BigInt(200) }, ) const block4PoS = createBlockFromBlockData( { header: { number: 4, parentHash: block3PoS.hash(), difficulty: 0 } }, - { common, setHardfork: BigInt(200) } + { common, setHardfork: BigInt(200) }, ) const block5 = createBlockFromBlockData( { header: { number: 5, parentHash: block4PoS.hash(), difficulty: 0 } }, - { common, setHardfork: BigInt(200) } + { common, setHardfork: BigInt(200) }, ) const skeleton = new Skeleton({ chain, config, metaDB: new MemoryLevel() }) @@ -876,7 +876,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(2), - 'canonical height should stop at block 2 (valid terminal block), since block 3 is invalid (past ttd)' + 'canonical height should stop at block 2 (valid terminal block), since block 3 is invalid (past ttd)', ) try { await skeleton.setHead(block5, false) @@ -889,7 +889,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(2), - 'canonical height should not change when setHead is set with force=false' + 'canonical height should not change when setHead is set with force=false', ) // Put correct chain await skeleton.initSync(block4PoS) @@ -904,12 +904,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(4), - 'canonical height should now be at head with correct chain' + 'canonical height should now be at head with correct chain', ) const latestHash = chain.headers.latest?.hash() assert.ok( latestHash !== undefined && equalsBytes(latestHash, block4PoS.hash()), - 'canonical height should now be at head with correct chain' + 'canonical height should now be at head with correct chain', ) await skeleton.setHead(block5, true) await wait(200) @@ -943,19 +943,19 @@ describe('[Skeleton] / setHead', async () => { const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesisBlock.hash(), difficulty: 100 } }, - { common } + { common }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common } + { common }, ) const block3PoW = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 100 } }, - { common } + { common }, ) const block4InvalidPoS = createBlockFromBlockData( { header: { number: 4, parentHash: block3PoW.hash(), difficulty: 0 } }, - { common, setHardfork: 200 } + { common, setHardfork: 200 }, ) const skeleton = new Skeleton({ chain, config, metaDB: new MemoryLevel() }) @@ -969,12 +969,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(2), - 'canonical height should stop at block 2 (valid terminal block), since block 3 is invalid (past ttd)' + 'canonical height should stop at block 2 (valid terminal block), since block 3 is invalid (past ttd)', ) assert.equal( skeleton['status'].progress.subchains[0].tail, BigInt(1), - `Subchain should have been backstepped to 1` + `Subchain should have been backstepped to 1`, ) }) @@ -1005,7 +1005,7 @@ describe('[Skeleton] / setHead', async () => { throw Error( `Invalid header difficulty=${ block.header.difficulty - } for consensus=${block.header.common.consensusType()}` + } for consensus=${block.header.common.consensusType()}`, ) } } @@ -1018,19 +1018,19 @@ describe('[Skeleton] / setHead', async () => { const block1 = createBlockFromBlockData( { header: { number: 1, parentHash: genesisBlock.hash(), difficulty: 100 } }, - { common } + { common }, ) const block2 = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 100 } }, - { common } + { common }, ) const block2PoS = createBlockFromBlockData( { header: { number: 2, parentHash: block1.hash(), difficulty: 0 } }, - { common } + { common }, ) const block3 = createBlockFromBlockData( { header: { number: 3, parentHash: block2.hash(), difficulty: 0 } }, - { common } + { common }, ) const skeleton = new Skeleton({ chain, config, metaDB: new MemoryLevel() }) @@ -1043,7 +1043,7 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(1), - 'canonical height should stop at block 1 (valid PoW block), since block 2 is invalid (invalid PoS, not past ttd)' + 'canonical height should stop at block 1 (valid PoW block), since block 2 is invalid (invalid PoS, not past ttd)', ) // Put correct chain await skeleton.initSync(block3) @@ -1058,12 +1058,12 @@ describe('[Skeleton] / setHead', async () => { assert.equal( chain.blocks.height, BigInt(3), - 'canonical height should now be at head with correct chain' + 'canonical height should now be at head with correct chain', ) const latestHash = chain.headers.latest?.hash() assert.ok( latestHash !== undefined && equalsBytes(latestHash, block3.hash()), - 'canonical height should now be at head with correct chain' + 'canonical height should now be at head with correct chain', ) BlockHeader.prototype['_consensusFormatValidation'] = originalValidate diff --git a/packages/client/test/sync/txpool.spec.ts b/packages/client/test/sync/txpool.spec.ts index 21240417e9..a8cabaa964 100644 --- a/packages/client/test/sync/txpool.spec.ts +++ b/packages/client/test/sync/txpool.spec.ts @@ -107,7 +107,7 @@ const handleTxs = async ( txs: any[], failMessage: string, stateManager?: DefaultStateManager, - pool?: TxPool + pool?: TxPool, ) => { if (pool === undefined) { pool = setup().pool @@ -134,7 +134,7 @@ const handleTxs = async ( await pool.handleAnnouncedTxHashes( validTxs.map((e) => e.hash()), peer, - peerPool + peerPool, ) await pool.add(txs[txs.length - 1]) @@ -262,13 +262,13 @@ describe('[TxPool]', async () => { assert.equal( (pool as any).knownByPeer.size, 2, - 'known tx hashes size 2 (entries for both peers)' + 'known tx hashes size 2 (entries for both peers)', ) assert.equal((pool as any).knownByPeer.get(peer.id).length, 1, 'one tx added for peer 1') assert.equal( (pool as any).knownByPeer.get(peer.id)[0].hash, bytesToUnprefixedHex(txA01.hash()), - 'new known tx hashes entry for announcing peer' + 'new known tx hashes entry for announcing peer', ) const txs = pool.getByHash([txA01.hash()]) @@ -276,7 +276,7 @@ describe('[TxPool]', async () => { assert.equal( bytesToHex(txs[0].serialize()), bytesToHex(txA01.serialize()), - 'should get correct tx by hash' + 'should get correct tx by hash', ) // check if transaction added in metrics @@ -294,7 +294,7 @@ describe('[TxPool]', async () => { assert.equal( feeMarketEip1559TransactionCountInPool, pool.pool.size, - 'pool should contain single eip 1559 transaction' + 'pool should contain single eip 1559 transaction', ) pool.pool.clear() @@ -303,12 +303,12 @@ describe('[TxPool]', async () => { assert.equal( (pool as any).knownByPeer.get(peer.id).length, 1, - 'should add tx only once to known tx hashes' + 'should add tx only once to known tx hashes', ) assert.equal( (pool as any).knownByPeer.size, 2, - 'known tx hashes size 2 (entries for both peers)' + 'known tx hashes size 2 (entries for both peers)', ) pool.stop() @@ -329,7 +329,7 @@ describe('[TxPool]', async () => { assert.equal( res['hashes'].length, TX_RETRIEVAL_LIMIT, - 'should limit to TX_RETRIEVAL_LIMIT' + 'should limit to TX_RETRIEVAL_LIMIT', ) return [null, []] }, @@ -431,7 +431,7 @@ describe('[TxPool]', async () => { } catch (e: any) { assert.ok( e.message.includes('replacement gas too low'), - 'successfully failed adding underpriced txn' + 'successfully failed adding underpriced txn', ) const poolObject = pool['handled'].get(bytesToUnprefixedHex(txA02_Underpriced.hash())) assert.equal(poolObject?.error, e, 'should have an errored poolObject') @@ -444,7 +444,7 @@ describe('[TxPool]', async () => { assert.equal( (pool as any).knownByPeer.get(peer2.id)[0]?.error?.message, 'NewPooledTransactionHashes', - 'should have errored sendObject for NewPooledTransactionHashes broadcast' + 'should have errored sendObject for NewPooledTransactionHashes broadcast', ) const address = bytesToUnprefixedHex(A.address) const poolContent = pool.pool.get(address)! @@ -492,7 +492,7 @@ describe('[TxPool]', async () => { for (let account = 0; account < 51; account++) { const pkey = concatBytes( hexToBytes(`0x${'aa'.repeat(31)}`), - hexToBytes(`0x${account.toString(16).padStart(2, '0')}`) + hexToBytes(`0x${account.toString(16).padStart(2, '0')}`), ) const from = { address: privateToAddress(pkey), @@ -523,7 +523,7 @@ describe('[TxPool]', async () => { assert.notOk( await handleTxs(txs, 'already have max amount of txs for this account'), - 'successfully rejected too many txs from same account' + 'successfully rejected too many txs from same account', ) }) @@ -534,12 +534,12 @@ describe('[TxPool]', async () => { create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, - }) + }), ) assert.notOk( await handleTxs(txs, 'Cannot call hash method if transaction is not signed'), - 'successfully rejected unsigned tx' + 'successfully rejected unsigned tx', ) }) @@ -551,14 +551,14 @@ describe('[TxPool]', async () => { maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, nonce: 0, - }).sign(A.privateKey) + }).sign(A.privateKey), ) assert.notOk( await handleTxs(txs, 'tx nonce too low', { getAccount: () => new Account(BigInt(1), BigInt('50000000000000000000')), } as any), - 'successfully rejected tx with invalid nonce' + 'successfully rejected tx with invalid nonce', ) }) @@ -574,15 +574,15 @@ describe('[TxPool]', async () => { nonce: 0, data: `0x${'00'.repeat(128 * 1024 + 1)}`, }, - { common } - ).sign(A.privateKey) + { common }, + ).sign(A.privateKey), ) assert.notOk( await handleTxs(txs, 'exceeds the max data size', { getAccount: () => new Account(BigInt(0), BigInt('50000000000000000000000')), } as any), - 'successfully rejected tx with too much data' + 'successfully rejected tx with too much data', ) }) @@ -595,14 +595,14 @@ describe('[TxPool]', async () => { maxPriorityFeePerGas: 1000000000, gasLimit: 21000, nonce: 0, - }).sign(A.privateKey) + }).sign(A.privateKey), ) assert.notOk( await handleTxs(txs, 'insufficient balance', { getAccount: () => new Account(BigInt(0), BigInt('0')), } as any), - 'successfully rejected account with too low balance' + 'successfully rejected account with too low balance', ) }) @@ -614,7 +614,7 @@ describe('[TxPool]', async () => { maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, nonce: 0, - }).sign(A.privateKey) + }).sign(A.privateKey), ) const { pool } = setup() @@ -625,7 +625,7 @@ describe('[TxPool]', async () => { assert.notOk( await handleTxs(txs, 'not within 50% range of current basefee', undefined, pool), - 'successfully rejected tx with too low gas price' + 'successfully rejected tx with too low gas price', ) }) @@ -638,7 +638,7 @@ describe('[TxPool]', async () => { maxPriorityFeePerGas: 1000000000, nonce: 0, gasLimit: 21000, - }).sign(A.privateKey) + }).sign(A.privateKey), ) const { pool } = setup() @@ -649,7 +649,7 @@ describe('[TxPool]', async () => { assert.notOk( await handleTxs(txs, 'exceeds last block gas limit', undefined, pool), - 'successfully rejected tx which has gas limit higher than block gas limit' + 'successfully rejected tx which has gas limit higher than block gas limit', ) }) @@ -660,7 +660,7 @@ describe('[TxPool]', async () => { create1559FeeMarketTx({ maxFeePerGas: 1000000000, maxPriorityFeePerGas: 1000000000, - }).sign(A.privateKey) + }).sign(A.privateKey), ) txs.push(txs[0]) @@ -669,7 +669,7 @@ describe('[TxPool]', async () => { assert.notOk( await handleTxs(txs, 'this transaction is already in the TxPool', undefined, pool), - 'successfully rejected tx which is already in pool' + 'successfully rejected tx which is already in pool', ) }) @@ -681,12 +681,12 @@ describe('[TxPool]', async () => { maxFeePerGas: 10000000, maxPriorityFeePerGas: 10000000, nonce: 0, - }).sign(A.privateKey) + }).sign(A.privateKey), ) assert.notOk( await handleTxs(txs, 'does not pay the minimum gas price of'), - 'successfully rejected tx with too low gas price' + 'successfully rejected tx with too low gas price', ) }) @@ -697,12 +697,12 @@ describe('[TxPool]', async () => { create2930AccessListTx({ gasPrice: 10000000, nonce: 0, - }).sign(A.privateKey) + }).sign(A.privateKey), ) assert.notOk( await handleTxs(txs, 'does not pay the minimum gas price of'), - 'successfully rejected tx with too low gas price' + 'successfully rejected tx with too low gas price', ) }) @@ -716,7 +716,7 @@ describe('[TxPool]', async () => { }, { freeze: false, - } + }, ).sign(A.privateKey) Object.defineProperty(tx, 'type', { get: () => 5 }) @@ -836,17 +836,17 @@ describe('[TxPool]', async () => { assert.equal( pool.pool.size, 2, - 'should not remove txs from pool (POOLED_STORAGE_TIME_LIMIT within range)' + 'should not remove txs from pool (POOLED_STORAGE_TIME_LIMIT within range)', ) assert.equal( (pool as any).knownByPeer.size, 1, - 'should not remove txs from known by peer map (POOLED_STORAGE_TIME_LIMIT within range)' + 'should not remove txs from known by peer map (POOLED_STORAGE_TIME_LIMIT within range)', ) assert.equal( (pool as any).handled.size, 2, - 'should not remove txs from handled (HANDLED_CLEANUP_TIME_LIMIT within range)' + 'should not remove txs from handled (HANDLED_CLEANUP_TIME_LIMIT within range)', ) const address = txB01.getSenderAddress().toString().slice(2) @@ -868,17 +868,17 @@ describe('[TxPool]', async () => { assert.equal( pool.pool.size, 1, - 'should remove txs from pool (POOLED_STORAGE_TIME_LIMIT before range)' + 'should remove txs from pool (POOLED_STORAGE_TIME_LIMIT before range)', ) assert.equal( (pool as any).knownByPeer.get(peer.id).length, 1, - 'should remove one tx from known by peer map (POOLED_STORAGE_TIME_LIMIT before range)' + 'should remove one tx from known by peer map (POOLED_STORAGE_TIME_LIMIT before range)', ) assert.equal( (pool as any).handled.size, 1, - 'should remove txs from handled (HANDLED_CLEANUP_TIME_LIMIT before range)' + 'should remove txs from handled (HANDLED_CLEANUP_TIME_LIMIT before range)', ) pool.stop() diff --git a/packages/client/test/util/parse.spec.ts b/packages/client/test/util/parse.spec.ts index 717b60a01b..5069c7dbc6 100644 --- a/packages/client/test/util/parse.spec.ts +++ b/packages/client/test/util/parse.spec.ts @@ -9,37 +9,37 @@ describe('[Util/Parse]', () => { assert.deepEqual( parseMultiaddrs('10.0.0.1:1234'), [multiaddr('/ip4/10.0.0.1/tcp/1234')], - 'parse ip:port' + 'parse ip:port', ) assert.deepEqual( parseMultiaddrs('enode://abc@10.0.0.1:1234'), [multiaddr('/ip4/10.0.0.1/tcp/1234')], - 'parse url' + 'parse url', ) assert.deepEqual( parseMultiaddrs('/ip4/1.1.1.1/tcp/50507/ws'), [multiaddr('/ip4/1.1.1.1/tcp/50507/ws')], - 'parse multiaddr' + 'parse multiaddr', ) assert.deepEqual( parseMultiaddrs( - '/ip4/1.1.1.2/tcp/50508/ws/p2p/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa' + '/ip4/1.1.1.2/tcp/50508/ws/p2p/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa', ), [multiaddr('/ip4/1.1.1.2/tcp/50508/ws/p2p/QmYAuYxw6QX1x5aafs6g3bUrPbMDifP5pDun3N9zbVLpEa')], - 'parse multiaddr with peer id' + 'parse multiaddr with peer id', ) assert.deepEqual( parseMultiaddrs( - '10.0.0.1:1234,enode://343149e4feefa15d882d9fe4ac7d88f885bd05ebb735e547f12e12080a9fa07c8014ca6fd7f373123488102fe5e34111f8509cf0b7de3f5b44339c9f25e87cb8@127.0.0.1:2345' + '10.0.0.1:1234,enode://343149e4feefa15d882d9fe4ac7d88f885bd05ebb735e547f12e12080a9fa07c8014ca6fd7f373123488102fe5e34111f8509cf0b7de3f5b44339c9f25e87cb8@127.0.0.1:2345', ), [multiaddr('/ip4/10.0.0.1/tcp/1234'), multiaddr('/ip4/127.0.0.1/tcp/2345')], - 'parse multiple' + 'parse multiple', ) assert.throws(() => parseMultiaddrs(10 as any), /not a function/, 'throws error') assert.deepEqual( parseMultiaddrs('[2607:f8b0:4003:c00::6a]:5678'), [multiaddr('/ip6/2607:f8b0:4003:c00::6a/tcp/5678')], - 'parse ipv6 multiaddr' + 'parse ipv6 multiaddr', ) }) }) diff --git a/packages/client/test/util/rpc.spec.ts b/packages/client/test/util/rpc.spec.ts index ac36366d7c..6dc89c6f5a 100644 --- a/packages/client/test/util/rpc.spec.ts +++ b/packages/client/test/util/rpc.spec.ts @@ -54,7 +54,7 @@ describe('[Util/RPC]', () => { assert.ok( httpServer !== undefined && wsServer !== undefined, - 'should return http and ws servers' + 'should return http and ws servers', ) } } @@ -81,7 +81,7 @@ describe('[Util/RPC]', () => { }) assert.ok( httpServer !== undefined && wsServer !== undefined, - 'should return http and ws servers' + 'should return http and ws servers', ) }) }) diff --git a/packages/client/test/util/wasmCrypto.spec.ts b/packages/client/test/util/wasmCrypto.spec.ts index 59b0502a2a..3ffb775eaa 100644 --- a/packages/client/test/util/wasmCrypto.spec.ts +++ b/packages/client/test/util/wasmCrypto.spec.ts @@ -29,14 +29,14 @@ describe('WASM crypto tests', () => { v: bigint, r: Uint8Array, s: Uint8Array, - chainID?: bigint + chainID?: bigint, ) => secp256k1Expand( secp256k1Recover( msgHash, concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32)), - Number(calculateSigRecovery(v, chainID)) - ) + Number(calculateSigRecovery(v, chainID)), + ), ).slice(1) await waitReady() @@ -90,7 +90,7 @@ describe('WASM crypto tests', () => { assert.deepEqual(wasmSig, jsSig, 'wasm signatures produce same result as js signatures') assert.throws( () => wasmSign(randomBytes(31), randomBytes(32)), - 'message length must be 32 bytes or greater' + 'message length must be 32 bytes or greater', ) }) it('should have the same signature and verification', async () => { diff --git a/packages/client/tsconfig.eslint.json b/packages/client/tsconfig.eslint.json deleted file mode 100644 index e2b5df7d39..0000000000 --- a/packages/client/tsconfig.eslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "include": ["webpack.config.js"] -} diff --git a/packages/client/tsconfig.lint.json b/packages/client/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/client/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/common/.eslintrc.cjs b/packages/common/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/common/.eslintrc.cjs +++ b/packages/common/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/common/examples/common.ts b/packages/common/examples/common.ts index 4e2ac82506..272f3005a0 100644 --- a/packages/common/examples/common.ts +++ b/packages/common/examples/common.ts @@ -1,4 +1,4 @@ -import { Chain, Common, createCustomCommon, Hardfork } from '@ethereumjs/common' +import { Chain, Common, Hardfork, createCustomCommon } from '@ethereumjs/common' // With enums: const commonWithEnums = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) diff --git a/packages/common/examples/customChain.ts b/packages/common/examples/customChain.ts index 44a89a547b..9344638359 100644 --- a/packages/common/examples/customChain.ts +++ b/packages/common/examples/customChain.ts @@ -1,4 +1,5 @@ import { Common } from '@ethereumjs/common' + import myCustomChain1 from './genesisData/testnet.json' // Add custom chain config diff --git a/packages/common/examples/customChains.ts b/packages/common/examples/customChains.ts index f051611dd8..4d492f2ab9 100644 --- a/packages/common/examples/customChains.ts +++ b/packages/common/examples/customChains.ts @@ -1,4 +1,5 @@ import { Common } from '@ethereumjs/common' + import myCustomChain1 from './genesisData/testnet.json' import myCustomChain2 from './genesisData/testnet2.json' // Add two custom chains, initial mainnet activation diff --git a/packages/common/examples/customCrypto.ts b/packages/common/examples/customCrypto.ts index 60668a71d2..3b1c601963 100644 --- a/packages/common/examples/customCrypto.ts +++ b/packages/common/examples/customCrypto.ts @@ -1,6 +1,6 @@ -import { keccak256, waitReady } from '@polkadot/wasm-crypto' +import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' -import { Block, createBlockFromBlockData } from '@ethereumjs/block' +import { keccak256, waitReady } from '@polkadot/wasm-crypto' const main = async () => { // @polkadot/wasm-crypto specific initialization @@ -14,4 +14,4 @@ const main = async () => { console.log(block.hash()) } -main() +void main() diff --git a/packages/common/examples/fromGeth.ts b/packages/common/examples/fromGeth.ts index 2164390404..af3828e4e4 100644 --- a/packages/common/examples/fromGeth.ts +++ b/packages/common/examples/fromGeth.ts @@ -1,4 +1,4 @@ -import { Common, createCommonFromGethGenesis } from '@ethereumjs/common' +import { createCommonFromGethGenesis } from '@ethereumjs/common' import { hexToBytes } from '@ethereumjs/util' import genesisJson from './genesisData/post-merge.json' diff --git a/packages/common/examples/initKzg.ts b/packages/common/examples/initKzg.ts index 4d6ecdcdf7..e3c72a889a 100644 --- a/packages/common/examples/initKzg.ts +++ b/packages/common/examples/initKzg.ts @@ -1,5 +1,5 @@ +import { Chain, Common, Hardfork } from '@ethereumjs/common' import { loadKZG } from 'kzg-wasm' -import { Common, Chain, Hardfork } from '@ethereumjs/common' const main = async () => { const kzg = await loadKZG() @@ -11,4 +11,4 @@ const main = async () => { console.log(common.customCrypto.kzg) // Should print the initialized KZG interface } -main() +void main() diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 2e4aadba31..1d25c0db9b 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -101,7 +101,7 @@ export class Common { } else if (typeof chain === 'object') { if (this._customChains.length > 0) { throw new Error( - 'Chain must be a string, number, or bigint when initialized with customChains passed in' + 'Chain must be a string, number, or bigint when initialized with customChains passed in', ) } const required = ['chainId', 'genesis', 'hardforks', 'bootstrapNodes'] @@ -163,7 +163,9 @@ export class Common { // Filter out hardforks with no block number, no ttd or no timestamp (i.e. unapplied hardforks) const hfs = this.hardforks().filter( (hf) => - hf.block !== null || (hf.ttd !== null && hf.ttd !== undefined) || hf.timestamp !== undefined + hf.block !== null || + (hf.ttd !== null && hf.ttd !== undefined) || + hf.timestamp !== undefined, ) const mergeIndex = hfs.findIndex((hf) => hf.ttd !== null && hf.ttd !== undefined) const doubleTTDHF = hfs @@ -180,7 +182,7 @@ export class Common { let hfIndex = hfs.findIndex( (hf) => (blockNumber !== undefined && hf.block !== null && BigInt(hf.block) > blockNumber) || - (timestamp !== undefined && hf.timestamp !== undefined && BigInt(hf.timestamp) > timestamp) + (timestamp !== undefined && hf.timestamp !== undefined && BigInt(hf.timestamp) > timestamp), ) if (hfIndex === -1) { @@ -239,7 +241,7 @@ export class Common { .slice(0, hfStartIndex) .reduce( (acc: number, hf: HardforkTransitionConfig) => Math.max(Number(hf.timestamp ?? '0'), acc), - 0 + 0, ) if (minTimeStamp > timestamp) { throw Error(`Maximum HF determined by timestamp is lower than the block number/ttd HF`) @@ -250,7 +252,7 @@ export class Common { .reduce( (acc: number, hf: HardforkTransitionConfig) => Math.min(Number(hf.timestamp ?? timestamp), acc), - Number(timestamp) + Number(timestamp), ) if (maxTimeStamp < timestamp) { throw Error(`Maximum HF determined by block number/ttd is lower than timestamp HF`) @@ -302,7 +304,7 @@ export class Common { const minHF = this.gteHardfork(eipsDict[eip]['minimumHardfork']) if (!minHF) { throw new Error( - `${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}` + `${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}`, ) } } @@ -464,7 +466,7 @@ export class Common { name: string, blockNumber: BigIntLike, td?: BigIntLike, - timestamp?: BigIntLike + timestamp?: BigIntLike, ): bigint { const hardfork = this.getHardforkBy({ blockNumber, td, timestamp }) return this.paramByHardfork(name, hardfork) diff --git a/packages/common/src/constructors.ts b/packages/common/src/constructors.ts index 5ee817a7b5..080d268bbc 100644 --- a/packages/common/src/constructors.ts +++ b/packages/common/src/constructors.ts @@ -28,7 +28,7 @@ import type { ChainConfig, CustomCommonOpts, GethConfigOpts } from './index.js' */ export function createCustomCommon( chainParamsOrName: Partial | CustomChain, - opts: CustomCommonOpts = {} + opts: CustomCommonOpts = {}, ): Common { const baseChain = opts.baseChain ?? 'mainnet' const standardChainParams = { ..._getChainParams(baseChain) } @@ -49,7 +49,7 @@ export function createCustomCommon( name: CustomChain.PolygonMainnet, chainId: 137, }, - opts + opts, ) } if (chainParamsOrName === CustomChain.PolygonMumbai) { @@ -58,7 +58,7 @@ export function createCustomCommon( name: CustomChain.PolygonMumbai, chainId: 80001, }, - opts + opts, ) } if (chainParamsOrName === CustomChain.ArbitrumOne) { @@ -67,7 +67,7 @@ export function createCustomCommon( name: CustomChain.ArbitrumOne, chainId: 42161, }, - opts + opts, ) } if (chainParamsOrName === CustomChain.xDaiChain) { @@ -76,7 +76,7 @@ export function createCustomCommon( name: CustomChain.xDaiChain, chainId: 100, }, - opts + opts, ) } @@ -86,7 +86,7 @@ export function createCustomCommon( name: CustomChain.OptimisticKovan, chainId: 69, }, - opts + opts, ) } @@ -97,7 +97,7 @@ export function createCustomCommon( chainId: 10, }, // Optimism has not implemented the London hardfork yet (targeting Q1.22) - { hardfork: Hardfork.Berlin, ...opts } + { hardfork: Hardfork.Berlin, ...opts }, ) } throw new Error(`Custom chain ${chainParamsOrName} not supported`) @@ -112,7 +112,7 @@ export function createCustomCommon( */ export function createCommonFromGethGenesis( genesisJson: any, - { chain, eips, genesisHash, hardfork, mergeForkIdPostMerge, customCrypto }: GethConfigOpts + { chain, eips, genesisHash, hardfork, mergeForkIdPostMerge, customCrypto }: GethConfigOpts, ): Common { const genesisParams = parseGethGenesis(genesisJson, chain, mergeForkIdPostMerge) const common = new Common({ diff --git a/packages/common/src/interfaces.ts b/packages/common/src/interfaces.ts index 9721b31945..113b5b47e9 100644 --- a/packages/common/src/interfaces.ts +++ b/packages/common/src/interfaces.ts @@ -84,7 +84,7 @@ export type AuthorizationListBytesItem = [ Uint8Array[], Uint8Array, Uint8Array, - Uint8Array + Uint8Array, ] export type AuthorizationListBytes = AuthorizationListBytesItem[] export type AuthorizationList = AuthorizationListItem[] @@ -120,24 +120,24 @@ export interface AccessWitnessInterface { touchAddressOnWriteAndComputeGas( address: Address, treeIndex: number | bigint, - subIndex: number | Uint8Array + subIndex: number | Uint8Array, ): bigint touchAddressOnReadAndComputeGas( address: Address, treeIndex: number | bigint, - subIndex: number | Uint8Array + subIndex: number | Uint8Array, ): bigint touchAddressAndChargeGas( address: Address, treeIndex: number | bigint, subIndex: number | Uint8Array, - { isWrite }: { isWrite?: boolean } + { isWrite }: { isWrite?: boolean }, ): bigint touchAddress( address: Address, treeIndex: number | bigint, subIndex: number | Uint8Array, - { isWrite }: { isWrite?: boolean } + { isWrite }: { isWrite?: boolean }, ): AccessEventFlags shallowCopy(): AccessWitnessInterface merge(accessWitness: AccessWitnessInterface): void diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index edd6eb1b7f..746400f364 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -78,7 +78,7 @@ export interface CustomCrypto { v: bigint, r: Uint8Array, s: Uint8Array, - chainId?: bigint + chainId?: bigint, ) => Uint8Array sha256?: (msg: Uint8Array) => Uint8Array ecsign?: (msg: Uint8Array, pk: Uint8Array, chainId?: bigint) => ECDSASignature diff --git a/packages/common/src/utils.ts b/packages/common/src/utils.ts index caa1274edf..0bc8ae3dac 100644 --- a/packages/common/src/utils.ts +++ b/packages/common/src/utils.ts @@ -81,7 +81,7 @@ function parseGethParams(json: any, mergeForkIdPostMerge: boolean = true) { // but have different configuration parameters in geth genesis parameters if (config.eip155Block !== config.eip158Block) { throw new Error( - 'EIP155 block number must equal EIP 158 block number since both are part of SpuriousDragon hardfork and the client only supports activating the full hardfork' + 'EIP155 block number must equal EIP 158 block number since both are part of SpuriousDragon hardfork and the client only supports activating the full hardfork', ) } @@ -143,12 +143,15 @@ function parseGethParams(json: any, mergeForkIdPostMerge: boolean = true) { } // forkMapRev is the map from config field name to Hardfork - const forkMapRev = Object.keys(forkMap).reduce((acc, elem) => { - acc[forkMap[elem].name] = elem - return acc - }, {} as { [key: string]: string }) + const forkMapRev = Object.keys(forkMap).reduce( + (acc, elem) => { + acc[forkMap[elem].name] = elem + return acc + }, + {} as { [key: string]: string }, + ) const configHardforkNames = Object.keys(config).filter( - (key) => forkMapRev[key] !== undefined && config[key] !== undefined && config[key] !== null + (key) => forkMapRev[key] !== undefined && config[key] !== undefined && config[key] !== null, ) params.hardforks = configHardforkNames @@ -196,7 +199,7 @@ function parseGethParams(json: any, mergeForkIdPostMerge: boolean = true) { // Merge hardfork has to be placed before first hardfork that is dependent on merge const postMergeIndex = params.hardforks.findIndex( - (hf: any) => forkMap[hf.name]?.postMerge === true + (hf: any) => forkMap[hf.name]?.postMerge === true, ) if (postMergeIndex !== -1) { params.hardforks.splice(postMergeIndex, 0, mergeConfig as unknown as ConfigHardfork) @@ -267,7 +270,7 @@ export function isSupportedChainId(chainId: bigint): boolean { export function _getChainParams( chain: string | number | Chain | bigint, - customChains?: ChainConfig[] + customChains?: ChainConfig[], ): ChainConfig { const initializedChains = getInitializedChains(customChains) if (typeof chain === 'number' || typeof chain === 'bigint') { diff --git a/packages/common/test/chains.spec.ts b/packages/common/test/chains.spec.ts index e0d25554b7..77e907421a 100644 --- a/packages/common/test/chains.spec.ts +++ b/packages/common/test/chains.spec.ts @@ -18,7 +18,7 @@ describe('[Common/Chains]: Initialization / Chain params', () => { assert.equal( c.hardfork(), c.DEFAULT_HARDFORK, - 'should set hardfork to hardfork set as DEFAULT_HARDFORK' + 'should set hardfork to hardfork set as DEFAULT_HARDFORK', ) c = new Common({ chain: 1 }) @@ -33,7 +33,7 @@ describe('[Common/Chains]: Initialization / Chain params', () => { assert.equal( c.hardfork(), c.DEFAULT_HARDFORK, - 'should set hardfork to hardfork set as DEFAULT_HARDFORK' + 'should set hardfork to hardfork set as DEFAULT_HARDFORK', ) }) @@ -68,12 +68,12 @@ describe('[Common/Chains]: Initialization / Chain params', () => { assert.equal( c.consensusType(), ConsensusType.ProofOfWork, - 'should return correct consensus type' + 'should return correct consensus type', ) assert.equal( c.consensusAlgorithm(), ConsensusAlgorithm.Ethash, - 'should return correct consensus algorithm' + 'should return correct consensus algorithm', ) assert.deepEqual(c.consensusConfig(), {}, 'should return empty dictionary for consensus config') @@ -83,17 +83,17 @@ describe('[Common/Chains]: Initialization / Chain params', () => { assert.equal( c.consensusType(), ConsensusType.ProofOfAuthority, - 'should return correct consensus type' + 'should return correct consensus type', ) assert.equal( c.consensusAlgorithm(), ConsensusAlgorithm.Clique, - 'should return correct consensus algorithm' + 'should return correct consensus algorithm', ) assert.equal( c.consensusConfig().epoch, 30000, - 'should return correct consensus config parameters' + 'should return correct consensus config parameters', ) }) @@ -108,12 +108,12 @@ describe('[Common/Chains]: Initialization / Chain params', () => { assert.equal( typeof bootnode.location, 'string', - 'returns the location as string (empty string if unavailable)' + 'returns the location as string (empty string if unavailable)', ) assert.equal( typeof bootnode.comment, 'string', - 'returns a comment as string (empty string if unavailable)' + 'returns a comment as string (empty string if unavailable)', ) } }) @@ -149,12 +149,12 @@ describe('[Common]: copy() listener tests', () => { assert.equal( common.events.listenerCount('hardforkChanged'), 2, - 'original common instance should have two listeners' + 'original common instance should have two listeners', ) assert.equal( commonCopy.events.listenerCount('hardforkChanged'), 0, - 'copied common instance should have zero listeners' + 'copied common instance should have zero listeners', ) }) }) diff --git a/packages/common/test/customChains.spec.ts b/packages/common/test/customChains.spec.ts index 14eb3a4688..288bd8d209 100644 --- a/packages/common/test/customChains.spec.ts +++ b/packages/common/test/customChains.spec.ts @@ -33,7 +33,7 @@ describe('[Common]: Custom chains', () => { }, /Missing required/, undefined, - 'should throw an exception on missing parameter' + 'should throw an exception on missing parameter', ) }) @@ -67,14 +67,14 @@ describe('[Common]: Custom chains', () => { assert.deepEqual( common.chainId(), BigInt(80001), - 'supported chain -> should initialize with correct chain ID' + 'supported chain -> should initialize with correct chain ID', ) for (const customChain of Object.values(CustomChain)) { common = createCustomCommon(customChain) assert.equal( common.chainName(), customChain, - `supported chain -> should initialize with enum name (${customChain})` + `supported chain -> should initialize with enum name (${customChain})`, ) } @@ -82,14 +82,14 @@ describe('[Common]: Custom chains', () => { assert.equal( common.hardfork(), common.DEFAULT_HARDFORK, - 'uses default hardfork when no options are present' + 'uses default hardfork when no options are present', ) common = createCustomCommon(CustomChain.OptimisticEthereum, { hardfork: Hardfork.Byzantium }) assert.equal( common.hardfork(), Hardfork.Byzantium, - 'should correctly set an option (default options present)' + 'should correctly set an option (default options present)', ) try { @@ -99,7 +99,7 @@ describe('[Common]: Custom chains', () => { } catch (e: any) { assert.ok( e.message.includes('not supported'), - 'supported chain -> should throw if chain name is not supported' + 'supported chain -> should throw if chain name is not supported', ) } }) @@ -111,9 +111,9 @@ describe('[Common]: Custom chains', () => { } catch (e: any) { assert.ok( e.message.includes( - 'Chain must be a string, number, or bigint when initialized with customChains passed in' + 'Chain must be a string, number, or bigint when initialized with customChains passed in', ), - 'should throw an exception on wrong initialization' + 'should throw an exception on wrong initialization', ) } }) @@ -149,7 +149,7 @@ describe('[Common]: Custom chains', () => { assert.equal( c.hardforkBlock()!, BigInt(10), - 'customChains, chain initialized with custom chain' + 'customChains, chain initialized with custom chain', ) const customChainParams: Partial = { @@ -163,14 +163,14 @@ describe('[Common]: Custom chains', () => { assert.equal( customChainCommon['_chainParams'].depositContractAddress, - customChainParams.depositContractAddress + customChainParams.depositContractAddress, ) c.setChain('testnet') assert.equal(c.chainName(), 'testnet', 'customChains, should allow to switch custom chain') assert.equal( c.consensusType(), ConsensusType.ProofOfWork, - 'customChains, should allow to switch custom chain' + 'customChains, should allow to switch custom chain', ) }) @@ -276,7 +276,7 @@ describe('custom chain setup with hardforks with undefined/null block numbers', () => createCustomCommon({ hardforks: undefinedHardforks as HardforkTransitionConfig[] }), undefined, undefined, - 'throws when a hardfork with an undefined block number is passed' + 'throws when a hardfork with an undefined block number is passed', ) const nullHardforks = [ diff --git a/packages/common/test/customCrypto.spec.ts b/packages/common/test/customCrypto.spec.ts index 7e5ae55f40..908198cc6f 100644 --- a/packages/common/test/customCrypto.spec.ts +++ b/packages/common/test/customCrypto.spec.ts @@ -14,7 +14,7 @@ describe('[Common]: Custom Crypto', () => { v: bigint, r: Uint8Array, s: Uint8Array, - _chainID?: bigint + _chainID?: bigint, ) => { return concatBytes(msgHash, Uint8Array.from([Number(v)]), r, s) } @@ -58,8 +58,8 @@ describe('[Common]: Custom Crypto', () => { Uint8Array.from([1]), BigInt(2), Uint8Array.from([3]), - Uint8Array.from([4]) - ) + Uint8Array.from([4]), + ), ) }) diff --git a/packages/common/test/hardforks.spec.ts b/packages/common/test/hardforks.spec.ts index 9375d3a2b2..d52e806aa4 100644 --- a/packages/common/test/hardforks.spec.ts +++ b/packages/common/test/hardforks.spec.ts @@ -260,7 +260,7 @@ describe('[Common]: Hardfork logic', () => { msg = 'should provide correct forkHash for HF provided' assert.equal(c.forkHash(Hardfork.SpuriousDragon), '0x3edd5b10', msg) const genesisHash = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) assert.equal(c.forkHash(Hardfork.SpuriousDragon, genesisHash), '0x3edd5b10', msg) @@ -357,34 +357,34 @@ describe('[Common]: Hardfork logic', () => { assert.equal( c.consensusType(), ConsensusType.ProofOfAuthority, - 'should provide the correct initial chain consensus type' + 'should provide the correct initial chain consensus type', ) assert.equal( c.consensusAlgorithm(), ConsensusAlgorithm.Clique, - 'should provide the correct initial chain consensus algorithm' + 'should provide the correct initial chain consensus algorithm', ) assert.equal( c.consensusConfig()['period'], 15, - 'should provide the correct initial chain consensus configuration' + 'should provide the correct initial chain consensus configuration', ) c = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Paris }) assert.equal( c.consensusType(), ConsensusType.ProofOfStake, - 'should provide the correct updated chain consensus type' + 'should provide the correct updated chain consensus type', ) assert.equal( c.consensusAlgorithm(), ConsensusAlgorithm.Casper, - 'should provide the correct updated chain consensus algorithm' + 'should provide the correct updated chain consensus algorithm', ) assert.deepEqual( c.consensusConfig(), {}, - 'should provide the correct updated chain consensus configuration' + 'should provide the correct updated chain consensus configuration', ) }) @@ -394,31 +394,31 @@ describe('[Common]: Hardfork logic', () => { assert.equal( c['HARDFORK_CHANGES'][11][0], Hardfork.Paris, - 'should correctly apply hardfork changes' + 'should correctly apply hardfork changes', ) assert.equal( c['HARDFORK_CHANGES'][12][0], Hardfork.MergeForkIdTransition, - 'should correctly apply hardfork changes' + 'should correctly apply hardfork changes', ) // Should give correct ConsensusType pre and post merge assert.equal( c.consensusType(), ConsensusType.ProofOfWork, - 'should provide the correct initial chain consensus type' + 'should provide the correct initial chain consensus type', ) c.setHardfork(Hardfork.Paris) assert.equal( c.consensusType(), ConsensusType.ProofOfStake, - `should switch to ProofOfStake consensus on merge` + `should switch to ProofOfStake consensus on merge`, ) c.setHardfork(Hardfork.MergeForkIdTransition) assert.equal( c.consensusType(), ConsensusType.ProofOfStake, - `should stay on ProofOfStake consensus post merge` + `should stay on ProofOfStake consensus post merge`, ) // For kiln MergeForkIdTransition happens BEFORE Merge @@ -431,12 +431,12 @@ describe('[Common]: Hardfork logic', () => { assert.equal( c['HARDFORK_CHANGES'][10][0], Hardfork.MergeForkIdTransition, - 'should correctly apply hardfork changes' + 'should correctly apply hardfork changes', ) assert.equal( c['HARDFORK_CHANGES'][11][0], Hardfork.Paris, - 'should correctly apply hardfork changes' + 'should correctly apply hardfork changes', ) // Should give correct ConsensusType pre and post merge @@ -444,19 +444,19 @@ describe('[Common]: Hardfork logic', () => { assert.equal( c.consensusType(), ConsensusType.ProofOfWork, - 'should provide the correct initial chain consensus type' + 'should provide the correct initial chain consensus type', ) c.setHardfork(Hardfork.Paris) assert.equal( c.consensusType(), ConsensusType.ProofOfStake, - `should switch to ProofOfStake consensus on merge` + `should switch to ProofOfStake consensus on merge`, ) c.setHardfork(Hardfork.MergeForkIdTransition) assert.equal( c.consensusType(), ConsensusType.ProofOfWork, - `should give pow consensus as MergeForkIdTransition is pre-merge` + `should give pow consensus as MergeForkIdTransition is pre-merge`, ) }) }) diff --git a/packages/common/test/mergePOS.spec.ts b/packages/common/test/mergePOS.spec.ts index f5dbe3a826..3d350704ec 100644 --- a/packages/common/test/mergePOS.spec.ts +++ b/packages/common/test/mergePOS.spec.ts @@ -16,7 +16,7 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.hardforkTTD('thisHardforkDoesNotExist'), null, - 'should return null if HF does not exist on chain' + 'should return null if HF does not exist on chain', ) }) @@ -159,7 +159,7 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.hardforkTTD(Hardfork.Chainstart), BigInt(0), - 'should get the HF total difficulty' + 'should get the HF total difficulty', ) const msg = 'block number > last HF block number set, TD set (0) and equal' @@ -197,7 +197,7 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.getHardforkBy({ blockNumber: 1450409n, td: 17000000000000000n }), Hardfork.Paris, - msg + msg, ) // should select MergeForkIdTransition even without td specified as the block is set for this hardfork assert.equal(c.getHardforkBy({ blockNumber: 1735371n }), Hardfork.MergeForkIdTransition, msg) @@ -205,24 +205,24 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.getHardforkBy({ blockNumber: 1735371n, td: 17000000000000000n }), Hardfork.MergeForkIdTransition, - msg + msg, ) // Check nextHardforkBlockOrTimestamp should be MergeForkIdTransition's block on london and merge both assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.Berlin), 1735371n, - `should get nextHardforkBlockOrTimestamp correctly` + `should get nextHardforkBlockOrTimestamp correctly`, ) assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.London), 1735371n, - `should get nextHardforkBlockOrTimestamp correctly` + `should get nextHardforkBlockOrTimestamp correctly`, ) assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.Paris), 1735371n, - `should get nextHardforkBlockOrTimestamp correctly` + `should get nextHardforkBlockOrTimestamp correctly`, ) let f = () => { @@ -232,7 +232,7 @@ describe('[Common]: Merge/POS specific logic', () => { f, undefined, undefined, - 'throws error as specified td < merge ttd for a post merge hardfork' + 'throws error as specified td < merge ttd for a post merge hardfork', ) msg = 'should set HF correctly' @@ -242,13 +242,13 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.setHardforkBy({ blockNumber: 1450409n, td: 17000000000000000n }), Hardfork.Paris, - msg + msg, ) assert.equal(c.setHardforkBy({ blockNumber: 1735371n }), Hardfork.MergeForkIdTransition, msg) assert.equal( c.setHardforkBy({ blockNumber: 1735371n, td: 17000000000000000n }), Hardfork.MergeForkIdTransition, - msg + msg, ) f = () => { c.setHardforkBy({ blockNumber: 1735371n, td: 15000000000000000n }) @@ -257,7 +257,7 @@ describe('[Common]: Merge/POS specific logic', () => { f, undefined, undefined, - 'throws error as specified td < merge ttd for a post merge hardfork' + 'throws error as specified td < merge ttd for a post merge hardfork', ) // restore value @@ -278,25 +278,25 @@ describe('[Common]: Merge/POS specific logic', () => { assert.equal( c.setHardforkBy({ blockNumber: 1450409n, td: 17000000000000000n }), Hardfork.Paris, - msg + msg, ) assert.equal(c.setHardforkBy({ blockNumber: 1735371n }), Hardfork.MergeForkIdTransition, msg) assert.equal( c.setHardforkBy({ blockNumber: 1735371n, td: 17000000000000000n }), Hardfork.MergeForkIdTransition, - msg + msg, ) // Check nextHardforkBlockOrTimestamp should be MergeForkIdTransition's block on london and merge both assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.London), 1735371n, - `should get nextHardforkBlockOrTimestamp correctly` + `should get nextHardforkBlockOrTimestamp correctly`, ) assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.Paris), 1735371n, - `should get nextHardforkBlockOrTimestamp correctly` + `should get nextHardforkBlockOrTimestamp correctly`, ) // restore value diff --git a/packages/common/test/params.spec.ts b/packages/common/test/params.spec.ts index 4969aaf6c2..a71702fbc4 100644 --- a/packages/common/test/params.spec.ts +++ b/packages/common/test/params.spec.ts @@ -37,7 +37,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { assert.equal( c.param('ecAddGas'), BigInt(500), - 'Should return correct value for HF set in class' + 'Should return correct value for HF set in class', ) }) diff --git a/packages/common/test/timestamp.spec.ts b/packages/common/test/timestamp.spec.ts index 7bd4008208..1dfcd9e34e 100644 --- a/packages/common/test/timestamp.spec.ts +++ b/packages/common/test/timestamp.spec.ts @@ -19,17 +19,17 @@ describe('[Common]: Timestamp Hardfork logic', () => { assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 0n }), Hardfork.MergeForkIdTransition, - 'should match the HF' + 'should match the HF', ) assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 1668699476n }), Hardfork.Shanghai, - 'should match the HF' + 'should match the HF', ) assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 1668699576n }), Hardfork.Shanghai, - 'should match the HF' + 'should match the HF', ) }) @@ -44,12 +44,12 @@ describe('[Common]: Timestamp Hardfork logic', () => { assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 0n }), Hardfork.MergeForkIdTransition, - 'should match the HF' + 'should match the HF', ) assert.equal( c.nextHardforkBlockOrTimestamp(Hardfork.Shanghai), null, - 'should give null on next Hardfork block' + 'should give null on next Hardfork block', ) }) @@ -64,18 +64,18 @@ describe('[Common]: Timestamp Hardfork logic', () => { assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 0n }), Hardfork.MergeForkIdTransition, - 'should match the HF' + 'should match the HF', ) // Should give the shanghai as sharding is schedule a bit post shanghai assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 1668699476n }), Hardfork.Shanghai, - 'should match the HF' + 'should match the HF', ) assert.equal( c.getHardforkBy({ blockNumber: 1n, timestamp: 1668699576n }), Hardfork.Shanghai, - 'should match the HF' + 'should match the HF', ) }) @@ -101,7 +101,7 @@ describe('[Common]: Timestamp Hardfork logic', () => { const c = createCustomCommon({ hardforks }, { baseChain: Chain.Mainnet }) const mainnetGenesisHash = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) for (const hf of c.hardforks()) { if (typeof hf.forkHash === 'string') { @@ -118,7 +118,7 @@ describe('[Common]: Timestamp Hardfork logic', () => { assert.equal( c.hardforkForForkHash('0xc1fdf181')?.name, Hardfork.Shanghai, - 'Should be able to get Shanghai from forkHash' + 'Should be able to get Shanghai from forkHash', ) }) @@ -142,7 +142,7 @@ describe('[Common]: Timestamp Hardfork logic', () => { const c = createCustomCommon({ hardforks }, { baseChain: Chain.Mainnet }) const mainnetGenesisHash = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) let noForkHashes = c.hardforks().reduce((acc, hf) => { diff --git a/packages/common/test/utils.spec.ts b/packages/common/test/utils.spec.ts index c478553469..5653c817c2 100644 --- a/packages/common/test/utils.spec.ts +++ b/packages/common/test/utils.spec.ts @@ -32,7 +32,7 @@ describe('[Utils/Parse]', () => { assert.deepEqual( params.consensus, { type: 'poa', algorithm: 'clique', clique: { period: 15, epoch: 30000 } }, - 'consensus config matches' + 'consensus config matches', ) const poaJSONCopy = Object.assign({}, poaJSON) poaJSONCopy.nonce = '00' @@ -40,7 +40,7 @@ describe('[Utils/Parse]', () => { assert.equal( params.genesis.nonce, '0x0000000000000000', - 'non-hex prefixed nonce is formatted correctly' + 'non-hex prefixed nonce is formatted correctly', ) assert.equal(params.hardfork, Hardfork.London, 'should correctly infer current hardfork') }) @@ -78,7 +78,7 @@ describe('[Utils/Parse]', () => { 'mergeForkIdTransition', 'paris', ], - 'hardfork parse order should be correct' + 'hardfork parse order should be correct', ) for (const hf of common.hardforks()) { /* eslint-disable @typescript-eslint/no-use-before-define */ @@ -113,7 +113,7 @@ describe('[Utils/Parse]', () => { 'mergeForkIdTransition', 'shanghai', ], - 'hardfork parse order should be correct' + 'hardfork parse order should be correct', ) assert.equal(common1.hardfork(), Hardfork.Shanghai, 'should correctly infer current hardfork') @@ -140,36 +140,36 @@ describe('[Utils/Parse]', () => { 'paris', 'shanghai', ], - 'hardfork parse order should be correct' + 'hardfork parse order should be correct', ) assert.equal(common.getHardforkBy({ blockNumber: 0n }), Hardfork.London, 'london at genesis') assert.equal( common.getHardforkBy({ blockNumber: 1n, td: 2n }), Hardfork.Paris, - 'merge at block 1' + 'merge at block 1', ) // shanghai is at timestamp 8 assert.equal( common.getHardforkBy({ blockNumber: 8n }), Hardfork.London, - 'without timestamp still london' + 'without timestamp still london', ) assert.equal( common.getHardforkBy({ blockNumber: 8n, td: 2n }), Hardfork.Paris, - 'without timestamp at merge' + 'without timestamp at merge', ) assert.equal( common.getHardforkBy({ blockNumber: 8n, timestamp: 8n }), Hardfork.Shanghai, - 'with timestamp at shanghai' + 'with timestamp at shanghai', ) // should be post merge at shanghai assert.equal( common.getHardforkBy({ blockNumber: 8n, td: 2n, timestamp: 8n }), Hardfork.Shanghai, - 'post merge shanghai' + 'post merge shanghai', ) assert.equal(common.hardfork(), Hardfork.Shanghai, 'should correctly infer common hardfork') }) @@ -185,7 +185,7 @@ describe('[Utils/Parse]', () => { assert.equal( depositContractAddress, getInitializedChains().mainnet.depositContractAddress, - 'should assign mainnet deposit contract' + 'should assign mainnet deposit contract', ) }) @@ -206,7 +206,7 @@ describe('[Utils/Parse]', () => { assert.equal( depositContractAddress, '0x4242424242424242424242424242424242424242', - 'should parse correct address' + 'should parse correct address', ) }) }) diff --git a/packages/common/tsconfig.lint.json b/packages/common/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/common/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/devp2p/.eslintrc.cjs b/packages/devp2p/.eslintrc.cjs index 940a7fc316..9c3e67209e 100644 --- a/packages/devp2p/.eslintrc.cjs +++ b/packages/devp2p/.eslintrc.cjs @@ -5,4 +5,13 @@ module.exports = { 'no-redeclare': 'off', 'no-undef': 'off', // temporary until fixed: 'NodeJS' is not defined }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], } diff --git a/packages/devp2p/examples/dpt.ts b/packages/devp2p/examples/dpt.ts index c054953328..af85e5a13f 100644 --- a/packages/devp2p/examples/dpt.ts +++ b/packages/devp2p/examples/dpt.ts @@ -1,5 +1,5 @@ import { DPT } from '@ethereumjs/devp2p' -import { bytesToHex, hexToBytes, randomBytes } from '@ethereumjs/util' +import { bytesToHex, hexToBytes } from '@ethereumjs/util' const PRIVATE_KEY = hexToBytes('0xed6df2d4b7e82d105538e4a1279925a16a84e772243e80a561e1b201f2e78220') const main = async () => { @@ -12,7 +12,7 @@ const main = async () => { }) console.log(`DPT is active and has id - ${bytesToHex(dpt.id!)}`) // Should log the DPT's hex ID - 0xcd80bb7a768432302d267729c15da61d172373ea036... - await dpt.destroy() + dpt.destroy() } -main() +void main() diff --git a/packages/devp2p/examples/peer-communication-les.ts b/packages/devp2p/examples/peer-communication-les.ts index f85d1ad84e..f173cb44db 100644 --- a/packages/devp2p/examples/peer-communication-les.ts +++ b/packages/devp2p/examples/peer-communication-les.ts @@ -1,17 +1,18 @@ -import { bytesToInt, intToBytes, randomBytes, bytesToHex, hexToBytes } from '@ethereumjs/util' -import { Block, BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' +import { BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' +import * as devp2p from '@ethereumjs/devp2p' +import { bytesToHex, bytesToInt, hexToBytes, intToBytes, randomBytes } from '@ethereumjs/util' import chalk from 'chalk' import ms from 'ms' -import * as devp2p from '@ethereumjs/devp2p' -import { ETH, Peer } from '@ethereumjs/devp2p' +import type { Block } from '@ethereumjs/block' +import type { Peer } from '@ethereumjs/devp2p' const PRIVATE_KEY = randomBytes(32) const GENESIS_TD = 1 const GENESIS_HASH = hexToBytes( - '0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177' + '0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177', ) const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) @@ -72,8 +73,8 @@ rlpx.events.on('peer:added', (peer) => { const clientId = peer.getHelloMessage().clientId console.log( chalk.green( - `Add peer: ${addr} ${clientId} (les${les.getVersion()}) (total: ${rlpx.getPeers().length})` - ) + `Add peer: ${addr} ${clientId} (les${les.getVersion()}) (total: ${rlpx.getPeers().length})`, + ), ) les.sendStatus({ @@ -104,7 +105,7 @@ rlpx.events.on('peer:added', (peer) => { case devp2p.LES.MESSAGE_CODES.BLOCK_HEADERS: { if (payload[2].length > 1) { console.log( - `${addr} not more than one block header expected (received: ${payload[2].length})` + `${addr} not more than one block header expected (received: ${payload[2].length})`, ) break } @@ -123,7 +124,7 @@ rlpx.events.on('peer:added', (peer) => { case devp2p.LES.MESSAGE_CODES.BLOCK_BODIES: { if (payload[2].length !== 1) { console.log( - `${addr} not more than one block body expected (received: ${payload[2].length})` + `${addr} not more than one block body expected (received: ${payload[2].length})`, ) break } @@ -155,9 +156,9 @@ rlpx.events.on('peer:removed', (peer, reasonCode, disconnectWe) => { console.log( chalk.yellow( `Remove peer: ${getPeerAddr(peer)} - ${who}, reason: ${peer.getDisconnectPrefix( - reasonCode - )} (${String(reasonCode)}) (total: ${total})` - ) + reasonCode, + )} (${String(reasonCode)}) (total: ${total})`, + ), ) }) @@ -203,11 +204,11 @@ function onNewBlock(block: Block, peer: Peer) { const blockNumber = block.header.number console.log( - `----------------------------------------------------------------------------------------------------------` + `----------------------------------------------------------------------------------------------------------`, ) console.log(`block ${blockNumber} received: ${blockHashHex} (from ${getPeerAddr(peer)})`) console.log( - `----------------------------------------------------------------------------------------------------------` + `----------------------------------------------------------------------------------------------------------`, ) } @@ -229,7 +230,7 @@ setInterval(() => { console.log( chalk.yellow( - `Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}` - ) + `Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}`, + ), ) }, ms('30s')) diff --git a/packages/devp2p/examples/peer-communication.ts b/packages/devp2p/examples/peer-communication.ts index a6da6f7ce1..e408062864 100644 --- a/packages/devp2p/examples/peer-communication.ts +++ b/packages/devp2p/examples/peer-communication.ts @@ -1,22 +1,23 @@ +import { BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' +import { Chain, Common, Hardfork } from '@ethereumjs/common' +import * as devp2p from '@ethereumjs/devp2p' +import { RLP } from '@ethereumjs/rlp' +import { createTxFromBlockBodyData } from '@ethereumjs/tx' import { bytesToInt, - intToBytes, - randomBytes, bytesToUnprefixedHex, equalsBytes, hexToBytes, + intToBytes, + randomBytes, } from '@ethereumjs/util' -import { Block, BlockHeader, createBlockFromValuesArray } from '@ethereumjs/block' -import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { RLP } from '@ethereumjs/rlp' -import { createTxFromBlockBodyData, TypedTransaction } from '@ethereumjs/tx' import chalk from 'chalk' import { LRUCache } from 'lru-cache' - import ms from 'ms' -import * as devp2p from '@ethereumjs/devp2p' -import { ETH, Peer } from '@ethereumjs/devp2p' +import type { Block } from '@ethereumjs/block' +import type { ETH, Peer } from '@ethereumjs/devp2p' +import type { TypedTransaction } from '@ethereumjs/tx' const PRIVATE_KEY = randomBytes(32) @@ -45,7 +46,7 @@ const CHECK_BLOCK_TITLE = 'Berlin Fork' // Only for debugging/console output const CHECK_BLOCK_NR = 12244000 const CHECK_BLOCK = '1638380ab737e0e916bd1c7f23bd2bab2a532e44b90047f045f262ee21c42b21' const CHECK_BLOCK_HEADER = RLP.decode( - '0xf90219a0d44a4d33e28d7ea9edd12b69bd32b394587eee498b0e2543ce2bad1877ffbeaca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941ad91ee08f21be3de0ba2ba6918e714da6b45836a0fdec060ee45e55da9e36060fc95dddd0bdc47e447224666a895d9f0dc9adaa0ca0092d9fcc02ca9b372daec726704ce720d3aa366739868f4820ecaabadb9ac309a0974fee017515a46303f467b6fd50872994db1b0ea64d3455bad93ff9678aced9b90100356050004c5c89691add79838a01d4c302419252a4d3c96e9273908b7ee84660886c070607b4928c416a1800746a0d1dbb442d0baf06eea321422263726748600cc200e82aec08336863514d12d665718016989189c116bc0947046cc6718110586c11464a189000a11a41cc96991970153d88840768170244197e164c6204249b9091a0052ac85088c8108a4418dd2903690a036722623888ea14e90458a390a305a2342cb02766094f68c4100036330719848b48411614686717ab6068a46318204232429dc42020608802ceecd66c3c33a3a1fc6e82522049470328a4a81ba07c6604228ba94f008476005087a6804463696b41002650c0fdf548448a90408717ca31b6d618e883bad42083be153b83bdfbb1846078104798307834383639373636353666366532303530366636663663a0ae1de0acd35a98e211c7e276ad7524bb84a5e1b8d33dd7d1c052b095b564e8b888cca66773148b6e12' + '0xf90219a0d44a4d33e28d7ea9edd12b69bd32b394587eee498b0e2543ce2bad1877ffbeaca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941ad91ee08f21be3de0ba2ba6918e714da6b45836a0fdec060ee45e55da9e36060fc95dddd0bdc47e447224666a895d9f0dc9adaa0ca0092d9fcc02ca9b372daec726704ce720d3aa366739868f4820ecaabadb9ac309a0974fee017515a46303f467b6fd50872994db1b0ea64d3455bad93ff9678aced9b90100356050004c5c89691add79838a01d4c302419252a4d3c96e9273908b7ee84660886c070607b4928c416a1800746a0d1dbb442d0baf06eea321422263726748600cc200e82aec08336863514d12d665718016989189c116bc0947046cc6718110586c11464a189000a11a41cc96991970153d88840768170244197e164c6204249b9091a0052ac85088c8108a4418dd2903690a036722623888ea14e90458a390a305a2342cb02766094f68c4100036330719848b48411614686717ab6068a46318204232429dc42020608802ceecd66c3c33a3a1fc6e82522049470328a4a81ba07c6604228ba94f008476005087a6804463696b41002650c0fdf548448a90408717ca31b6d618e883bad42083be153b83bdfbb1846078104798307834383639373636353666366532303530366636663663a0ae1de0acd35a98e211c7e276ad7524bb84a5e1b8d33dd7d1c052b095b564e8b888cca66773148b6e12', ) const getPeerAddr = (peer: Peer) => `${peer['_socket'].remoteAddress}:${peer['_socket'].remotePort}` @@ -88,8 +89,8 @@ rlpx.events.on('peer:added', (peer) => { const clientId = peer.getHelloMessage().clientId console.log( chalk.green( - `Add peer: ${addr} ${clientId} (eth${eth.getVersion()}) (total: ${rlpx.getPeers().length})` - ) + `Add peer: ${addr} ${clientId} (eth${eth.getVersion()}) (total: ${rlpx.getPeers().length})`, + ), ) eth.sendStatus({ @@ -166,7 +167,7 @@ rlpx.events.on('peer:added', (peer) => { if (!forkVerified) { if (payload[1].length !== 1) { console.log( - `${addr} expected one header for ${CHECK_BLOCK_TITLE} verify (received: ${payload[1].length})` + `${addr} expected one header for ${CHECK_BLOCK_TITLE} verify (received: ${payload[1].length})`, ) peer.disconnect(devp2p.DISCONNECT_REASON.USELESS_PEER) break @@ -182,7 +183,7 @@ rlpx.events.on('peer:added', (peer) => { } else { if (payload[1].length > 1) { console.log( - `${addr} not more than one block header expected (received: ${payload[1].length})` + `${addr} not more than one block header expected (received: ${payload[1].length})`, ) break } @@ -206,7 +207,7 @@ rlpx.events.on('peer:added', (peer) => { if (!isValidPayload) { console.log( - `${addr} received wrong block header ${bytesToUnprefixedHex(header.hash())}` + `${addr} received wrong block header ${bytesToUnprefixedHex(header.hash())}`, ) } } @@ -227,7 +228,7 @@ rlpx.events.on('peer:added', (peer) => { if (payload[1].length !== 1) { console.log( - `${addr} not more than one block body expected (received: ${payload[1].length})` + `${addr} not more than one block body expected (received: ${payload[1].length})`, ) break } @@ -294,9 +295,9 @@ rlpx.events.on('peer:removed', (peer, reasonCode, disconnectWe) => { console.log( chalk.yellow( `Remove peer: ${getPeerAddr(peer)} - ${who}, reason: ${peer.getDisconnectPrefix( - reasonCode - )} (${String(reasonCode)}) (total: ${total})` - ) + reasonCode, + )} (${String(reasonCode)}) (total: ${total})`, + ), ) }) @@ -378,7 +379,7 @@ setInterval(() => { console.log( chalk.yellow( - `Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}` - ) + `Total nodes in DPT: ${peersCount}, open slots: ${openSlots}, queue: ${queueLength} / ${queueLength2}`, + ), ) }, ms('30s')) diff --git a/packages/devp2p/examples/rlpx.ts b/packages/devp2p/examples/rlpx.ts index b2293763d3..c9d0b46727 100644 --- a/packages/devp2p/examples/rlpx.ts +++ b/packages/devp2p/examples/rlpx.ts @@ -1,11 +1,11 @@ import { Chain, Common } from '@ethereumjs/common' -import { RLPx, ETH } from '@ethereumjs/devp2p' +import { ETH, RLPx } from '@ethereumjs/devp2p' import { hexToBytes } from '@ethereumjs/util' const main = async () => { const common = new Common({ chain: Chain.Mainnet }) const PRIVATE_KEY = hexToBytes( - '0xed6df2d4b7e82d105538e4a1279925a16a84e772243e80a561e1b201f2e78220' + '0xed6df2d4b7e82d105538e4a1279925a16a84e772243e80a561e1b201f2e78220', ) const rlpx = new RLPx(PRIVATE_KEY, { maxPeers: 25, @@ -13,7 +13,7 @@ const main = async () => { common, }) console.log(`RLPx is active - ${rlpx._isAlive()}`) - await rlpx.destroy() + rlpx.destroy() } -main() +void main() diff --git a/packages/devp2p/examples/simple.ts b/packages/devp2p/examples/simple.ts index 130fbac857..c25b51eddd 100644 --- a/packages/devp2p/examples/simple.ts +++ b/packages/devp2p/examples/simple.ts @@ -1,8 +1,7 @@ import { Chain, Common } from '@ethereumjs/common' -import chalk from 'chalk' -import { bytesToHex, hexToBytes } from '@ethereumjs/util' - import { DPT } from '@ethereumjs/devp2p' +import { bytesToHex, hexToBytes } from '@ethereumjs/util' +import chalk from 'chalk' const TIMEOUT = 5000 // 5 second timeout const PRIVATE_KEY = '0xd772e3d6a001a38064dd23964dd2836239fa0e6cec8b28972a87460a17210fe9' diff --git a/packages/devp2p/src/dns/dns.ts b/packages/devp2p/src/dns/dns.ts index d2d056994e..ac526b30c1 100644 --- a/packages/devp2p/src/dns/dns.ts +++ b/packages/devp2p/src/dns/dns.ts @@ -32,7 +32,7 @@ export class DNS { this._common = options.common this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } /** diff --git a/packages/devp2p/src/dns/enr.ts b/packages/devp2p/src/dns/enr.ts index 996ed5938c..43ad937c35 100644 --- a/packages/devp2p/src/dns/enr.ts +++ b/packages/devp2p/src/dns/enr.ts @@ -74,7 +74,7 @@ export class ENR { const isVerified = ecdsaVerify( signature as Uint8Array, (common?.customCrypto.keccak256 ?? keccak256)(RLP.encode([seq, ...kvs])), - obj.secp256k1 + obj.secp256k1, ) if (!isVerified) throw new Error('Unable to verify ENR signature') @@ -106,7 +106,7 @@ export class ENR { 'eRoot', 'lRoot', 'seq', - 'signature' + 'signature', ) as ENRRootValues if (!rootVals.eRoot) throw new Error("Could not parse 'e' value from ENR root entry") @@ -122,7 +122,7 @@ export class ENR { const signedComponent = root.split(' sig')[0] const signedComponentBytes = utf8ToBytes(signedComponent) const signatureBytes = Uint8Array.from( - [...base64url.decode(rootVals.signature + '=').values()].slice(0, 64) + [...base64url.decode(rootVals.signature + '=').values()].slice(0, 64), ) const keyBytes = Uint8Array.from(decodedPublicKey) @@ -130,7 +130,7 @@ export class ENR { const isVerified = ecdsaVerify( signatureBytes, (common?.customCrypto.keccak256 ?? keccak256)(signedComponentBytes), - keyBytes + keyBytes, ) if (!isVerified) throw new Error('Unable to verify ENR root signature') @@ -154,7 +154,7 @@ export class ENR { tree, `${this.TREE_PREFIX}//%s@%s`, 'publicKey', - 'domain' + 'domain', ) as ENRTreeValues if (!treeVals.publicKey) throw new Error('Could not parse public key from ENR tree entry') diff --git a/packages/devp2p/src/dpt/ban-list.ts b/packages/devp2p/src/dpt/ban-list.ts index 639a700e96..cae50bd8af 100644 --- a/packages/devp2p/src/dpt/ban-list.ts +++ b/packages/devp2p/src/dpt/ban-list.ts @@ -16,7 +16,7 @@ export class BanList { constructor() { this._lru = new LRUCache({ max: 10000 }) this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } add(obj: string | Uint8Array | PeerInfo, maxAge?: number) { diff --git a/packages/devp2p/src/dpt/dpt.ts b/packages/devp2p/src/dpt/dpt.ts index 60c6f61f1e..8a6b2341c7 100644 --- a/packages/devp2p/src/dpt/dpt.ts +++ b/packages/devp2p/src/dpt/dpt.ts @@ -86,7 +86,7 @@ export class DPT { this._refreshIntervalId = setInterval(() => this.refresh(), refreshIntervalSubdivided) this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } bind(...args: any[]): void { @@ -113,7 +113,8 @@ export class DPT { }) .then(() => { if (++count < oldPeers.length) return - if (err === null) this._banlist.add(newPeer, 300000) // 5 min * 60 * 1000 + if (err === null) + this._banlist.add(newPeer, 300000) // 5 min * 60 * 1000 else this._kbucket.add(newPeer) }) } @@ -200,7 +201,7 @@ export class DPT { let peers = this._kbucket.closest(id) if (this._onlyConfirmed && this._confirmedPeers.size > 0) { peers = peers.filter((peer) => - this._confirmedPeers.has(bytesToUnprefixedHex(peer.id as Uint8Array)) ? true : false + this._confirmedPeers.has(bytesToUnprefixedHex(peer.id as Uint8Array)) ? true : false, ) } return peers @@ -231,7 +232,7 @@ export class DPT { const peers = this.getPeers() if (this.DEBUG) { this._debug( - `call .refresh() (selector ${this._refreshIntervalSelectionCounter}) (${peers.length} peers in table)` + `call .refresh() (selector ${this._refreshIntervalSelectionCounter}) (${peers.length} peers in table)`, ) } @@ -259,7 +260,7 @@ export class DPT { this._debug( `.refresh() Adding ${dnsPeers.length} from DNS tree, (${ this.getPeers().length - } current peers in table)` + } current peers in table)`, ) } diff --git a/packages/devp2p/src/dpt/message.ts b/packages/devp2p/src/dpt/message.ts index f0d09ccfcd..8e861c6519 100644 --- a/packages/devp2p/src/dpt/message.ts +++ b/packages/devp2p/src/dpt/message.ts @@ -197,7 +197,7 @@ export function decode(bytes: Uint8Array, common?: Common) { signature, recoverId, sighash, - false + false, ) return { typename, data, publicKey } } diff --git a/packages/devp2p/src/dpt/server.ts b/packages/devp2p/src/dpt/server.ts index dfb982e3f0..73b3c16076 100644 --- a/packages/devp2p/src/dpt/server.ts +++ b/packages/devp2p/src/dpt/server.ts @@ -63,7 +63,7 @@ export class Server { this._common = options.common this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } bind(...args: any[]) { @@ -111,7 +111,7 @@ export class Server { this._debug( `ping timeout: ${peer.address}:${peer.udpPort} ${ peer.id ? formatLogId(bytesToHex(peer.id), verbose) : '-' - }` + }`, ) } this._requests.delete(rkey) @@ -140,7 +140,7 @@ export class Server { typename, `send ${typename} to ${peer.address}:${peer.udpPort} (peerId: ${ peer.id ? formatLogId(bytesToHex(peer.id), verbose) : '-' - })` + })`, ) } @@ -159,8 +159,8 @@ export class Server { info.typename.toString(), `received ${info.typename} from ${rinfo.address}:${rinfo.port} (peerId: ${formatLogId( bytesToHex(peerId), - verbose - )})` + verbose, + )})`, ) } @@ -217,7 +217,7 @@ export class Server { case 'neighbours': { this.events.emit( 'peers', - info.data.peers.map((peer: any) => peer.endpoint) + info.data.peers.map((peer: any) => peer.endpoint), ) break } diff --git a/packages/devp2p/src/protocol/eth.ts b/packages/devp2p/src/protocol/eth.ts index c2dd7e0c92..fc89e9cbb7 100644 --- a/packages/devp2p/src/protocol/eth.ts +++ b/packages/devp2p/src/protocol/eth.ts @@ -78,7 +78,7 @@ export class ETH extends Protocol { null, 'Uncontrolled status message', this.debug.bind(this), - 'STATUS' + 'STATUS', ) this._peerStatus = payload as ETH.StatusMsg const peerStatusMsg = `${ @@ -185,21 +185,21 @@ export class ETH extends Protocol { this._peerStatus[0], 'Protocol version mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) assertEq( this._status[1], this._peerStatus[1], 'NetworkId mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) assertEq( this._status[4], this._peerStatus[4], 'Genesis block mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) const status: { @@ -222,7 +222,7 @@ export class ETH extends Protocol { 2, 'Incorrect forkId msg format', this.debug.bind(this), - 'STATUS' + 'STATUS', ) this._validateForkId(this._peerStatus[5] as Uint8Array[]) status.forkId = this._peerStatus[5] @@ -248,11 +248,11 @@ export class ETH extends Protocol { _getStatusString(status: ETH.StatusMsg) { let sStr = `[V:${bytesToInt(status[0] as Uint8Array)}, NID:${bytesToInt( - status[1] as Uint8Array + status[1] as Uint8Array, )}, TD:${status[2].length === 0 ? 0 : bytesToBigInt(status[2] as Uint8Array).toString()}` sStr += `, BestH:${formatLogId( bytesToHex(status[3] as Uint8Array), - this._verbose + this._verbose, )}, GenH:${formatLogId(bytesToHex(status[4] as Uint8Array), this._verbose)}` if (this._version >= 64) { sStr += `, ForkHash: ${ @@ -280,13 +280,13 @@ export class ETH extends Protocol { const latestBlock = bytesToBigInt(status.latestBlock) if (latestBlock < this._latestBlock) { throw new Error( - 'latest block provided is not matching the HF setting of the Common instance (Rlpx)' + 'latest block provided is not matching the HF setting of the Common instance (Rlpx)', ) } this._latestBlock = latestBlock } const forkHashB = hexToBytes( - isHexString(this._forkHash) ? this._forkHash : `0x${this._forkHash}` + isHexString(this._forkHash) ? this._forkHash : `0x${this._forkHash}`, ) const nextForkB = @@ -301,7 +301,7 @@ export class ETH extends Protocol { `Send STATUS message to ${this._peer['_socket'].remoteAddress}:${ this._peer['_socket'].remotePort - } (eth${this._version}): ${this._getStatusString(this._status)}` + } (eth${this._version}): ${this._getStatusString(this._status)}`, ) } diff --git a/packages/devp2p/src/protocol/les.ts b/packages/devp2p/src/protocol/les.ts index a0950a7f17..6c23c389c2 100644 --- a/packages/devp2p/src/protocol/les.ts +++ b/packages/devp2p/src/protocol/les.ts @@ -34,7 +34,7 @@ export class LES extends Protocol { }, 5000) // 5 sec * 1000 this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } static les2 = { name: 'les', version: 2, length: 21, constructor: LES } @@ -50,7 +50,7 @@ export class LES extends Protocol { this.getMsgPrefix(code), `${`Received ${this.getMsgPrefix(code)} message from ${ this._peer['_socket'].remoteAddress - }:${this._peer['_socket'].remotePort}`}: ${logData}` + }:${this._peer['_socket'].remotePort}`}: ${logData}`, ) } } @@ -61,7 +61,7 @@ export class LES extends Protocol { null, 'Uncontrolled status message', this.debug.bind(this), - 'STATUS' + 'STATUS', ) const status: LES.Status = Object.assign({}) for (const value of payload as NestedUint8Array) { @@ -73,7 +73,7 @@ export class LES extends Protocol { this.getMsgPrefix(code), `${`Received ${this.getMsgPrefix(code)} message from ${ this._peer['_socket'].remoteAddress - }:${this._peer['_socket'].remotePort}`}: ${this._getStatusString(this._peerStatus)}` + }:${this._peer['_socket'].remotePort}`}: ${this._getStatusString(this._peerStatus)}`, ) } this._handleStatus() @@ -124,21 +124,21 @@ export class LES extends Protocol { this._peerStatus['protocolVersion'], 'Protocol version mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) assertEq( this._status['chainId'], this._peerStatus['chainId'], 'NetworkId mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) assertEq( this._status['genesisHash'], this._peerStatus['genesisHash'], 'Genesis block mismatch', this.debug.bind(this), - 'STATUS' + 'STATUS', ) this.events.emit('status', this._peerStatus) @@ -154,7 +154,7 @@ export class LES extends Protocol { _getStatusString(status: LES.Status) { let sStr = `[V:${bytesToInt(status['protocolVersion'])}, ` sStr += `NID:${bytesToInt(status['chainId'] as Uint8Array)}, HTD:${bytesToInt( - status['headTd'] + status['headTd'], )}, ` sStr += `HeadH:${bytesToHex(status['headHash'])}, HeadN:${bytesToInt(status['headNum'])}, ` sStr += `GenH:${bytesToHex(status['genesisHash'])}` @@ -169,7 +169,7 @@ export class LES extends Protocol { if (status['flowControl/MRC)'] !== undefined) sStr += `, flowControl/MRC set` if (status['forkID'] !== undefined) sStr += `, forkID: [crc32: ${bytesToHex(status['forkID'][0])}, nextFork: ${bytesToInt( - status['forkID'][1] + status['forkID'][1], )}]` if (status['recentTxLookup'] !== undefined) sStr += `, recentTxLookup: ${bytesToInt(status['recentTxLookup'])}` @@ -198,7 +198,7 @@ export class LES extends Protocol { 'STATUS', `Send STATUS message to ${this._peer['_socket'].remoteAddress}:${ this._peer['_socket'].remotePort - } (les${this._version}): ${this._getStatusString(this._status)}` + } (les${this._version}): ${this._getStatusString(this._status)}`, ) } @@ -224,7 +224,7 @@ export class LES extends Protocol { this.getMsgPrefix(code), `Send ${this.getMsgPrefix(code)} message to ${this._peer['_socket'].remoteAddress}:${ this._peer['_socket'].remotePort - }: ${formatLogData(bytesToHex(RLP.encode(payload)), this._verbose)}` + }: ${formatLogData(bytesToHex(RLP.encode(payload)), this._verbose)}`, ) } diff --git a/packages/devp2p/src/protocol/protocol.ts b/packages/devp2p/src/protocol/protocol.ts index 01ccd3e22e..6d54e2be4f 100644 --- a/packages/devp2p/src/protocol/protocol.ts +++ b/packages/devp2p/src/protocol/protocol.ts @@ -34,7 +34,7 @@ export abstract class Protocol { send: SendMethod, protocol: ProtocolType, version: number, - messageCodes: MessageCodes + messageCodes: MessageCodes, ) { this.events = new EventEmitter() this._peer = peer @@ -55,7 +55,7 @@ export abstract class Protocol { private initMsgDebuggers(protocol: ProtocolType) { const MESSAGE_NAMES = Object.values(this._messageCodes).filter( - (value) => typeof value === 'string' + (value) => typeof value === 'string', ) as string[] for (const name of MESSAGE_NAMES) { this.msgDebuggers[name] = devp2pDebug.extend(protocol).extend(name) diff --git a/packages/devp2p/src/protocol/snap.ts b/packages/devp2p/src/protocol/snap.ts index 084c93aa72..3fa8da2d44 100644 --- a/packages/devp2p/src/protocol/snap.ts +++ b/packages/devp2p/src/protocol/snap.ts @@ -16,7 +16,7 @@ export class SNAP extends Protocol { constructor(version: number, peer: Peer, send: SendMethod) { super(peer, send, ProtocolType.SNAP, version, SNAP.MESSAGE_CODES) this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } static snap = { name: 'snap', version: 1, length: 8, constructor: SNAP } @@ -30,7 +30,7 @@ export class SNAP extends Protocol { this.getMsgPrefix(code), `Received ${this.getMsgPrefix(code)} message from ${this._peer['_socket'].remoteAddress}:${ this._peer['_socket'].remotePort - }: ${formatLogData(bytesToHex(data), this._verbose)}` + }: ${formatLogData(bytesToHex(data), this._verbose)}`, ) } @@ -66,7 +66,7 @@ export class SNAP extends Protocol { this.getMsgPrefix(code), `Send ${this.getMsgPrefix(code)} message to ${this._peer['_socket'].remoteAddress}:${ this._peer['_socket'].remotePort - }: ${formatLogData(utils.bytesToHex(RLP.encode(payload)), this._verbose)}` + }: ${formatLogData(utils.bytesToHex(RLP.encode(payload)), this._verbose)}`, ) } diff --git a/packages/devp2p/src/rlpx/ecies.ts b/packages/devp2p/src/rlpx/ecies.ts index d13fa10886..4eaa7455d5 100644 --- a/packages/devp2p/src/rlpx/ecies.ts +++ b/packages/devp2p/src/rlpx/ecies.ts @@ -43,7 +43,7 @@ function concatKDF(keyMaterial: Uint8Array, keyLength: number) { counter += 1 new DataView(tmp.buffer).setUint32(0, counter) bytes.push( - Uint8Array.from(crypto.createHash('sha256').update(tmp).update(keyMaterial).digest()) + Uint8Array.from(crypto.createHash('sha256').update(tmp).update(keyMaterial).digest()), ) } @@ -73,7 +73,7 @@ export class ECIES { protected _keccakFunction: (msg: Uint8Array) => Uint8Array protected _ecdsaSign: ( msg: Uint8Array, - pk: Uint8Array + pk: Uint8Array, ) => { signature: Uint8Array recid: number @@ -82,7 +82,7 @@ export class ECIES { sig: Uint8Array, recId: number, hash: Uint8Array, - compressed?: boolean + compressed?: boolean, ) => Uint8Array constructor(privateKey: Uint8Array, id: Uint8Array, remoteId: Uint8Array, common?: Common) { @@ -101,7 +101,7 @@ export class ECIES { _encryptMessage( data: Uint8Array, - sharedMacData: Uint8Array | null = null + sharedMacData: Uint8Array | null = null, ): Uint8Array | undefined { const privateKey = genPrivateKey() if (!this._remotePublicKey) return @@ -121,7 +121,7 @@ export class ECIES { sharedMacData = Uint8Array.from([]) } const tag = Uint8Array.from( - crypto.createHmac('sha256', mkey).update(concatBytes(dataIV, sharedMacData)).digest() + crypto.createHmac('sha256', mkey).update(concatBytes(dataIV, sharedMacData)).digest(), ) const publicKey = secp256k1.getPublicKey(privateKey, false) @@ -133,7 +133,7 @@ export class ECIES { data.subarray(0, 1), hexToBytes('0x04'), 'wrong ecies header (possible cause: EIP8 upgrade)', - debug + debug, ) const publicKey = data.subarray(0, 65) @@ -220,7 +220,7 @@ export class ECIES { this._keccakFunction(pk2id(this._ephemeralPublicKey)), pk2id(this._publicKey), this._nonce, - Uint8Array.from([0x00]) + Uint8Array.from([0x00]), ) this._initMsg = this._encryptMessage(data) @@ -229,7 +229,7 @@ export class ECIES { parseAuthPlain( data: Uint8Array, - sharedMacData: Uint8Array | null = null + sharedMacData: Uint8Array | null = null, ): Uint8Array | undefined { const prefix = sharedMacData !== null ? sharedMacData : new Uint8Array() this._remoteInitMsg = concatBytes(prefix, data) @@ -272,7 +272,7 @@ export class ECIES { signature, recoveryId, xor(x, this._remoteNonce), - false + false, ) if (this._remoteEphemeralPublicKey === null) return @@ -282,7 +282,7 @@ export class ECIES { this._keccakFunction(pk2id(this._remoteEphemeralPublicKey)), heid, 'the hash of the ephemeral key should match', - debug + debug, ) } } diff --git a/packages/devp2p/src/rlpx/peer.ts b/packages/devp2p/src/rlpx/peer.ts index e980c89688..228cc13bd3 100644 --- a/packages/devp2p/src/rlpx/peer.ts +++ b/packages/devp2p/src/rlpx/peer.ts @@ -143,7 +143,7 @@ export class Peer { this._sendAuth() } this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } /** @@ -152,7 +152,7 @@ export class Peer { _sendAuth() { if (this._closed) return this._logger( - `Send auth (EIP8: ${this._EIP8}) to ${this._socket.remoteAddress}:${this._socket.remotePort}` + `Send auth (EIP8: ${this._EIP8}) to ${this._socket.remoteAddress}:${this._socket.remotePort}`, ) if (this._EIP8 === true) { const authEIP8 = this._eciesSession.createAuthEIP8() @@ -173,7 +173,7 @@ export class Peer { _sendAck() { if (this._closed) return this._logger( - `Send ack (EIP8: ${this._eciesSession['_gotEIP8Auth']}) to ${this._socket.remoteAddress}:${this._socket.remotePort}` + `Send ack (EIP8: ${this._eciesSession['_gotEIP8Auth']}) to ${this._socket.remoteAddress}:${this._socket.remotePort}`, ) if (this._eciesSession['_gotEIP8Auth']) { @@ -227,7 +227,7 @@ export class Peer { // TODO: Remove when we can also serve snap requests from other peers .filter((c) => c.name !== 'snap') .map((c) => `${c.name}${c.version}`) - .join(',')} clientId=${bytesToUtf8(this.clientId)}` + .join(',')} clientId=${bytesToUtf8(this.clientId)}`, ) } const payload: HelloMsg = [ @@ -260,7 +260,7 @@ export class Peer { this.debug( 'DISCONNECT', `Send DISCONNECT to ${this._socket.remoteAddress}:${this._socket.remotePort} (reason: ${reasonName})`, - reasonName + reasonName, ) } const data = RLP.encode(reason) @@ -340,7 +340,7 @@ export class Peer { if (parseData.subarray(0, 1) === hexToBytes('0x04')) { this._eciesSession.parseAckPlain(parseData) this._logger( - `Received ack (old format) from ${this._socket.remoteAddress}:${this._socket.remotePort}` + `Received ack (old format) from ${this._socket.remoteAddress}:${this._socket.remotePort}`, ) } else { this._eciesSession['_gotEIP8Ack'] = true @@ -350,7 +350,7 @@ export class Peer { } else { this._eciesSession.parseAckEIP8(parseData) this._logger( - `Received ack (EIP8) from ${this._socket.remoteAddress}:${this._socket.remotePort}` + `Received ack (EIP8) from ${this._socket.remoteAddress}:${this._socket.remotePort}`, ) } this._state = 'Header' @@ -380,7 +380,7 @@ export class Peer { this._hello.protocolVersion } capabilities=${(this._hello.capabilities ?? []) .map((c) => `${c.name}${c.version}`) - .join(',')} clientId=${this._hello.clientId}` + .join(',')} clientId=${this._hello.clientId}`, ) } @@ -458,7 +458,7 @@ export class Peer { `DISCONNECT reason: ${DISCONNECT_REASON[this._disconnectReason as number]} ${ this._socket.remoteAddress }:${this._socket.remotePort}`, - DISCONNECT_REASON[this._disconnectReason as number] + DISCONNECT_REASON[this._disconnectReason as number], ) } this._disconnectWe = false @@ -534,8 +534,8 @@ export class Peer { this._logger( `Received body ${this._socket.remoteAddress}:${this._socket.remotePort} ${formatLogData( bytesToHex(body), - verbose - )}` + verbose, + )}`, ) this._state = 'Header' this._nextPacketSize = 32 diff --git a/packages/devp2p/src/rlpx/rlpx.ts b/packages/devp2p/src/rlpx/rlpx.ts index 45232dcf4c..7e5f49a158 100644 --- a/packages/devp2p/src/rlpx/rlpx.ts +++ b/packages/devp2p/src/rlpx/rlpx.ts @@ -94,7 +94,7 @@ export class RLPx { this._dpt.events.on('peer:removed', (peer: PeerInfo) => { // remove from queue this._peersQueue = this._peersQueue.filter( - (item) => !equalsBytes(item.peer.id! as Uint8Array, peer.id as Uint8Array) + (item) => !equalsBytes(item.peer.id! as Uint8Array, peer.id as Uint8Array), ) }) } @@ -119,7 +119,7 @@ export class RLPx { this._keccakFunction = options.common?.customCrypto.keccak256 ?? keccak256 this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } listen(...args: any[]) { @@ -157,7 +157,7 @@ export class RLPx { if (this.DEBUG) { this._debug( - `connect to ${peer.address}:${peer.tcpPort} (id: ${formatLogId(peerKey, verbose)})` + `connect to ${peer.address}:${peer.tcpPort} (id: ${formatLogId(peerKey, verbose)})`, ) } const deferred = createDeferred() @@ -272,7 +272,7 @@ export class RLPx { if (this.DEBUG) { this._debug( `disconnect from ${socket.remoteAddress}:${socket.remotePort}, reason: ${DISCONNECT_REASON[reason]}`, - `disconnect` + `disconnect`, ) } } @@ -309,7 +309,7 @@ export class RLPx { this._refillIntervalSelectionCounter } peers: ${this._peers.size}, queue size: ${ this._peersQueue.length - }, open slots: ${this._getOpenSlots()}` + }, open slots: ${this._getOpenSlots()}`, ) } } diff --git a/packages/devp2p/src/util.ts b/packages/devp2p/src/util.ts index 746cece35e..e1de5db726 100644 --- a/packages/devp2p/src/util.ts +++ b/packages/devp2p/src/util.ts @@ -46,7 +46,7 @@ export function assertEq( actual: assertInput, msg: string, debug: Function, - messageName?: string + messageName?: string, ): void { let fullMsg diff --git a/packages/devp2p/test/dns.spec.ts b/packages/devp2p/test/dns.spec.ts index bee07a82a7..1b6f434ed0 100644 --- a/packages/devp2p/test/dns.spec.ts +++ b/packages/devp2p/test/dns.spec.ts @@ -174,6 +174,6 @@ describe('DNS: (integration)', () => { seen.push(peer!.address as string) } }, - { timeout: 10000 } + { timeout: 10000 }, ) }) diff --git a/packages/devp2p/test/dpt-message.spec.ts b/packages/devp2p/test/dpt-message.spec.ts index a5ed1ca801..b5c4cdf38e 100644 --- a/packages/devp2p/test/dpt-message.spec.ts +++ b/packages/devp2p/test/dpt-message.spec.ts @@ -9,7 +9,7 @@ const publicKey = publicKeyCreate(privateKey, false) describe('DPT message tests', () => { it('ping packet with version 4, additional list elements', () => { const bytes = hexToBytes( - '0xe9614ccfd9fc3e74360018522d30e1419a143407ffcce748de3e22116b7e8dc92ff74788c0b6663aaa3d67d641936511c8f8d6ad8698b820a7cf9e1be7155e9a241f556658c55428ec0563514365799a4be2be5a685a80971ddcfa80cb422cdd0101ec04cb847f000001820cfa8215a8d790000000000000000000000000000000018208ae820d058443b9a3550102' + '0xe9614ccfd9fc3e74360018522d30e1419a143407ffcce748de3e22116b7e8dc92ff74788c0b6663aaa3d67d641936511c8f8d6ad8698b820a7cf9e1be7155e9a241f556658c55428ec0563514365799a4be2be5a685a80971ddcfa80cb422cdd0101ec04cb847f000001820cfa8215a8d790000000000000000000000000000000018208ae820d058443b9a3550102', ) const msg = message.decode(bytes) @@ -20,7 +20,7 @@ describe('DPT message tests', () => { it('ping packet with version 555, additional list elements and additional random data:', () => { const bytes = hexToBytes( - '0x577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3' + '0x577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3', ) const msg = message.decode(bytes) @@ -31,7 +31,7 @@ describe('DPT message tests', () => { it('pong packet with additional list elements and additional random data', () => { const bytes = hexToBytes( - '0x09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b2069869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f055542124e' + '0x09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b2069869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f055542124e', ) const msg = message.decode(bytes) @@ -41,7 +41,7 @@ describe('DPT message tests', () => { it('findnode packet with additional list elements and additional random data', () => { const bytes = hexToBytes( - '0xc7c44041b9f7c7e41934417ebac9a8e1a4c6298f74553f2fcfdcae6ed6fe53163eb3d2b52e39fe91831b8a927bf4fc222c3902202027e5e9eb812195f95d20061ef5cd31d502e47ecb61183f74a504fe04c51e73df81f25c4d506b26db4517490103f84eb840ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f8443b9a35582999983999999280dc62cc8255c73471e0a61da0c89acdc0e035e260add7fc0c04ad9ebf3919644c91cb247affc82b69bd2ca235c71eab8e49737c937a2c396' + '0xc7c44041b9f7c7e41934417ebac9a8e1a4c6298f74553f2fcfdcae6ed6fe53163eb3d2b52e39fe91831b8a927bf4fc222c3902202027e5e9eb812195f95d20061ef5cd31d502e47ecb61183f74a504fe04c51e73df81f25c4d506b26db4517490103f84eb840ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f8443b9a35582999983999999280dc62cc8255c73471e0a61da0c89acdc0e035e260add7fc0c04ad9ebf3919644c91cb247affc82b69bd2ca235c71eab8e49737c937a2c396', ) const msg = message.decode(bytes) @@ -51,7 +51,7 @@ describe('DPT message tests', () => { it('neighbours packet with additional list elements and additional random data', () => { const bytes = hexToBytes( - '0xc679fc8fe0b8b12f06577f2e802d34f6fa257e6137a995f6f4cbfc9ee50ed3710faf6e66f932c4c8d81d64343f429651328758b47d3dbc02c4042f0fff6946a50f4a49037a72bb550f3a7872363a83e1b9ee6469856c24eb4ef80b7535bcf99c0004f9015bf90150f84d846321163782115c82115db8403155e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa829115d224c523596b401065a97f74010610fce76382c0bf32f84984010203040101b840312c55512422cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e829f04c2d314fc2d4e255e0d3bc08792b069dbf8599020010db83c4d001500000000abcdef12820d05820d05b84038643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aacf8599020010db885a308d313198a2e037073488203e78203e8b8408dcab8618c3253b558d459da53bd8fa68935a719aff8b811197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df738443b9a355010203b525a138aa34383fec3d2719a0' + '0xc679fc8fe0b8b12f06577f2e802d34f6fa257e6137a995f6f4cbfc9ee50ed3710faf6e66f932c4c8d81d64343f429651328758b47d3dbc02c4042f0fff6946a50f4a49037a72bb550f3a7872363a83e1b9ee6469856c24eb4ef80b7535bcf99c0004f9015bf90150f84d846321163782115c82115db8403155e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa829115d224c523596b401065a97f74010610fce76382c0bf32f84984010203040101b840312c55512422cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e829f04c2d314fc2d4e255e0d3bc08792b069dbf8599020010db83c4d001500000000abcdef12820d05820d05b84038643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aacf8599020010db885a308d313198a2e037073488203e78203e8b8408dcab8618c3253b558d459da53bd8fa68935a719aff8b811197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df738443b9a355010203b525a138aa34383fec3d2719a0', ) const msg = message.decode(bytes) diff --git a/packages/devp2p/test/dpt.spec.ts b/packages/devp2p/test/dpt.spec.ts index 4f37791f5e..0e776e1483 100644 --- a/packages/devp2p/test/dpt.spec.ts +++ b/packages/devp2p/test/dpt.spec.ts @@ -11,7 +11,7 @@ describe('DPT', () => { }) const privateKey1 = hexToBytes( - '0x012e930448c53e0b73edbbbc433e8a741e978cda79be2be039905f538d6247c2' + '0x012e930448c53e0b73edbbbc433e8a741e978cda79be2be039905f538d6247c2', ) const peers: PeerInfo[] = [] @@ -56,7 +56,7 @@ describe('DPT', () => { assert.equal( dpt.getClosestPeers(peers[0].id!).length, 2, - 'should return all peers on getClosestPeers()' + 'should return all peers on getClosestPeers()', ) dpt.destroy() @@ -73,7 +73,7 @@ describe('DPT', () => { await dpt.refresh() expect( spy, - 'call findneighbours on unconfirmed if no confirmed peers yet' + 'call findneighbours on unconfirmed if no confirmed peers yet', ).toHaveBeenCalledTimes(1) dpt['_refreshIntervalSelectionCounter'] = 0 @@ -86,21 +86,21 @@ describe('DPT', () => { assert.equal( dpt.getClosestPeers(peers[0].id!).length, 1, - 'should not return unconfirmed on getClosestPeers()' + 'should not return unconfirmed on getClosestPeers()', ) dpt.confirmPeer('02') assert.equal( dpt.getClosestPeers(peers[0].id!).length, 2, - 'should return confirmed on getClosestPeers()' + 'should return confirmed on getClosestPeers()', ) dpt.removePeer(peers[1]) assert.equal( dpt.getClosestPeers(peers[0].id!).length, 1, - 'should work after peers being removed' + 'should work after peers being removed', ) dpt.destroy() diff --git a/packages/devp2p/test/enr.spec.ts b/packages/devp2p/test/enr.spec.ts index 01df40ac6d..60b1858740 100644 --- a/packages/devp2p/test/enr.spec.ts +++ b/packages/devp2p/test/enr.spec.ts @@ -19,7 +19,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes("ENR root entry must start with 'enrtree-root:'"), - 'has correct error message' + 'has correct error message', ) } }) @@ -30,7 +30,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes('Unable to verify ENR root signature'), - 'has correct error message' + 'has correct error message', ) } }) @@ -41,7 +41,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes("Could not parse 'l' value from ENR root entry"), - 'has correct error message' + 'has correct error message', ) } }) @@ -60,7 +60,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes("ENR tree entry must start with 'enrtree:'"), - 'has correct error message' + 'has correct error message', ) } }) @@ -71,7 +71,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes('Could not parse domain from ENR tree entry'), - 'has correct error message' + 'has correct error message', ) } }) @@ -94,7 +94,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes("ENR branch entry must start with 'enrtree-branch:'"), - 'has correct error message' + 'has correct error message', ) } }) @@ -121,7 +121,7 @@ describe('ENR tests', () => { } catch (e: any) { assert.ok( e.toString().includes("String encoded ENR must start with 'enr:'"), - 'has correct error message' + 'has correct error message', ) } }) diff --git a/packages/devp2p/test/integration/dpt-simulator.spec.ts b/packages/devp2p/test/integration/dpt-simulator.spec.ts index 0b2682effa..6bea867128 100644 --- a/packages/devp2p/test/integration/dpt-simulator.spec.ts +++ b/packages/devp2p/test/integration/dpt-simulator.spec.ts @@ -37,7 +37,7 @@ describe('DPT simulator tests', () => { assert.equal( dpts[0].getPeers().length, 0, - 'should have removed peer from k-bucket on peer:removed' + 'should have removed peer from k-bucket on peer:removed', ) await util.delay(500) util.destroyDPTs(dpts) @@ -60,7 +60,7 @@ describe('DPT simulator tests', () => { assert.equal( dpts[0].getPeers().length, 0, - 'should have removed peer from k-bucket on peer:removed' + 'should have removed peer from k-bucket on peer:removed', ) await util.delay(500) util.destroyDPTs(dpts) diff --git a/packages/devp2p/test/integration/eth-simulator.spec.ts b/packages/devp2p/test/integration/eth-simulator.spec.ts index 3a8d1847c5..9f49b08ff8 100644 --- a/packages/devp2p/test/integration/eth-simulator.spec.ts +++ b/packages/devp2p/test/integration/eth-simulator.spec.ts @@ -11,7 +11,7 @@ import type { Capabilities } from '../../src/index.js' const GENESIS_TD = 17179869184 const GENESIS_HASH = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) const capabilities = [devp2p.ETH.eth63, devp2p.ETH.eth62] @@ -98,7 +98,7 @@ describe('ETH simulator tests', () => { t: typeof it, version: number, cap: Capabilities[], - expectedCode: ETH.MESSAGE_CODES + expectedCode: ETH.MESSAGE_CODES, ) { await new Promise((resolve) => { const opts: any = {} @@ -142,7 +142,7 @@ describe('ETH simulator tests', () => { resolve(undefined) }) }) - } + }, ) it('ETH: send not-allowed eth67', async () => { diff --git a/packages/devp2p/test/integration/les-simulator.spec.ts b/packages/devp2p/test/integration/les-simulator.spec.ts index 93091ae10d..0b472ce954 100644 --- a/packages/devp2p/test/integration/les-simulator.spec.ts +++ b/packages/devp2p/test/integration/les-simulator.spec.ts @@ -8,7 +8,7 @@ import * as util from './util.js' const GENESIS_TD = 17179869184 const GENESIS_HASH = hexToBytes( - '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' + '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3', ) const capabilities = [devp2p.LES.les4] diff --git a/packages/devp2p/test/integration/rlpx-simulator.spec.ts b/packages/devp2p/test/integration/rlpx-simulator.spec.ts index e958b39221..b35bccdc2e 100644 --- a/packages/devp2p/test/integration/rlpx-simulator.spec.ts +++ b/packages/devp2p/test/integration/rlpx-simulator.spec.ts @@ -14,7 +14,7 @@ describe('RLPx simulator tests', () => { assert.equal( peer._port, basePort + 1, - 'should have added peer on peer:added after successful handshake' + 'should have added peer on peer:added after successful handshake', ) assert.equal(rlpxs[0].getPeers().length, 1, 'peer list length should be 1') assert.equal(rlpxs[0]._getOpenSlots(), 9, 'should have maxPeers - 1 open slots left') @@ -35,12 +35,12 @@ describe('RLPx simulator tests', () => { } assert.notOk( rlpxs[0]['_dpt']!['_banlist'].has(peer), - 'should not be in ban list before bad peer discovered' + 'should not be in ban list before bad peer discovered', ) rlpxs[0]['_dpt']!.events.emit('peer:new', peer) assert.ok( rlpxs[0]['_dpt']!['_banlist'].has(peer), - 'should be in ban list after bad peer discovered' + 'should be in ban list after bad peer discovered', ) await util.delay(500) util.destroyRLPXs(rlpxs) @@ -58,7 +58,7 @@ describe('RLPx simulator tests', () => { assert.equal( reason, DISCONNECT_REASON.CLIENT_QUITTING, - 'should close with CLIENT_QUITTING disconnect reason' + 'should close with CLIENT_QUITTING disconnect reason', ) assert.equal(rlpxs[0]._getOpenSlots(), 10, 'should have maxPeers open slots left') await util.delay(500) diff --git a/packages/devp2p/test/integration/util.ts b/packages/devp2p/test/integration/util.ts index 6ebef037a6..ac35ccd51a 100644 --- a/packages/devp2p/test/integration/util.ts +++ b/packages/devp2p/test/integration/util.ts @@ -72,7 +72,7 @@ export function getTestRLPXs( maxPeers: number = 10, basePort: number, capabilities?: Capabilities[], - common?: Object | Common + common?: Object | Common, ) { const rlpxs = [] if (typeof capabilities === 'undefined') { @@ -101,7 +101,7 @@ export function initTwoPeerRLPXSetup( maxPeers?: any, capabilities?: any, common?: Object | Common, - basePort = 30306 + basePort = 30306, ): RLPx[] { const rlpxs = getTestRLPXs(2, maxPeers, basePort, capabilities, common) const peer = { address: localhost, udpPort: basePort + 1, tcpPort: basePort + 1 } @@ -128,7 +128,7 @@ export function twoPeerMsgExchange( opts: any, capabilities?: Capabilities[], common?: Object | Common, - basePort = 30306 + basePort = 30306, ) { const rlpxs = initTwoPeerRLPXSetup(null, capabilities, common, basePort) rlpxs[0].events.on('peer:added', function (peer: any) { @@ -190,7 +190,7 @@ export async function twoPeerMsgExchange2( opts: any, capabilities?: any, common?: Object | Common, - basePort = 30306 + basePort = 30306, ) { const rlpxs = initTwoPeerRLPXSetup(null, capabilities, common, basePort) rlpxs[0].events.on('peer:added', function (peer: any) { @@ -223,7 +223,7 @@ export async function twoPeerMsgExchange2( assert.equal( err.message, 'Invalid Snappy bitstream', - 'unable to process snappy compressed message' + 'unable to process snappy compressed message', ) destroyRLPXs(rlpxs) opts.promise(undefined) @@ -245,7 +245,7 @@ export function twoPeerMsgExchange3( opts: any, capabilities?: any, common?: Object | Common, - basePort = 30306 + basePort = 30306, ) { const rlpxs = initTwoPeerRLPXSetup(null, capabilities, common, basePort) rlpxs[0].events.on('peer:added', function (peer: any) { diff --git a/packages/devp2p/test/rlpx-ecies.spec.ts b/packages/devp2p/test/rlpx-ecies.spec.ts index fc67c63fbf..4e857a477f 100644 --- a/packages/devp2p/test/rlpx-ecies.spec.ts +++ b/packages/devp2p/test/rlpx-ecies.spec.ts @@ -64,7 +64,7 @@ it( const encrypted = t.context.a._encryptMessage(message) const decrypted = t.context.b._decryptMessage(encrypted as Uint8Array) assert.deepEqual(message, decrypted, 'encryptMessage -> decryptMessage should lead to same') - }) + }), ) it( @@ -89,7 +89,7 @@ it( const parsedBody = t.context.b.parseBody(t.context.a.createBody(body) as Uint8Array) assert.deepEqual(parsedBody, body, 'createBody -> parseBody should lead to same') - }) + }), ) it( @@ -106,7 +106,7 @@ it( t.context.a['_gotEIP8Ack'] = true t.context.a.parseAckEIP8(ack as Uint8Array) }, 'should not throw on ack creation/parsing') - }) + }), ) it( @@ -122,7 +122,7 @@ it( t.context.a['_gotEIP8Ack'] = false t.context.a.parseAckPlain(t.context.h0?.ack as Uint8Array) }, 'should not throw on ack parsing') - }) + }), ) it( @@ -137,5 +137,5 @@ it( t.context.a['_gotEIP8Ack'] = true t.context.a.parseAckEIP8(t.context.h1?.ack as Uint8Array) }, 'should not throw on ack parsing') - }) + }), ) diff --git a/packages/devp2p/test/rlpx.spec.ts b/packages/devp2p/test/rlpx.spec.ts index 457bab846e..0978ee8154 100644 --- a/packages/devp2p/test/rlpx.spec.ts +++ b/packages/devp2p/test/rlpx.spec.ts @@ -165,12 +165,12 @@ describe('RLPx', () => { assert.equal( rlpx['_getOpenSlots'](), 10, - 'returns default number of open slots (i.e. `max_peers`) on startup' + 'returns default number of open slots (i.e. `max_peers`) on startup', ) assert.equal( rlpx['_getOpenQueueSlots'](), 20, - 'returns default number of open queue slots on startup' + 'returns default number of open queue slots on startup', ) }) }) diff --git a/packages/devp2p/tsconfig.lint.json b/packages/devp2p/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/devp2p/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/ethash/.eslintrc.cjs b/packages/ethash/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/ethash/.eslintrc.cjs +++ b/packages/ethash/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/ethash/examples/example.ts b/packages/ethash/examples/example.ts index 28461ba38f..983a4007bf 100644 --- a/packages/ethash/examples/example.ts +++ b/packages/ethash/examples/example.ts @@ -1,4 +1,5 @@ import { bytesToHex, hexToBytes } from '@ethereumjs/util' + import { Ethash } from '../dist/cjs/index.js' const ethash = new Ethash() diff --git a/packages/ethash/examples/miner.ts b/packages/ethash/examples/miner.ts index ab783d6d60..c4f294b8c0 100644 --- a/packages/ethash/examples/miner.ts +++ b/packages/ethash/examples/miner.ts @@ -1,6 +1,8 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Ethash } from '@ethereumjs/ethash' -import { DBObject, MapDB, bytesToHex } from '@ethereumjs/util' +import { MapDB, bytesToHex } from '@ethereumjs/util' + +import type { DBObject } from '@ethereumjs/util' const block = createBlockFromBlockData( { @@ -9,7 +11,7 @@ const block = createBlockFromBlockData( number: BigInt(1), }, }, - { setHardfork: true, skipConsensusFormatValidation: true } + { setHardfork: true, skipConsensusFormatValidation: true }, ) const cacheDB = new MapDB() diff --git a/packages/ethash/examples/powBlock.ts b/packages/ethash/examples/powBlock.ts index fcd54323c0..f9bbce1a4e 100644 --- a/packages/ethash/examples/powBlock.ts +++ b/packages/ethash/examples/powBlock.ts @@ -1,6 +1,8 @@ -import { Ethash } from '@ethereumjs/ethash' import { createBlockFromRLPSerializedBlock } from '@ethereumjs/block' -import { DBObject, hexToBytes, MapDB } from '@ethereumjs/util' +import { Ethash } from '@ethereumjs/ethash' +import { MapDB, hexToBytes } from '@ethereumjs/util' + +import type { DBObject } from '@ethereumjs/util' const cacheDB = new MapDB() diff --git a/packages/ethash/examples/rawExample.ts b/packages/ethash/examples/rawExample.ts index 3046119e2c..67f0f44727 100644 --- a/packages/ethash/examples/rawExample.ts +++ b/packages/ethash/examples/rawExample.ts @@ -1,5 +1,8 @@ +import { MapDB, bytesToHex, hexToBytes } from '@ethereumjs/util' + import { Ethash } from '../dist/cjs/index.js' -import { DBObject, MapDB, bytesToHex, hexToBytes } from '@ethereumjs/util' + +import type { DBObject } from '@ethereumjs/util' const ethash = new Ethash(new MapDB()) @@ -7,7 +10,7 @@ const verifySubmit = async ( ethash: Ethash, number: number, headerHash: Uint8Array, - nonce: Uint8Array + nonce: Uint8Array, ): Promise => { console.log('Verifying number: ', number) await ethash.loadEpoc(BigInt(number)) @@ -20,6 +23,6 @@ const verifySubmit = async ( const headerHash = hexToBytes('0x0e2887aa1a0668bf8254d1a6ae518927de99e3e5d7f30fd1f16096e2608fe05e') const nonce = hexToBytes('0xe360b6170c229d15') -verifySubmit(ethash, 35414, headerHash, nonce).then((result) => { +void verifySubmit(ethash, 35414, headerHash, nonce).then((result) => { console.log('Result: ', bytesToHex(result)) }) diff --git a/packages/ethash/src/index.ts b/packages/ethash/src/index.ts index 31b8157c8d..0f2f274e48 100644 --- a/packages/ethash/src/index.ts +++ b/packages/ethash/src/index.ts @@ -227,7 +227,7 @@ export class Ethash { const p = (fnv( i ^ new DataView(s.buffer).getUint32(0, true), - new DataView(mix.buffer).getUint32((i % w) * 4, true) + new DataView(mix.buffer).getUint32((i % w) * 4, true), ) % Math.floor(n / mixhashes)) * mixhashes @@ -344,7 +344,7 @@ export class Ethash { { keyEncoding: KeyEncoding.Number, valueEncoding: ValueEncoding.JSON, - } + }, ) } else { this.cache = data.cache.map((a: Uint8Array) => { diff --git a/packages/ethash/src/util.ts b/packages/ethash/src/util.ts index eae06d2a0b..43c261c450 100644 --- a/packages/ethash/src/util.ts +++ b/packages/ethash/src/util.ts @@ -66,7 +66,7 @@ export function fnvBytes(a: Uint8Array, b: Uint8Array) { rView.setUint32( i, fnv(new DataView(a.buffer).getUint32(i, true), new DataView(b.buffer).getUint32(i, true)), - true + true, ) } return r diff --git a/packages/ethash/test/miner.spec.ts b/packages/ethash/test/miner.spec.ts index 493245da5b..3f69b95a33 100644 --- a/packages/ethash/test/miner.spec.ts +++ b/packages/ethash/test/miner.spec.ts @@ -22,7 +22,7 @@ describe('Miner', () => { number: BigInt(1), }, }, - { common } + { common }, ) const invalidBlockResult = await e.verifyPOW(block) @@ -46,7 +46,7 @@ describe('Miner', () => { mixHash: solution?.mixHash, }, }, - { common } + { common }, ) const validBlockResult = await e.verifyPOW(validBlock) @@ -64,14 +64,14 @@ describe('Miner', () => { number: BigInt(1), }, }, - { common } + { common }, ) const miner = e.getMiner(block.header) const solution = await miner.mine(-1) assert.ok( e.verifyPOW(createBlockFromBlockData({ header: solution.toJSON() }, { common })), - 'successfully mined block' + 'successfully mined block', ) const blockMiner = e.getMiner(block) @@ -90,7 +90,7 @@ describe('Miner', () => { number: BigInt(1), }, }, - { common } + { common }, ) const miner = e.getMiner(block.header) setTimeout(function () { @@ -111,7 +111,7 @@ describe('Miner', () => { }, undefined, undefined, - 'miner constructor successfully throws if no BlockHeader or Block object is passed' + 'miner constructor successfully throws if no BlockHeader or Block object is passed', ) }) @@ -127,7 +127,7 @@ describe('Miner', () => { }, { common, - } + }, ) const miner = e.getMiner(block.header) diff --git a/packages/ethash/tsconfig.lint.json b/packages/ethash/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/ethash/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/evm/.eslintrc.cjs b/packages/evm/.eslintrc.cjs index 965b6e94e6..10790297fc 100644 --- a/packages/evm/.eslintrc.cjs +++ b/packages/evm/.eslintrc.cjs @@ -7,9 +7,10 @@ module.exports = { }, overrides: [ { - files: ['test/util.ts', 'test/tester/**/*.ts'], + files: ['test/util.ts', 'test/tester/**/*.ts', 'examples/**/*.ts'], rules: { 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', }, }, ], diff --git a/packages/evm/examples/4844.ts b/packages/evm/examples/4844.ts index 180bf1d2a5..5c4944fae7 100644 --- a/packages/evm/examples/4844.ts +++ b/packages/evm/examples/4844.ts @@ -1,3 +1,3 @@ -import { Common, Chain, Hardfork } from '@ethereumjs/common' +import { Chain, Common, Hardfork } from '@ethereumjs/common' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai, eips: [4844] }) diff --git a/packages/evm/examples/decode-opcodes.ts b/packages/evm/examples/decode-opcodes.ts index ff551679e3..b138bd529d 100644 --- a/packages/evm/examples/decode-opcodes.ts +++ b/packages/evm/examples/decode-opcodes.ts @@ -4,6 +4,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { bytesToHex, hexToBytes } from '@ethereumjs/util' + import { getOpcodesForHF } from '../dist/cjs/opcodes/index.js' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) @@ -33,7 +34,7 @@ function nameOpCodes(raw: Uint8Array) { ' ' + curOpCode + ' ' + - (pushData?.length > 0 ? bytesToHex(pushData as Uint8Array) : '') + (pushData?.length > 0 ? bytesToHex(pushData as Uint8Array) : ''), ) pushData = new Uint8Array() diff --git a/packages/evm/examples/eips.ts b/packages/evm/examples/eips.ts index 09b0986e1c..878373118c 100644 --- a/packages/evm/examples/eips.ts +++ b/packages/evm/examples/eips.ts @@ -1,5 +1,5 @@ import { Chain, Common } from '@ethereumjs/common' -import { createEVM, EVM } from '@ethereumjs/evm' +import { createEVM } from '@ethereumjs/evm' const main = async () => { const common = new Common({ chain: Chain.Mainnet, eips: [3074] }) @@ -7,4 +7,4 @@ const main = async () => { console.log(`EIP 3074 is active - ${evm.common.isActivatedEIP(3074)}`) } -main() +void main() diff --git a/packages/evm/examples/runCode.ts b/packages/evm/examples/runCode.ts index 901cf97c80..2c9643f580 100644 --- a/packages/evm/examples/runCode.ts +++ b/packages/evm/examples/runCode.ts @@ -1,8 +1,10 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { createEVM, EVM } from '@ethereumjs/evm' +import { createEVM } from '@ethereumjs/evm' import { bytesToHex, hexToBytes } from '@ethereumjs/util' +import type { PrefixedHexString } from '@ethereumjs/util' + const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const blockchain = await createBlockchain() @@ -26,7 +28,7 @@ const main = async () => { evm .runCode({ - code: hexToBytes('0x' + code.join('')), + code: hexToBytes(('0x' + code.join('')) as PrefixedHexString), gasLimit: BigInt(0xffff), }) .then((results) => { diff --git a/packages/evm/examples/simple.ts b/packages/evm/examples/simple.ts index 9600f3b5e7..66cf71b510 100644 --- a/packages/evm/examples/simple.ts +++ b/packages/evm/examples/simple.ts @@ -1,5 +1,5 @@ +import { createEVM } from '@ethereumjs/evm' import { hexToBytes } from '@ethereumjs/util' -import { createEVM, EVM } from '@ethereumjs/evm' const main = async () => { const evm = await createEVM() @@ -7,4 +7,4 @@ const main = async () => { console.log(res.executionGasUsed) // 3n } -main() +void main() diff --git a/packages/evm/examples/withBlockchain.ts b/packages/evm/examples/withBlockchain.ts index 6b046cd466..b7370658c9 100644 --- a/packages/evm/examples/withBlockchain.ts +++ b/packages/evm/examples/withBlockchain.ts @@ -1,8 +1,10 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { createEVM, EVM } from '@ethereumjs/evm' +import { createEVM } from '@ethereumjs/evm' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { bytesToHex } from '@ethereumjs/util' +import { bytesToHex, hexToBytes } from '@ethereumjs/util' + +import type { PrefixedHexString } from '@ethereumjs/util' const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) @@ -28,7 +30,7 @@ const main = async () => { }) const results = await evm.runCode({ - code: Buffer.from(code.join(''), 'hex'), + code: hexToBytes(('0x' + code.join('')) as PrefixedHexString), gasLimit: BigInt(0xffff), }) diff --git a/packages/evm/src/eof/container.ts b/packages/evm/src/eof/container.ts index 7a60e1f141..a2be68d86c 100644 --- a/packages/evm/src/eof/container.ts +++ b/packages/evm/src/eof/container.ts @@ -290,7 +290,7 @@ class EOFBody { buf: Uint8Array, // The buffer of the body. This should be the entire body. It is not valid to pass an entire EOF container in here header: EOFHeader, // The EOFHeader corresponding to this body eofMode: EOFContainerMode = EOFContainerMode.Default, // The container mode of EOF - dataSectionAllowedSmaller = false // Only for validation: Deployment containers are allowed to have smaller data section size + dataSectionAllowedSmaller = false, // Only for validation: Deployment containers are allowed to have smaller data section size ) { const stream = new StreamReader(buf) const typeSections: TypeSection[] = [] @@ -415,7 +415,7 @@ export class EOFContainer { constructor( buf: Uint8Array, eofMode: EOFContainerMode = EOFContainerMode.Default, - dataSectionAllowedSmaller = false + dataSectionAllowedSmaller = false, ) { this.eofMode = eofMode this.header = new EOFHeader(buf) @@ -423,7 +423,7 @@ export class EOFContainer { buf.slice(this.header.buffer.length), this.header, eofMode, - dataSectionAllowedSmaller + dataSectionAllowedSmaller, ) this.buffer = buf } @@ -443,12 +443,12 @@ export function validateEOF( input: Uint8Array, evm: EVM, containerMode: ContainerSectionType = ContainerSectionType.RuntimeCode, - eofMode: EOFContainerMode = EOFContainerMode.Default + eofMode: EOFContainerMode = EOFContainerMode.Default, ) { const container = new EOFContainer( input, eofMode, - containerMode === ContainerSectionType.DeploymentCode + containerMode === ContainerSectionType.DeploymentCode, ) const containerMap = verifyCode(container, evm, containerMode) // Recursively validate the containerSections diff --git a/packages/evm/src/eof/verify.ts b/packages/evm/src/eof/verify.ts index 00537f1eb0..988f1adc04 100644 --- a/packages/evm/src/eof/verify.ts +++ b/packages/evm/src/eof/verify.ts @@ -41,7 +41,7 @@ export enum ContainerSectionType { export function verifyCode( container: EOFContainer, evm: EVM, - mode: ContainerSectionType = ContainerSectionType.RuntimeCode + mode: ContainerSectionType = ContainerSectionType.RuntimeCode, ) { return validateOpcodes(container, evm, mode) } @@ -58,7 +58,7 @@ function readUint16(code: Uint8Array, start: number) { function validateOpcodes( container: EOFContainer, evm: EVM, - mode: ContainerSectionType = ContainerSectionType.RuntimeCode + mode: ContainerSectionType = ContainerSectionType.RuntimeCode, ) { // Track the intermediate bytes const intermediateBytes = new Set() diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index 1d1ac85bac..ff85812b00 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -179,7 +179,7 @@ export class EVM implements EVMInterface { if (!EVM.supportedHardforks.includes(this.common.hardfork() as Hardfork)) { throw new Error( - `Hardfork ${this.common.hardfork()} not set as supported in supportedHardforks` + `Hardfork ${this.common.hardfork()} not set as supported in supportedHardforks`, ) } @@ -214,7 +214,7 @@ export class EVM implements EVMInterface { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } /** @@ -282,13 +282,13 @@ export class EVM implements EVMInterface { if (!toAccount) { if (this.common.isActivatedEIP(6800)) { const absenceProofAccessGas = message.accessWitness!.touchAndChargeProofOfAbsence( - message.to + message.to, ) gasLimit -= absenceProofAccessGas if (gasLimit < BIGINT_0) { if (this.DEBUG) { debugGas( - `Proof of absense access charged(${absenceProofAccessGas}) caused OOG (-> ${gasLimit})` + `Proof of absense access charged(${absenceProofAccessGas}) caused OOG (-> ${gasLimit})`, ) } return { execResult: OOGResult(message.gasLimit) } @@ -429,13 +429,13 @@ export class EVM implements EVMInterface { if (this.common.isActivatedEIP(6800)) { const contractCreateAccessGas = message.accessWitness!.touchAndChargeContractCreateInit( - message.to + message.to, ) gasLimit -= contractCreateAccessGas if (gasLimit < BIGINT_0) { if (this.DEBUG) { debugGas( - `ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})` + `ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`, ) } return { execResult: OOGResult(message.gasLimit) } @@ -518,13 +518,13 @@ export class EVM implements EVMInterface { if (gasLimit < BIGINT_0) { if (this.DEBUG) { debug( - `ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})` + `ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`, ) } return { execResult: OOGResult(message.gasLimit) } } else { debug( - `ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})` + `ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`, ) } } @@ -627,19 +627,19 @@ export class EVM implements EVMInterface { gasLimit = message.gasLimit - result.executionGasUsed if (!result.exceptionError && this.common.isActivatedEIP(6800)) { const createCompleteAccessGas = message.accessWitness!.touchAndChargeContractCreateCompleted( - message.to + message.to, ) gasLimit -= createCompleteAccessGas if (gasLimit < BIGINT_0) { if (this.DEBUG) { debug( - `ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})` + `ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`, ) } result = { ...result, ...OOGResult(message.gasLimit) } } else { debug( - `ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})` + `ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`, ) result.executionGasUsed += createCompleteAccessGas } @@ -657,13 +657,13 @@ export class EVM implements EVMInterface { message.accessWitness!.touchCodeChunksRangeOnWriteAndChargeGas( message.to, 0, - result.returnValue.length - 1 + result.returnValue.length - 1, ) gasLimit -= byteCodeWriteAccessfee if (gasLimit < BIGINT_0) { if (this.DEBUG) { debug( - `byteCodeWrite access gas (${byteCodeWriteAccessfee}) caused OOG (-> ${gasLimit})` + `byteCodeWrite access gas (${byteCodeWriteAccessfee}) caused OOG (-> ${gasLimit})`, ) } result = { ...result, ...OOGResult(message.gasLimit) } @@ -700,7 +700,7 @@ export class EVM implements EVMInterface { */ protected async runInterpreter( message: Message, - opts: InterpreterOpts = {} + opts: InterpreterOpts = {}, ): Promise { let contract = await this.stateManager.getAccount(message.to ?? Address.zero()) if (!contract) { @@ -736,7 +736,7 @@ export class EVM implements EVMInterface { message.gasLimit, this.journal, this.performanceLogger, - this._optsCached.profiler + this._optsCached.profiler, ) if (message.selfdestruct) { interpreter._result.selfdestruct = message.selfdestruct @@ -870,7 +870,7 @@ export class EVM implements EVMInterface { debug( `New message caller=${caller} gasLimit=${gasLimit} to=${ to?.toString() ?? 'none' - } value=${value} delegatecall=${delegatecall ? 'yes' : 'no'}` + } value=${value} delegatecall=${delegatecall ? 'yes' : 'no'}`, ) } if (message.to) { @@ -889,7 +889,7 @@ export class EVM implements EVMInterface { debug( `Received message execResult: [ gasUsed=${executionGasUsed} exceptionError=${ exceptionError ? `'${exceptionError.error}'` : 'none' - } returnValue=${short(returnValue)} gasRefund=${result.execResult.gasRefund ?? 0} ]` + } returnValue=${short(returnValue)} gasRefund=${result.execResult.gasRefund ?? 0} ]`, ) } const err = result.execResult.exceptionError @@ -971,7 +971,7 @@ export class EVM implements EVMInterface { protected runPrecompile( code: PrecompileFunc, data: Uint8Array, - gasLimit: bigint + gasLimit: bigint, ): Promise | ExecResult { if (typeof code !== 'function') { throw new Error('Invalid precompile') diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 2c9715f9f5..8e2516b124 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -153,7 +153,7 @@ export class Interpreter { gasLeft: bigint, journal: Journal, performanceLogs: EVMPerformanceLogger, - profilerOpts?: EVMProfilerOpts + profilerOpts?: EVMProfilerOpts, ) { this._evm = evm this._stateManager = stateManager @@ -228,7 +228,7 @@ export class Interpreter { this._runState.code, this._evm, ContainerSectionType.InitCode, - EOFContainerMode.TxInitmode + EOFContainerMode.TxInitmode, ) } catch (e) { // Trying to deploy an invalid EOF container @@ -360,7 +360,7 @@ export class Interpreter { this._runState.env.accessWitness!.touchCodeChunksRangeOnReadAndChargeGas( contract, this._runState.programCounter, - this._runState.programCounter + this._runState.programCounter, ) gas += statelessGas debugGas(`codechunk accessed statelessGas=${statelessGas} (-> ${gas})`) @@ -398,7 +398,7 @@ export class Interpreter { Number(gas), 'opcodes', opInfo.fee, - Number(gas) - opInfo.fee + Number(gas) - opInfo.fee, ) } } @@ -543,7 +543,7 @@ export class Interpreter { debugGas( `${typeof context === 'string' ? context + ': ' : ''}refund ${amount} gas (-> ${ this._runState.gasRefund - })` + })`, ) } this._runState.gasRefund += amount @@ -559,7 +559,7 @@ export class Interpreter { debugGas( `${typeof context === 'string' ? context + ': ' : ''}sub gas refund ${amount} (-> ${ this._runState.gasRefund - })` + })`, ) } this._runState.gasRefund -= amount @@ -874,7 +874,7 @@ export class Interpreter { gasLimit: bigint, address: Address, value: bigint, - data: Uint8Array + data: Uint8Array, ): Promise { const msg = new Message({ caller: this._runState.auth, @@ -899,7 +899,7 @@ export class Interpreter { gasLimit: bigint, address: Address, value: bigint, - data: Uint8Array + data: Uint8Array, ): Promise { const msg = new Message({ caller: this._env.address, @@ -926,7 +926,7 @@ export class Interpreter { gasLimit: bigint, address: Address, value: bigint, - data: Uint8Array + data: Uint8Array, ): Promise { const msg = new Message({ caller: this._env.address, @@ -951,7 +951,7 @@ export class Interpreter { gasLimit: bigint, address: Address, value: bigint, - data: Uint8Array + data: Uint8Array, ): Promise { const msg = new Message({ caller: this._env.caller, @@ -1042,7 +1042,7 @@ export class Interpreter { value: bigint, codeToRun: Uint8Array, salt?: Uint8Array, - eofCallData?: Uint8Array + eofCallData?: Uint8Array, ): Promise { const selfdestruct = new Set(this._result.selfdestruct) const caller = this._env.address @@ -1150,7 +1150,7 @@ export class Interpreter { gasLimit: bigint, value: bigint, data: Uint8Array, - salt: Uint8Array + salt: Uint8Array, ): Promise { return this.create(gasLimit, value, data, salt) } @@ -1164,7 +1164,7 @@ export class Interpreter { value: bigint, containerData: Uint8Array, salt: Uint8Array, - callData: Uint8Array + callData: Uint8Array, ): Promise { return this.create(gasLimit, value, containerData, salt, callData) } diff --git a/packages/evm/src/journal.ts b/packages/evm/src/journal.ts index 60dad80bd3..9c17a3e861 100644 --- a/packages/evm/src/journal.ts +++ b/packages/evm/src/journal.ts @@ -51,7 +51,7 @@ export class Journal { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this._debug = debugDefault('statemanager:statemanager') @@ -100,7 +100,7 @@ export class Journal { const bytesAddress = unprefixedHexToBytes(address) if (this.stateManager.getAppliedKey === undefined) { throw new Error( - 'touchAccount: stateManager.getAppliedKey can not be undefined if preimage storing is enabled' + 'touchAccount: stateManager.getAppliedKey can not be undefined if preimage storing is enabled', ) } const hashedKey = this.stateManager.getAppliedKey(bytesAddress) diff --git a/packages/evm/src/logger.ts b/packages/evm/src/logger.ts index cd81bba043..13f383e009 100644 --- a/packages/evm/src/logger.ts +++ b/packages/evm/src/logger.ts @@ -146,7 +146,7 @@ export class EVMPerformanceLogger { gasUsed: number, targetTimer: 'precompiles' | 'opcodes' = 'opcodes', staticGas?: number, - dynamicGas?: number + dynamicGas?: number, ) { if (this.currentTimer === undefined || this.currentTimer !== timer) { throw new Error('Cannot stop timer: another timer is already running') diff --git a/packages/evm/src/opcodes/EIP1283.ts b/packages/evm/src/opcodes/EIP1283.ts index 49a67a48c8..be1412d3f0 100644 --- a/packages/evm/src/opcodes/EIP1283.ts +++ b/packages/evm/src/opcodes/EIP1283.ts @@ -17,7 +17,7 @@ export function updateSstoreGasEIP1283( currentStorage: Uint8Array, originalStorage: Uint8Array, value: Uint8Array, - common: Common + common: Common, ) { if (equalsBytes(currentStorage, value)) { // If current value equals new value (this is a no-op), 200 gas is deducted. @@ -34,7 +34,7 @@ export function updateSstoreGasEIP1283( // If new value is 0, add 15000 gas to refund counter. runState.interpreter.refundGas( common.param('netSstoreClearRefundGas'), - 'EIP-1283 -> netSstoreClearRefund' + 'EIP-1283 -> netSstoreClearRefund', ) } // Otherwise, 5000 gas is deducted. @@ -47,13 +47,13 @@ export function updateSstoreGasEIP1283( // If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. runState.interpreter.subRefund( common.param('netSstoreClearRefundGas'), - 'EIP-1283 -> netSstoreClearRefund' + 'EIP-1283 -> netSstoreClearRefund', ) } else if (value.length === 0) { // If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. runState.interpreter.refundGas( common.param('netSstoreClearRefundGas'), - 'EIP-1283 -> netSstoreClearRefund' + 'EIP-1283 -> netSstoreClearRefund', ) } } @@ -63,13 +63,13 @@ export function updateSstoreGasEIP1283( // If original value is 0, add 19800 gas to refund counter. runState.interpreter.refundGas( common.param('netSstoreResetClearRefundGas'), - 'EIP-1283 -> netSstoreResetClearRefund' + 'EIP-1283 -> netSstoreResetClearRefund', ) } else { // Otherwise, add 4800 gas to refund counter. runState.interpreter.refundGas( common.param('netSstoreResetRefundGas'), - 'EIP-1283 -> netSstoreResetRefund' + 'EIP-1283 -> netSstoreResetRefund', ) } } diff --git a/packages/evm/src/opcodes/EIP2200.ts b/packages/evm/src/opcodes/EIP2200.ts index 50ee69ddd1..5f08305d09 100644 --- a/packages/evm/src/opcodes/EIP2200.ts +++ b/packages/evm/src/opcodes/EIP2200.ts @@ -23,7 +23,7 @@ export function updateSstoreGasEIP2200( originalStorage: Uint8Array, value: Uint8Array, key: Uint8Array, - common: Common + common: Common, ) { // Fail if not enough gas is left if (runState.interpreter.getGasLeft() <= common.param('sstoreSentryEIP2200Gas')) { @@ -44,7 +44,7 @@ export function updateSstoreGasEIP2200( if (value.length === 0) { runState.interpreter.refundGas( common.param('sstoreClearRefundEIP2200Gas'), - 'EIP-2200 -> sstoreClearRefundEIP2200' + 'EIP-2200 -> sstoreClearRefundEIP2200', ) } // Write existing slot @@ -55,13 +55,13 @@ export function updateSstoreGasEIP2200( // Recreate slot runState.interpreter.subRefund( common.param('sstoreClearRefundEIP2200Gas'), - 'EIP-2200 -> sstoreClearRefundEIP2200' + 'EIP-2200 -> sstoreClearRefundEIP2200', ) } else if (value.length === 0) { // Delete slot runState.interpreter.refundGas( common.param('sstoreClearRefundEIP2200Gas'), - 'EIP-2200 -> sstoreClearRefundEIP2200' + 'EIP-2200 -> sstoreClearRefundEIP2200', ) } } @@ -71,14 +71,14 @@ export function updateSstoreGasEIP2200( const sstoreInitRefund = common.param('sstoreInitRefundEIP2200Gas') runState.interpreter.refundGas( adjustSstoreGasEIP2929(runState, key, sstoreInitRefund, 'initRefund', common), - 'EIP-2200 -> initRefund' + 'EIP-2200 -> initRefund', ) } else { // Reset to original existing slot const sstoreCleanRefund = common.param('sstoreCleanRefundEIP2200Gas') runState.interpreter.refundGas( BigInt(adjustSstoreGasEIP2929(runState, key, sstoreCleanRefund, 'cleanRefund', common)), - 'EIP-2200 -> cleanRefund' + 'EIP-2200 -> cleanRefund', ) } } diff --git a/packages/evm/src/opcodes/EIP2929.ts b/packages/evm/src/opcodes/EIP2929.ts index 9812f45467..a82c17e700 100644 --- a/packages/evm/src/opcodes/EIP2929.ts +++ b/packages/evm/src/opcodes/EIP2929.ts @@ -18,7 +18,7 @@ export function accessAddressEIP2929( address: Uint8Array, common: Common, chargeGas = true, - isSelfdestructOrAuthcall = false + isSelfdestructOrAuthcall = false, ): bigint { if (!common.isActivatedEIP(2929)) return BIGINT_0 @@ -52,7 +52,7 @@ export function accessStorageEIP2929( key: Uint8Array, isSstore: boolean, common: Common, - chargeGas = true + chargeGas = true, ): bigint { if (!common.isActivatedEIP(2929)) return BIGINT_0 @@ -86,7 +86,7 @@ export function adjustSstoreGasEIP2929( key: Uint8Array, defaultCost: bigint, costName: string, - common: Common + common: Common, ): bigint { if (!common.isActivatedEIP(2929)) return defaultCost diff --git a/packages/evm/src/opcodes/codes.ts b/packages/evm/src/opcodes/codes.ts index dd3e2250d2..d7f51241b0 100644 --- a/packages/evm/src/opcodes/codes.ts +++ b/packages/evm/src/opcodes/codes.ts @@ -384,7 +384,7 @@ function createOpcodes(opcodes: OpcodeEntryFee): OpcodeList { code, fullName: getFullname(code, value.name), ...value, - }) + }), ) } return result @@ -448,7 +448,7 @@ export function getOpcodesForHF(common: Common, customOpcodes?: CustomOpcode[]): // Sanity checks if (code.opcodeName === undefined || code.baseFee === undefined) { throw new Error( - `Custom opcode ${code.opcode} does not have the required values: opcodeName and baseFee are required` + `Custom opcode ${code.opcode} does not have the required values: opcodeName and baseFee are required`, ) } const entry = { diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 7011f92273..5976f9381e 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -535,13 +535,13 @@ export const handlers: Map = new Map([ if (typeof runState.stateManager.getContractCodeSize === 'function') { size = BigInt( await runState.stateManager.getContractCodeSize( - new Address(addresstoBytes(addressBigInt)) - ) + new Address(addresstoBytes(addressBigInt)), + ), ) } else { size = BigInt( (await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt)))) - .length + .length, ) } @@ -556,7 +556,7 @@ export const handlers: Map = new Map([ if (dataLength !== BIGINT_0) { let code = await runState.stateManager.getContractCode( - new Address(addresstoBytes(addressBigInt)) + new Address(addresstoBytes(addressBigInt)), ) if (isEOF(code)) { @@ -613,7 +613,7 @@ export const handlers: Map = new Map([ const data = getDataSlice( runState.interpreter.getReturnData(), returnDataOffset, - dataLength + dataLength, ) const memOffsetNum = Number(memOffset) const lengthNum = Number(dataLength) @@ -650,7 +650,7 @@ export const handlers: Map = new Map([ } const historyAddress = new Address( - bigIntToAddressBytes(common.param('historyStorageAddress')) + bigIntToAddressBytes(common.param('historyStorageAddress')), ) const historyServeWindow = common.param('historyServeWindow') const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32) @@ -661,7 +661,7 @@ export const handlers: Map = new Map([ const statelessGas = runState.env.accessWitness!.touchAddressOnReadAndComputeGas( historyAddress, treeIndex, - subIndex + subIndex, ) runState.interpreter.useGas(statelessGas, `BLOCKHASH`) } @@ -957,7 +957,7 @@ export const handlers: Map = new Map([ const statelessGas = runState.env.accessWitness!.touchCodeChunksRangeOnReadAndChargeGas( contract, startOffset, - endOffset + endOffset, ) runState.interpreter.useGas(statelessGas, `PUSH`) } @@ -967,7 +967,7 @@ export const handlers: Map = new Map([ runState.programCounter += numToPush } else { const loaded = bytesToBigInt( - runState.code.subarray(runState.programCounter, runState.programCounter + numToPush) + runState.code.subarray(runState.programCounter, runState.programCounter + numToPush), ) runState.programCounter += numToPush runState.stack.push(loaded) @@ -1045,10 +1045,10 @@ export const handlers: Map = new Map([ trap(ERROR.INVALID_OPCODE) } const toLoad = Number( - bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 2)) + bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 2)), ) const data = bytesToBigInt( - runState.env.eof!.container.body.dataSection.subarray(toLoad, toLoad + 32) + runState.env.eof!.container.body.dataSection.subarray(toLoad, toLoad + 32), ) runState.stack.push(data) runState.programCounter += 2 @@ -1134,7 +1134,7 @@ export const handlers: Map = new Map([ const jumptableCase = runState.stack.pop() if (jumptableCase <= jumptableEntries) { const rjumpDest = new DataView(code.buffer).getInt16( - runState.programCounter + Number(jumptableCase) * 2 + runState.programCounter + Number(jumptableCase) * 2, ) runState.programCounter += jumptableSize + rjumpDest } else { @@ -1152,7 +1152,7 @@ export const handlers: Map = new Map([ trap(ERROR.INVALID_OPCODE) } const sectionTarget = bytesToInt( - runState.code.slice(runState.programCounter, runState.programCounter + 2) + runState.code.slice(runState.programCounter, runState.programCounter + 2), ) const stackItems = runState.stack.length const typeSection = runState.env.eof!.container.body.typeSections[sectionTarget] @@ -1196,7 +1196,7 @@ export const handlers: Map = new Map([ // (and also the return stack overflow check) // It is commented out here const sectionTarget = bytesToInt( - runState.code.slice(runState.programCounter, runState.programCounter + 2) + runState.code.slice(runState.programCounter, runState.programCounter + 2), ) const stackItems = runState.stack.length const typeSection = runState.env.eof!.container.body.typeSections[sectionTarget] @@ -1223,8 +1223,8 @@ export const handlers: Map = new Map([ const toDup = Number( bytesToBigInt( - runState.code.subarray(runState.programCounter, runState.programCounter + 1) - ) + runState.code.subarray(runState.programCounter, runState.programCounter + 1), + ), ) + 1 runState.stack.dup(toDup) runState.programCounter++ @@ -1241,8 +1241,8 @@ export const handlers: Map = new Map([ const toSwap = Number( bytesToBigInt( - runState.code.subarray(runState.programCounter, runState.programCounter + 1) - ) + runState.code.subarray(runState.programCounter, runState.programCounter + 1), + ), ) + 1 runState.stack.swap(toSwap) runState.programCounter++ @@ -1257,7 +1257,7 @@ export const handlers: Map = new Map([ trap(ERROR.INVALID_OPCODE) } const toExchange = Number( - bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 1)) + bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 1)), ) const n = (toExchange >> 4) + 1 const m = (toExchange & 0x0f) + 1 @@ -1295,7 +1295,7 @@ export const handlers: Map = new Map([ value, containerCode, setLengthLeft(bigIntToBytes(salt), 32), - data + data, ) runState.stack.push(ret) } @@ -1420,7 +1420,7 @@ export const handlers: Map = new Map([ gasLimit, value, data, - setLengthLeft(bigIntToBytes(salt), 32) + setLengthLeft(bigIntToBytes(salt), 32), ) runState.stack.push(ret) }, diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index 7d2bfe179e..dc0ad6e5bf 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -98,7 +98,7 @@ export const dynamicGasHandlers: Map gasLimit) { @@ -987,7 +987,7 @@ export const dynamicGasHandlers: Map BIGINT_0) { gas += runState.env.accessWitness!.touchAddressOnWriteAndComputeGas( contractAddress, 0, - VERKLE_BALANCE_LEAF_KEY + VERKLE_BALANCE_LEAF_KEY, ) } @@ -1121,14 +1121,14 @@ export const dynamicGasHandlers: Map BIGINT_0) { selfDestructToColdAccessGas += runState.env.accessWitness!.touchAddressOnWriteAndComputeGas( selfdestructToAddress, 0, - VERKLE_BALANCE_LEAF_KEY + VERKLE_BALANCE_LEAF_KEY, ) } @@ -1142,7 +1142,7 @@ export const dynamicGasHandlers: Map { opts._debug( `Run KZG_POINT_EVALUATION (0x14) precompile data=${short(opts.data)} length=${ opts.data.length - } gasLimit=${opts.gasLimit} gasUsed=${gasUsed}` + } gasLimit=${opts.gasLimit} gasUsed=${gasUsed}`, ) } @@ -61,8 +61,8 @@ export async function precompile0a(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug( `KZG_POINT_EVALUATION (0x14): proof verification with commitment=${bytesToHex( - commitment - )} z=${bytesToHex(z)} y=${bytesToHex(y)} kzgProof=${bytesToHex(kzgProof)}` + commitment, + )} z=${bytesToHex(z)} y=${bytesToHex(y)} kzgProof=${bytesToHex(kzgProof)}`, ) } try { @@ -89,8 +89,8 @@ export async function precompile0a(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug( `KZG_POINT_EVALUATION (0x14) return fieldElements=${bytesToHex( - fieldElementsBuffer - )} modulus=${bytesToHex(modulusBuffer)}` + fieldElementsBuffer, + )} modulus=${bytesToHex(modulusBuffer)}`, ) } diff --git a/packages/evm/src/precompiles/bls12_381/constants.ts b/packages/evm/src/precompiles/bls12_381/constants.ts index f5f19a77b6..0ce107c5f3 100644 --- a/packages/evm/src/precompiles/bls12_381/constants.ts +++ b/packages/evm/src/precompiles/bls12_381/constants.ts @@ -2,7 +2,7 @@ import { concatBytes, hexToBytes } from '@ethereumjs/util' // base field modulus as described in the EIP export const BLS_FIELD_MODULUS = BigInt( - '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab' + '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab', ) export const BLS_G1_POINT_BYTE_LENGTH = 128 diff --git a/packages/evm/src/precompiles/bls12_381/mcl.ts b/packages/evm/src/precompiles/bls12_381/mcl.ts index e006a0a263..133ef18cbe 100644 --- a/packages/evm/src/precompiles/bls12_381/mcl.ts +++ b/packages/evm/src/precompiles/bls12_381/mcl.ts @@ -226,7 +226,7 @@ export class MCLBLS implements EVMBLSInterface { const p2 = BLS12_381_ToG1Point( input.subarray(BLS_G1_POINT_BYTE_LENGTH, BLS_G1_POINT_BYTE_LENGTH * 2), this._mcl, - false + false, ) const result = this._mcl.add(p1, p2) @@ -250,7 +250,7 @@ export class MCLBLS implements EVMBLSInterface { const p2 = BLS12_381_ToG2Point( input.subarray(BLS_G2_POINT_BYTE_LENGTH, BLS_G2_POINT_BYTE_LENGTH * 2), this._mcl, - false + false, ) const result = this._mcl.add(p1, p2) @@ -296,11 +296,11 @@ export class MCLBLS implements EVMBLSInterface { const pairStart = pairLength * k const G1 = BLS12_381_ToG1Point( input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH), - this._mcl + this._mcl, ) const Fr = BLS12_381_ToFrPoint( input.subarray(pairStart + BLS_G1_POINT_BYTE_LENGTH, pairStart + pairLength), - this._mcl + this._mcl, ) G1Array.push(G1) @@ -322,11 +322,11 @@ export class MCLBLS implements EVMBLSInterface { const pairStart = pairLength * k const G2 = BLS12_381_ToG2Point( input.subarray(pairStart, pairStart + BLS_G2_POINT_BYTE_LENGTH), - this._mcl + this._mcl, ) const Fr = BLS12_381_ToFrPoint( input.subarray(pairStart + BLS_G2_POINT_BYTE_LENGTH, pairStart + pairLength), - this._mcl + this._mcl, ) G2Array.push(G2) @@ -344,13 +344,13 @@ export class MCLBLS implements EVMBLSInterface { const pairStart = pairLength * k const G1 = BLS12_381_ToG1Point( input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH), - this._mcl + this._mcl, ) const g2start = pairStart + BLS_G1_POINT_BYTE_LENGTH const G2 = BLS12_381_ToG2Point( input.subarray(g2start, g2start + BLS_G2_POINT_BYTE_LENGTH), - this._mcl + this._mcl, ) pairs.push([G1, G2]) diff --git a/packages/evm/src/precompiles/bls12_381/noble.ts b/packages/evm/src/precompiles/bls12_381/noble.ts index 1d2ad640be..4a39590785 100644 --- a/packages/evm/src/precompiles/bls12_381/noble.ts +++ b/packages/evm/src/precompiles/bls12_381/noble.ts @@ -166,7 +166,7 @@ export class NobleBLS implements EVMBLSInterface { addG1(input: Uint8Array): Uint8Array { const p1 = BLS12_381_ToG1Point(input.subarray(0, BLS_G1_POINT_BYTE_LENGTH)) const p2 = BLS12_381_ToG1Point( - input.subarray(BLS_G1_POINT_BYTE_LENGTH, BLS_G1_POINT_BYTE_LENGTH * 2) + input.subarray(BLS_G1_POINT_BYTE_LENGTH, BLS_G1_POINT_BYTE_LENGTH * 2), ) const p = p1.add(p2) @@ -190,7 +190,7 @@ export class NobleBLS implements EVMBLSInterface { addG2(input: Uint8Array): Uint8Array { const p1 = BLS12_381_ToG2Point(input.subarray(0, BLS_G2_POINT_BYTE_LENGTH)) const p2 = BLS12_381_ToG2Point( - input.subarray(BLS_G2_POINT_BYTE_LENGTH, BLS_G2_POINT_BYTE_LENGTH * 2) + input.subarray(BLS_G2_POINT_BYTE_LENGTH, BLS_G2_POINT_BYTE_LENGTH * 2), ) const p = p1.add(p2) const result = BLS12_381_FromG2Point(p) @@ -240,10 +240,10 @@ export class NobleBLS implements EVMBLSInterface { for (let k = 0; k < numPairs; k++) { const pairStart = pairLength * k const G1 = BLS12_381_ToG1Point( - input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH) + input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH), ) const Fr = BLS12_381_ToFrPoint( - input.subarray(pairStart + BLS_G1_POINT_BYTE_LENGTH, pairStart + pairLength) + input.subarray(pairStart + BLS_G1_POINT_BYTE_LENGTH, pairStart + pairLength), ) let pMul if (Fr === BIGINT_0) { @@ -272,10 +272,10 @@ export class NobleBLS implements EVMBLSInterface { for (let k = 0; k < numPairs; k++) { const pairStart = pairLength * k const G2 = BLS12_381_ToG2Point( - input.subarray(pairStart, pairStart + BLS_G2_POINT_BYTE_LENGTH) + input.subarray(pairStart, pairStart + BLS_G2_POINT_BYTE_LENGTH), ) const Fr = BLS12_381_ToFrPoint( - input.subarray(pairStart + BLS_G2_POINT_BYTE_LENGTH, pairStart + pairLength) + input.subarray(pairStart + BLS_G2_POINT_BYTE_LENGTH, pairStart + pairLength), ) let pMul if (Fr === BIGINT_0) { @@ -296,7 +296,7 @@ export class NobleBLS implements EVMBLSInterface { for (let k = 0; k < input.length / pairLength; k++) { const pairStart = pairLength * k const G1 = BLS12_381_ToG1Point( - input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH) + input.subarray(pairStart, pairStart + BLS_G1_POINT_BYTE_LENGTH), ) const g2start = pairStart + BLS_G1_POINT_BYTE_LENGTH diff --git a/packages/evm/src/precompiles/bls12_381/util.ts b/packages/evm/src/precompiles/bls12_381/util.ts index ca09ef1271..618acca0a7 100644 --- a/packages/evm/src/precompiles/bls12_381/util.ts +++ b/packages/evm/src/precompiles/bls12_381/util.ts @@ -19,7 +19,7 @@ export const gasCheck = (opts: PrecompileInput, gasUsed: bigint, pName: string) opts._debug( `Run ${pName} precompile data=${short(opts.data)} length=${opts.data.length} gasLimit=${ opts.gasLimit - } gasUsed=${gasUsed}` + } gasUsed=${gasUsed}`, ) } if (opts.gasLimit < gasUsed) { @@ -68,7 +68,7 @@ export const equalityLengthCheck = (opts: PrecompileInput, length: number, pName if (opts.data.length !== length) { if (opts._debug !== undefined) { opts._debug( - `${pName} failed: Invalid input length length=${opts.data.length} (expected: ${length})` + `${pName} failed: Invalid input length length=${opts.data.length} (expected: ${length})`, ) } return false @@ -89,7 +89,7 @@ export const moduloLengthCheck = (opts: PrecompileInput, length: number, pName: if (opts.data.length % length !== 0) { if (opts._debug !== undefined) { opts._debug( - `${pName} failed: Invalid input length length=${opts.data.length} (expected: ${length}*k bytes)` + `${pName} failed: Invalid input length length=${opts.data.length} (expected: ${length}*k bytes)`, ) } return false @@ -123,12 +123,12 @@ export const leading16ZeroBytesCheck = ( opts: PrecompileInput, zeroByteRanges: number[][], pName: string, - pairStart = 0 + pairStart = 0, ) => { for (const index in zeroByteRanges) { const slicedBuffer = opts.data.subarray( zeroByteRanges[index][0] + pairStart, - zeroByteRanges[index][1] + pairStart + zeroByteRanges[index][1] + pairStart, ) if (!(equalsBytes(slicedBuffer, ZERO_BYTES_16) === true)) { if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/index.ts b/packages/evm/src/precompiles/index.ts index 92d57e2f76..c84f429948 100644 --- a/packages/evm/src/precompiles/index.ts +++ b/packages/evm/src/precompiles/index.ts @@ -266,14 +266,14 @@ type CustomPrecompile = AddPrecompile | DeletePrecompile function getActivePrecompiles( common: Common, - customPrecompiles?: CustomPrecompile[] + customPrecompiles?: CustomPrecompile[], ): Map { const precompileMap = new Map() if (customPrecompiles) { for (const precompile of customPrecompiles) { precompileMap.set( bytesToUnprefixedHex(precompile.address.bytes), - 'function' in precompile ? precompile.function : undefined + 'function' in precompile ? precompile.function : undefined, ) } } diff --git a/packages/evm/test/blobVersionedHashes.spec.ts b/packages/evm/test/blobVersionedHashes.spec.ts index 7bc20dcb7f..f8676be1aa 100644 --- a/packages/evm/test/blobVersionedHashes.spec.ts +++ b/packages/evm/test/blobVersionedHashes.spec.ts @@ -32,7 +32,7 @@ describe('BLOBHASH / access blobVersionedHashes in calldata', () => { assert.equal( bytesToHex(unpadBytes(res.execResult.returnValue)), '0xab', - 'retrieved correct versionedHash from runState' + 'retrieved correct versionedHash from runState', ) }) }) @@ -81,7 +81,7 @@ describe(`BLOBHASH: access blobVersionedHashes within contract calls`, () => { assert.equal( bytesToHex(unpadBytes(res.execResult.returnValue)), '0xab', - `retrieved correct versionedHash from runState through callCode=${callCode}` + `retrieved correct versionedHash from runState through callCode=${callCode}`, ) } }) @@ -137,7 +137,7 @@ describe(`BLOBHASH: access blobVersionedHashes in a CREATE/CREATE2 frame`, () => assert.equal( bytesToHex(code), '0x' + 'ab'.padStart(64, '0'), // have to padStart here, since `BLOBHASH` will push 32 bytes on stack - `retrieved correct versionedHash from runState through createOP=${createOP}` + `retrieved correct versionedHash from runState through createOP=${createOP}`, ) } }) diff --git a/packages/evm/test/customCrypto.spec.ts b/packages/evm/test/customCrypto.spec.ts index 7f75682f1b..7338005f82 100644 --- a/packages/evm/test/customCrypto.spec.ts +++ b/packages/evm/test/customCrypto.spec.ts @@ -37,7 +37,7 @@ describe('custom crypto', () => { it('should use custom ecrecover function', async () => { const customEcrecover = (_msg: Uint8Array) => { return hexToBytes( - '0x84b2586da9b582d3cb260e8fd136129c734f3c80453f48a68e8217ea0b81e08342520f318d202f27a548ad8d3f814ca76d0ee621de2cc510c29e2db4d4f39418' + '0x84b2586da9b582d3cb260e8fd136129c734f3c80453f48a68e8217ea0b81e08342520f318d202f27a548ad8d3f814ca76d0ee621de2cc510c29e2db4d4f39418', ) } const customCrypto = { @@ -57,7 +57,7 @@ describe('custom crypto', () => { assert.equal( bytesToHex(result.returnValue), '0x00000000000000000000000063304c5c6884567b84b18f5bc5774d829a32d25d', - 'used custom ecrecover hashing function' + 'used custom ecrecover hashing function', ) }) }) diff --git a/packages/evm/test/customOpcodes.spec.ts b/packages/evm/test/customOpcodes.spec.ts index 807be3c29e..753743c78d 100644 --- a/packages/evm/test/customOpcodes.spec.ts +++ b/packages/evm/test/customOpcodes.spec.ts @@ -117,18 +117,18 @@ describe('VM: custom opcodes', () => { assert.deepEqual( (evmCopy as any)._customOpcodes, (evmCopy as any)._customOpcodes, - 'evm.shallowCopy() successfully copied customOpcodes option' + 'evm.shallowCopy() successfully copied customOpcodes option', ) assert.equal( evm.events.listenerCount('beforeMessage'), 2, - 'original EVM instance should have two listeners' + 'original EVM instance should have two listeners', ) assert.equal( evmCopy!.events!.listenerCount('beforeMessage'), 0, - 'copied EVM instance should have zero listeners' + 'copied EVM instance should have zero listeners', ) }) }) diff --git a/packages/evm/test/customPrecompiles.spec.ts b/packages/evm/test/customPrecompiles.spec.ts index 2dd614ce68..ef73bb7efa 100644 --- a/packages/evm/test/customPrecompiles.spec.ts +++ b/packages/evm/test/customPrecompiles.spec.ts @@ -137,12 +137,12 @@ describe('EVM -> custom precompiles', () => { assert.deepEqual( shaResult.execResult.returnValue, shaResult2.execResult.returnValue, - 'restored sha precompile - returndata correct' + 'restored sha precompile - returndata correct', ) assert.equal( shaResult.execResult.executionGasUsed, shaResult2.execResult.executionGasUsed, - 'restored sha precompile - gas correct' + 'restored sha precompile - gas correct', ) }) it('shold copy custom precompiles', async () => { @@ -158,7 +158,7 @@ describe('EVM -> custom precompiles', () => { assert.deepEqual( (evm as any)._customPrecompiles, (evmCopy as any)._customPrecompiles, - 'evm.shallowCopy() successfully copied customPrecompiles option' + 'evm.shallowCopy() successfully copied customPrecompiles option', ) }) }) diff --git a/packages/evm/test/eips/eip-3860.spec.ts b/packages/evm/test/eips/eip-3860.spec.ts index e9f08e022b..394643bb90 100644 --- a/packages/evm/test/eips/eip-3860.spec.ts +++ b/packages/evm/test/eips/eip-3860.spec.ts @@ -29,15 +29,15 @@ describe('EIP 3860 tests', () => { // (since memory which is not allocated/resized to yet is always defaulted to 0) data: concatBytes( hexToBytes( - '0x7F6000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060005260206000F3' + '0x7F6000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060005260206000F3', ), - buffer + buffer, ), } const result = await evm.runCall(runCallArgs) assert.ok( (result.execResult.exceptionError?.error as string) === 'initcode exceeds max initcode size', - 'initcode exceeds max size' + 'initcode exceeds max size', ) }) @@ -65,7 +65,7 @@ describe('EIP 3860 tests', () => { await evm.stateManager.putAccount(contractFactory, contractAccount!) await evmWithout3860.stateManager.putAccount(contractFactory, contractAccount!) const factoryCode = hexToBytes( - '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a8160006000f05a8203600a55806000556001600155505050' + '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a8160006000f05a8203600a55806000556001600155505050', ) await evm.stateManager.putContractCode(contractFactory, factoryCode) @@ -81,7 +81,7 @@ describe('EIP 3860 tests', () => { const res2 = await evmWithout3860.runCall(runCallArgs) assert.ok( res.execResult.executionGasUsed > res2.execResult.executionGasUsed, - 'execution gas used is higher with EIP 3860 active' + 'execution gas used is higher with EIP 3860 active', ) }) @@ -109,7 +109,7 @@ describe('EIP 3860 tests', () => { await evm.stateManager.putAccount(contractFactory, contractAccount!) await evmWithout3860.stateManager.putAccount(contractFactory, contractAccount!) const factoryCode = hexToBytes( - '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a60008260006000f55a8203600a55806000556001600155505050' + '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a60008260006000f55a8203600a55806000556001600155505050', ) await evm.stateManager.putContractCode(contractFactory, factoryCode) @@ -125,7 +125,7 @@ describe('EIP 3860 tests', () => { const res2 = await evmWithout3860.runCall(runCallArgs) assert.ok( res.execResult.executionGasUsed > res2.execResult.executionGasUsed, - 'execution gas used is higher with EIP 3860 active' + 'execution gas used is higher with EIP 3860 active', ) }) @@ -151,13 +151,13 @@ describe('EIP 3860 tests', () => { // (since memory which is not allocated/resized to yet is always defaulted to 0) data: concatBytes( hexToBytes(`0x${'00'.repeat(Number(common.param('maxInitCodeSize')) + 1)}`), - bytes + bytes, ), } const result = await evm.runCall(runCallArgs) assert.ok( result.execResult.exceptionError === undefined, - 'succesfully created a contract with data size > MAX_INITCODE_SIZE and allowUnlimitedInitCodeSize active' + 'succesfully created a contract with data size > MAX_INITCODE_SIZE and allowUnlimitedInitCodeSize active', ) }) @@ -207,16 +207,16 @@ describe('EIP 3860 tests', () => { const storageActive = await evm.stateManager.getContractStorage(contractFactory, key0) const storageInactive = await evmDisabled.stateManager.getContractStorage( contractFactory, - key0 + key0, ) assert.ok( !equalsBytes(storageActive, new Uint8Array()), - 'created contract with MAX_INITCODE_SIZE + 1 length, allowUnlimitedInitCodeSize=true' + 'created contract with MAX_INITCODE_SIZE + 1 length, allowUnlimitedInitCodeSize=true', ) assert.ok( equalsBytes(storageInactive, new Uint8Array()), - 'did not create contract with MAX_INITCODE_SIZE + 1 length, allowUnlimitedInitCodeSize=false' + 'did not create contract with MAX_INITCODE_SIZE + 1 length, allowUnlimitedInitCodeSize=false', ) // gas check @@ -236,7 +236,7 @@ describe('EIP 3860 tests', () => { assert.ok( res.execResult.executionGasUsed > res2.execResult.executionGasUsed, - 'charged initcode analysis gas cost on both allowUnlimitedCodeSize=true, allowUnlimitedInitCodeSize=false' + 'charged initcode analysis gas cost on both allowUnlimitedCodeSize=true, allowUnlimitedInitCodeSize=false', ) } }) diff --git a/packages/evm/test/eips/eof-header-validation.ts b/packages/evm/test/eips/eof-header-validation.ts index a2931d1e03..5b51da3ead 100644 --- a/packages/evm/test/eips/eof-header-validation.ts +++ b/packages/evm/test/eips/eof-header-validation.ts @@ -33,7 +33,7 @@ await new Promise((resolve, reject) => { err: Error | undefined, content: string | Uint8Array, fileName: string, - next: Function + next: Function, ) => { if (err) { reject(err) @@ -88,6 +88,6 @@ await new Promise((resolve, reject) => { match: /.json$/, }, fileCallback, - finishedCallback + finishedCallback, ) }) diff --git a/packages/evm/test/memory.spec.ts b/packages/evm/test/memory.spec.ts index 640fe150dd..3bf538966c 100644 --- a/packages/evm/test/memory.spec.ts +++ b/packages/evm/test/memory.spec.ts @@ -38,13 +38,13 @@ describe('Memory', () => { assert.equal( memory._store.length, CONTAINER_SIZE, - 'memory should remain in CONTAINER_SIZE length' + 'memory should remain in CONTAINER_SIZE length', ) memory.write(CONTAINER_SIZE, 1, Uint8Array.from([1])) assert.equal( memory._store.length, 8192 * 2, - 'memory buffer length expanded by CONTAINER_SIZE bytes' + 'memory buffer length expanded by CONTAINER_SIZE bytes', ) }) diff --git a/packages/evm/test/opcodes.spec.ts b/packages/evm/test/opcodes.spec.ts index a18b3fa916..aabde1e465 100644 --- a/packages/evm/test/opcodes.spec.ts +++ b/packages/evm/test/opcodes.spec.ts @@ -13,7 +13,7 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(CHAINID), undefined, - 'istanbul opcode not exposed (HF: < istanbul (petersburg)' + 'istanbul opcode not exposed (HF: < istanbul (petersburg)', ) }) @@ -23,7 +23,7 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(CHAINID)!.name, 'CHAINID', - 'istanbul opcode exposed (HF: istanbul)' + 'istanbul opcode exposed (HF: istanbul)', ) common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.MuirGlacier }) @@ -31,7 +31,7 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(CHAINID)!.name, 'CHAINID', - 'istanbul opcode exposed (HF: > istanbul (muirGlacier)' + 'istanbul opcode exposed (HF: > istanbul (muirGlacier)', ) }) @@ -41,7 +41,7 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(DIFFICULTY_PREVRANDAO)!.name, 'DIFFICULTY', - 'Opcode x44 named DIFFICULTY pre-Merge' + 'Opcode x44 named DIFFICULTY pre-Merge', ) common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Paris }) @@ -49,7 +49,7 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(DIFFICULTY_PREVRANDAO)!.name, 'PREVRANDAO', - 'Opcode x44 named PREVRANDAO post-Merge' + 'Opcode x44 named PREVRANDAO post-Merge', ) }) @@ -61,14 +61,14 @@ describe('EVM -> getActiveOpcodes()', () => { assert.equal( evm.getActiveOpcodes().get(CHAINID), undefined, - 'opcode not exposed after HF change (-> < istanbul)' + 'opcode not exposed after HF change (-> < istanbul)', ) common.setHardfork(Hardfork.Istanbul) assert.equal( evm.getActiveOpcodes().get(CHAINID)!.name, 'CHAINID', - 'opcode exposed after HF change (-> istanbul)' + 'opcode exposed after HF change (-> istanbul)', ) }) }) diff --git a/packages/evm/test/precompiles/01-ecrecover.spec.ts b/packages/evm/test/precompiles/01-ecrecover.spec.ts index 1665f66963..bd9a87eac6 100644 --- a/packages/evm/test/precompiles/01-ecrecover.spec.ts +++ b/packages/evm/test/precompiles/01-ecrecover.spec.ts @@ -34,7 +34,7 @@ describe('Precompiles: ECRECOVER', () => { assert.deepEqual( bytesToHex(result.returnValue.slice(-20)), address, - 'should recover expected address' + 'should recover expected address', ) result = await ECRECOVER({ diff --git a/packages/evm/test/precompiles/03-ripemd160.spec.ts b/packages/evm/test/precompiles/03-ripemd160.spec.ts index 8ce317e014..d865095f53 100644 --- a/packages/evm/test/precompiles/03-ripemd160.spec.ts +++ b/packages/evm/test/precompiles/03-ripemd160.spec.ts @@ -29,7 +29,7 @@ describe('Precompiles: RIPEMD160', () => { assert.deepEqual( bytesToHex(result.returnValue), `0x${expected}`, - 'should generate expected value' + 'should generate expected value', ) result = await RIPEMD160({ diff --git a/packages/evm/test/precompiles/08-ecpairing.spec.ts b/packages/evm/test/precompiles/08-ecpairing.spec.ts index d74c3b7e95..7474550547 100644 --- a/packages/evm/test/precompiles/08-ecpairing.spec.ts +++ b/packages/evm/test/precompiles/08-ecpairing.spec.ts @@ -14,7 +14,7 @@ describe('Precompiles: ECPAIRING', () => { const ECPAIRING = getActivePrecompiles(common).get(addressStr)! const result = await ECPAIRING({ data: hexToBytes( - '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa' + '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa', ), gasLimit: BigInt(0xffffff), common, @@ -24,7 +24,7 @@ describe('Precompiles: ECPAIRING', () => { assert.deepEqual( result.executionGasUsed, BigInt(260000), - 'should use petersburg gas costs (k ^= 2 pairings)' + 'should use petersburg gas costs (k ^= 2 pairings)', ) }) }) diff --git a/packages/evm/test/precompiles/09-blake2f.spec.ts b/packages/evm/test/precompiles/09-blake2f.spec.ts index 0f4e410b66..a502e1fa91 100644 --- a/packages/evm/test/precompiles/09-blake2f.spec.ts +++ b/packages/evm/test/precompiles/09-blake2f.spec.ts @@ -105,7 +105,7 @@ describe('Precompiles: BLAKE2F', () => { assert.equal( bytesToHex(result.returnValue), `0x${t.expected}`, - 'should generate expected value' + 'should generate expected value', ) assert.deepEqual(result.executionGasUsed, BigInt(t.gas), 'should use expected amount of gas') }) diff --git a/packages/evm/test/precompiles/0a-pointevaluation.spec.ts b/packages/evm/test/precompiles/0a-pointevaluation.spec.ts index 67bfd4801f..f5018b03f1 100644 --- a/packages/evm/test/precompiles/0a-pointevaluation.spec.ts +++ b/packages/evm/test/precompiles/0a-pointevaluation.spec.ts @@ -14,7 +14,7 @@ import { createEVM, getActivePrecompiles } from '../../src/index.js' import type { PrecompileInput } from '../../src/index.js' const BLS_MODULUS = BigInt( - '52435875175126190479447740508185965837690552500527637822603658699938581184513' + '52435875175126190479447740508185965837690552500527637822603658699938581184513', ) describe('Precompiles: point evaluation', () => { @@ -37,12 +37,12 @@ describe('Precompiles: point evaluation', () => { const testCase = { commitment: hexToBytes( - '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', ), z: hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000002'), y: hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), proof: hexToBytes( - '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + '0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', ), } const versionedHash = computeVersionedHash(testCase.commitment, 1) @@ -58,7 +58,7 @@ describe('Precompiles: point evaluation', () => { assert.equal( bytesToBigInt(unpadBytes(res.returnValue.slice(32))), BLS_MODULUS, - 'point evaluation precompile returned expected output' + 'point evaluation precompile returned expected output', ) const optsWithInvalidCommitment: PrecompileInput = { @@ -67,7 +67,7 @@ describe('Precompiles: point evaluation', () => { testCase.z, testCase.y, testCase.commitment, - testCase.proof + testCase.proof, ), gasLimit: 0xfffffffffn, _EVM: evm, @@ -77,7 +77,7 @@ describe('Precompiles: point evaluation', () => { res = await pointEvaluation(optsWithInvalidCommitment) assert.ok( res.exceptionError?.error.match('kzg commitment does not match versioned hash'), - 'precompile throws when commitment does not match versioned hash' + 'precompile throws when commitment does not match versioned hash', ) }) }) diff --git a/packages/evm/test/precompiles/eip-2537-bls.spec.ts b/packages/evm/test/precompiles/eip-2537-bls.spec.ts index be698084e9..138eeeacfe 100644 --- a/packages/evm/test/precompiles/eip-2537-bls.spec.ts +++ b/packages/evm/test/precompiles/eip-2537-bls.spec.ts @@ -79,7 +79,7 @@ for (const bls of [undefined, mclbls]) { assert.deepEqual( '0x' + data.Expected, bytesToHex(result.returnValue), - 'return value should match testVectorResult' + 'return value should match testVectorResult', ) assert.equal(result.executionGasUsed, BigInt(data.Gas)) } catch (e) { diff --git a/packages/evm/test/runCall.spec.ts b/packages/evm/test/runCall.spec.ts index d42a63b5cb..bdd2a3f899 100644 --- a/packages/evm/test/runCall.spec.ts +++ b/packages/evm/test/runCall.spec.ts @@ -36,7 +36,7 @@ describe('RunCall tests', () => { assert.equal( res.createdAddress?.toString(), '0xbd770416a3345f91e4b34576cb804a576fa48eb1', - 'created valid address when FROM account nonce is 0' + 'created valid address when FROM account nonce is 0', ) }) @@ -137,11 +137,11 @@ describe('RunCall tests', () => { assert.ok( byzantiumResult.execResult.exceptionError && byzantiumResult.execResult.exceptionError.error === 'invalid opcode', - 'byzantium cannot accept constantinople opcodes (SHL)' + 'byzantium cannot accept constantinople opcodes (SHL)', ) assert.ok( !constantinopleResult.execResult.exceptionError, - 'constantinople can access the SHL opcode' + 'constantinople can access the SHL opcode', ) }) @@ -178,7 +178,7 @@ describe('RunCall tests', () => { await evm.stateManager.putContractStorage( address, new Uint8Array(32), - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) // setup the call arguments @@ -414,7 +414,7 @@ describe('RunCall tests', () => { assert.deepEqual( storage, emptyBytes, - 'failed to create contract; nonce of creating contract is too high (MAX_UINT64)' + 'failed to create contract; nonce of creating contract is too high (MAX_UINT64)', ) }) @@ -469,7 +469,7 @@ describe('RunCall tests', () => { } catch (err: any) { assert.ok( err.message.includes('value field cannot be negative'), - 'throws on negative call value' + 'throws on negative call value', ) } }) @@ -483,7 +483,7 @@ describe('RunCall tests', () => { const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') await evm.stateManager.putContractCode(contractAddress, contractCode) const senderKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const sender = Address.fromPrivateKey(senderKey) @@ -503,7 +503,7 @@ describe('RunCall tests', () => { assert.equal( senderBalance, balance ?? BigInt(0), - 'sender balance should be the same before and after call execution with skipBalance' + 'sender balance should be the same before and after call execution with skipBalance', ) assert.equal(res.execResult.exceptionError, undefined, 'no exceptionError with skipBalance') } @@ -511,7 +511,7 @@ describe('RunCall tests', () => { const res2 = await evm.runCall({ ...runCallArgs, skipBalance: false }) assert.ok( res2.execResult.exceptionError?.error.match('insufficient balance'), - 'runCall reverts when insufficient sender balance and skipBalance is false' + 'runCall reverts when insufficient sender balance and skipBalance is false', ) }) @@ -536,7 +536,7 @@ describe('RunCall tests', () => { assert.equal( result.execResult.exceptionError?.error, ERROR.CODESIZE_EXCEEDS_MAXIMUM, - 'reported error is correct' + 'reported error is correct', ) }) it('runCall() => use BLOBHASH opcode from EIP 4844', async () => { @@ -558,7 +558,7 @@ describe('RunCall tests', () => { assert.equal( bytesToHex(unpadBytes(res.execResult.returnValue)), '0xab', - 'retrieved correct versionedHash from runState' + 'retrieved correct versionedHash from runState', ) // setup the call arguments @@ -572,7 +572,7 @@ describe('RunCall tests', () => { assert.equal( bytesToHex(unpadBytes(res2.execResult.returnValue)), '0x', - 'retrieved no versionedHash when specified versionedHash does not exist in runState' + 'retrieved no versionedHash when specified versionedHash does not exist in runState', ) }) @@ -588,7 +588,7 @@ describe('RunCall tests', () => { assert.equal( evm.getActiveOpcodes().get(BLOBBASEFEE_OPCODE)!.name, 'BLOBBASEFEE', - 'Opcode 0x4a named BLOBBASEFEE' + 'Opcode 0x4a named BLOBBASEFEE', ) const block = defaultBlock() @@ -605,7 +605,7 @@ describe('RunCall tests', () => { assert.equal( bytesToBigInt(unpadBytes(res.execResult.returnValue)), BigInt(119), - 'retrieved correct gas fee' + 'retrieved correct gas fee', ) assert.equal(res.execResult.executionGasUsed, BigInt(6417), 'correct blob gas fee (2) charged') }) @@ -742,7 +742,7 @@ describe('RunCall tests', () => { await evm.runCall(runCallArgs) const callResult = bytesToHex( - await evm.stateManager.getContractStorage(callerAddress, zeros(32)) + await evm.stateManager.getContractStorage(callerAddress, zeros(32)), ) // Expect slot to have value of either: 0 since CALLCODE and CODE did not have enough gas to execute // Or 1, if CALL(CODE) has enough gas to enter the new call frame diff --git a/packages/evm/test/runCode.spec.ts b/packages/evm/test/runCode.spec.ts index f49596a310..c63560fa9f 100644 --- a/packages/evm/test/runCode.spec.ts +++ b/packages/evm/test/runCode.spec.ts @@ -37,7 +37,7 @@ describe('VM.runCode: initial program counter', () => { assert.equal( result.runState?.programCounter, testData.resultPC, - `should start the execution at the specified pc or 0, testCases[${i}]` + `should start the execution at the specified pc or 0, testCases[${i}]`, ) } } catch (e: any) { @@ -118,7 +118,7 @@ describe('VM.runCode: RunCodeOptions', () => { } catch (err: any) { assert.ok( err.message.includes('value field cannot be negative'), - 'throws on negative call value' + 'throws on negative call value', ) } }) diff --git a/packages/evm/test/transientStorage.spec.ts b/packages/evm/test/transientStorage.spec.ts index 095b4b66b3..94a29cd8fa 100644 --- a/packages/evm/test/transientStorage.spec.ts +++ b/packages/evm/test/transientStorage.spec.ts @@ -96,9 +96,9 @@ describe('Transient Storage', () => { assert.deepEqual( transientStorage.get( Address.fromString('0xff00000000000000000000000000000000000002'), - new Uint8Array(32).fill(0xff) + new Uint8Array(32).fill(0xff), ), - value + value, ) }) diff --git a/packages/evm/tsconfig.lint.json b/packages/evm/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/evm/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/genesis/.eslintrc.cjs b/packages/genesis/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/genesis/.eslintrc.cjs +++ b/packages/genesis/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/genesis/examples/simple.ts b/packages/genesis/examples/simple.ts index 2f20316aa7..91033c5bf7 100644 --- a/packages/genesis/examples/simple.ts +++ b/packages/genesis/examples/simple.ts @@ -1,9 +1,9 @@ -import { getGenesis } from '@ethereumjs/genesis' import { Chain } from '@ethereumjs/common' // or directly use chain ID +import { getGenesis } from '@ethereumjs/genesis' const mainnetGenesis = getGenesis(Chain.Mainnet) console.log( `This balance for account 0x000d836201318ec6899a67540690382780743280 in this chain's genesis state is ${parseInt( - mainnetGenesis!['0x000d836201318ec6899a67540690382780743280'] as string - )}` + mainnetGenesis!['0x000d836201318ec6899a67540690382780743280'] as string, + )}`, ) diff --git a/packages/genesis/test/index.spec.ts b/packages/genesis/test/index.spec.ts index d3eb6023b4..f321627034 100644 --- a/packages/genesis/test/index.spec.ts +++ b/packages/genesis/test/index.spec.ts @@ -17,15 +17,15 @@ describe('genesis test', () => { const genesisState = getGenesis(Number(chainId)) assert.ok( genesisState !== undefined, - `network=${name} chainId=${chainId} genesis should be found` + `network=${name} chainId=${chainId} genesis should be found`, ) const stateRoot = await genGenesisStateRoot(genesisState!) assert.ok( equalsBytes(expectedRoot, stateRoot), `network=${name} chainId=${chainId} stateRoot should match expected=${bytesToHex( - expectedRoot - )} actual=${bytesToHex(stateRoot)}` + expectedRoot, + )} actual=${bytesToHex(stateRoot)}`, ) } }) diff --git a/packages/genesis/tsconfig.lint.json b/packages/genesis/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/genesis/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/rlp/.eslintrc.cjs b/packages/rlp/.eslintrc.cjs index 217a81018c..092291ee94 100644 --- a/packages/rlp/.eslintrc.cjs +++ b/packages/rlp/.eslintrc.cjs @@ -2,7 +2,14 @@ module.exports = { extends: '../../config/eslint.cjs', rules: { '@typescript-eslint/no-use-before-define': 'off', - '@typescript-eslint/no-unused-vars': 'off', - 'no-unused-vars': 'off', }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], } diff --git a/packages/rlp/examples/simple.ts b/packages/rlp/examples/simple.ts index dcd6f7795d..2c7d5f2cb8 100644 --- a/packages/rlp/examples/simple.ts +++ b/packages/rlp/examples/simple.ts @@ -1,5 +1,5 @@ -import assert from 'assert' import { RLP } from '@ethereumjs/rlp' +import assert from 'assert' const nestedList = [[], [[]], [[], [[]]]] const encoded = RLP.encode(nestedList) diff --git a/packages/rlp/src/index.ts b/packages/rlp/src/index.ts index 084ed01399..7d9527bc18 100644 --- a/packages/rlp/src/index.ts +++ b/packages/rlp/src/index.ts @@ -232,7 +232,6 @@ function concatBytes(...arrays: Uint8Array[]): Uint8Array { // Global symbols in both browsers and Node.js since v11 // See https://github.com/microsoft/TypeScript/issues/31535 declare const TextEncoder: any -declare const TextDecoder: any function utf8ToBytes(utf: string): Uint8Array { return new TextEncoder().encode(utf) diff --git a/packages/rlp/test/cli.spec.ts b/packages/rlp/test/cli.spec.ts index dae67540d5..afd4a85d45 100644 --- a/packages/rlp/test/cli.spec.ts +++ b/packages/rlp/test/cli.spec.ts @@ -5,7 +5,7 @@ import type { ChildProcessWithoutNullStreams } from 'child_process' export function cliRunHelper( cliArgs: string[], - onData: (message: string, child: ChildProcessWithoutNullStreams, resolve: Function) => void + onData: (message: string, child: ChildProcessWithoutNullStreams, resolve: Function) => void, ) { const file = require.resolve('../bin/rlp.cjs') const child = spawn(process.execPath, [file, ...cliArgs]) @@ -46,7 +46,7 @@ describe('rlp CLI', async () => { const onData = ( message: string, child: ChildProcessWithoutNullStreams, - resolve: Function + resolve: Function, ) => { assert.ok(message.includes('0x05'), 'cli correctly encoded 5') child.kill(9) diff --git a/packages/rlp/test/dataTypes.spec.ts b/packages/rlp/test/dataTypes.spec.ts index 32f8d70da6..ff95ecb621 100644 --- a/packages/rlp/test/dataTypes.spec.ts +++ b/packages/rlp/test/dataTypes.spec.ts @@ -57,7 +57,7 @@ describe('RLP encoding (string)', () => { it('length of string >55 should return 0xb7+len(len(data)) plus len(data) plus data', () => { const encodedLongString = RLP.encode( - 'zoo255zoo255zzzzzzzzzzzzssssssssssssssssssssssssssssssssssssssssssssss' + 'zoo255zoo255zzzzzzzzzzzzssssssssssssssssssssssssssssssssssssssssssssss', ) assert.deepEqual(72, encodedLongString.length) assert.deepEqual(encodedLongString[0], 184) @@ -92,7 +92,7 @@ describe('RLP encoding (list)', () => { } // Verified with Geth's RLPDump const expected = hexToBytes( - 'f85483646f6783676f6483636174b8467a6f6f3235357a6f6f3235357a7a7a7a7a7a7a7a7a7a7a7a73737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373' + 'f85483646f6783676f6483636174b8467a6f6f3235357a6f6f3235357a7a7a7a7a7a7a7a7a7a7a7a73737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373', ) assert.deepEqual(encodedArrayOfStrings, expected) }) @@ -324,7 +324,7 @@ describe('empty values', () => { describe('bad values', () => { it('wrong encoded a zero', () => { const val = hexToBytes( - 'f9005f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3' + 'f9005f030182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3', ) let result try { @@ -337,7 +337,7 @@ describe('bad values', () => { it('invalid length', () => { const a = hexToBytes( - 'f86081000182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3' + 'f86081000182520894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3', ) let result @@ -405,11 +405,8 @@ describe('hex prefix', () => { describe('recursive typings', () => { it('should not throw compilation error', () => { - type IsType = Exclude extends never - ? Exclude extends never - ? true - : false - : false + type IsType = + Exclude extends never ? (Exclude extends never ? true : false) : false const assertType = (isTrue: IsType) => { return isTrue } diff --git a/packages/rlp/test/integration.spec.ts b/packages/rlp/test/integration.spec.ts index 107c0dcd47..4cb3a5186d 100644 --- a/packages/rlp/test/integration.spec.ts +++ b/packages/rlp/test/integration.spec.ts @@ -44,7 +44,7 @@ describe.skipIf(isBrowser)('CLI command', () => { assert.deepEqual(encodeResultTrimmed, out.toLowerCase(), `should pass encoding ${testName}`) } }, - { timeout: 10000 } + { timeout: 10000 }, ) }) @@ -54,9 +54,9 @@ describe.skipIf(isBrowser)('Cross-frame', () => { assert.deepEqual( vm.runInNewContext( "Array.from(RLP.encode(['dog', 'god', 'cat'])).map(n => n.toString(16).padStart(2, '0')).join('')", - { RLP } + { RLP }, ), - 'cc83646f6783676f6483636174' + 'cc83646f6783676f6483636174', ) }) }) diff --git a/packages/rlp/test/invalid.spec.ts b/packages/rlp/test/invalid.spec.ts index 06e1a18372..be0280dbf9 100644 --- a/packages/rlp/test/invalid.spec.ts +++ b/packages/rlp/test/invalid.spec.ts @@ -19,7 +19,7 @@ describe('invalid tests', () => { }, undefined, undefined, - `should not decode invalid RLPs, input: ${out}` + `should not decode invalid RLPs, input: ${out}`, ) }) } @@ -27,7 +27,7 @@ describe('invalid tests', () => { it('should pass long string sanity check test', function () { // long string invalid test; string length > 55 const longBufferTest = RLP.encode( - 'zoo255zoo255zzzzzzzzzzzzssssssssssssssssssssssssssssssssssssssssssssss' + 'zoo255zoo255zzzzzzzzzzzzssssssssssssssssssssssssssssssssssssssssssssss', ) // sanity checks assert.ok(longBufferTest[0] > 0xb7) @@ -40,7 +40,7 @@ describe('invalid tests', () => { }, undefined, undefined, - 'string longer than 55 bytes: should throw' + 'string longer than 55 bytes: should throw', ) }) }) @@ -87,7 +87,7 @@ describe('invalid geth tests', () => { }, undefined, undefined, - `should throw: ${gethCase}` + `should throw: ${gethCase}`, ) }) } diff --git a/packages/rlp/test/official.spec.ts b/packages/rlp/test/official.spec.ts index df03b862e6..9f8aef85ef 100644 --- a/packages/rlp/test/official.spec.ts +++ b/packages/rlp/test/official.spec.ts @@ -171,13 +171,13 @@ describe('geth tests', () => { assert.deepEqual( JSON.stringify(arrayOutput), JSON.stringify(gethCase.value!), - `invalid output: ${gethCase.input}` + `invalid output: ${gethCase.input}`, ) } else { assert.deepEqual( bytesToHex(Uint8Array.from(output as any)), gethCase.value, - `invalid output: ${gethCase.input}` + `invalid output: ${gethCase.input}`, ) } }, `should not throw: ${gethCase.input}`) diff --git a/packages/rlp/test/utils.ts b/packages/rlp/test/utils.ts index 4c96e4f216..161f0bb006 100644 --- a/packages/rlp/test/utils.ts +++ b/packages/rlp/test/utils.ts @@ -4,7 +4,6 @@ const { hexToBytes } = utils // Global symbols in both browsers and Node.js since v11 // See https://github.com/microsoft/TypeScript/issues/31535 -declare const TextEncoder: any declare const TextDecoder: any export function bytesToUtf8(bytes: Uint8Array): string { diff --git a/packages/rlp/tsconfig.lint.json b/packages/rlp/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/rlp/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/statemanager/.eslintrc.cjs b/packages/statemanager/.eslintrc.cjs index 91c78776e6..9c5b0dcd15 100644 --- a/packages/statemanager/.eslintrc.cjs +++ b/packages/statemanager/.eslintrc.cjs @@ -5,4 +5,13 @@ module.exports = { 'no-invalid-this': 'off', 'no-restricted-syntax': 'off', }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], } diff --git a/packages/statemanager/examples/basicUsage.ts b/packages/statemanager/examples/basicUsage.ts index d95f08bd73..462e28b8cd 100644 --- a/packages/statemanager/examples/basicUsage.ts +++ b/packages/statemanager/examples/basicUsage.ts @@ -1,6 +1,5 @@ -import { Account, Address } from '@ethereumjs/util' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { hexToBytes } from '@ethereumjs/util' +import { Account, Address, hexToBytes } from '@ethereumjs/util' const main = async () => { const stateManager = new DefaultStateManager() @@ -15,7 +14,7 @@ const main = async () => { console.log( `Account at address ${address.toString()} has balance ${ (await stateManager.getAccount(address))?.balance - }` + }`, ) } -main() +void main() diff --git a/packages/statemanager/examples/evm.ts b/packages/statemanager/examples/evm.ts index bc804f6525..5e767aa137 100644 --- a/packages/statemanager/examples/evm.ts +++ b/packages/statemanager/examples/evm.ts @@ -1,5 +1,5 @@ -import { RPCStateManager, RPCBlockChain } from '@ethereumjs/statemanager' -import { createEVM, EVM } from '@ethereumjs/evm' +import { createEVM } from '@ethereumjs/evm' +import { RPCBlockChain, RPCStateManager } from '@ethereumjs/statemanager' const main = async () => { try { @@ -12,4 +12,4 @@ const main = async () => { console.log(e.message) // fetch would fail because provider url is not real. please replace provider with a valid rpc url string. } } -main() +void main() diff --git a/packages/statemanager/examples/fromProofInstantiation.ts b/packages/statemanager/examples/fromProofInstantiation.ts index df607aef58..97df90f29c 100644 --- a/packages/statemanager/examples/fromProofInstantiation.ts +++ b/packages/statemanager/examples/fromProofInstantiation.ts @@ -1,6 +1,5 @@ -import { Address } from '@ethereumjs/util' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { hexToBytes } from '@ethereumjs/util' +import { Address, hexToBytes } from '@ethereumjs/util' const main = async () => { // setup `stateManager` with some existing address @@ -8,10 +7,10 @@ const main = async () => { const contractAddress = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) const byteCode = hexToBytes('0x67ffffffffffffffff600160006000fb') const storageKey1 = hexToBytes( - '0x0000000000000000000000000000000000000000000000000000000000000001' + '0x0000000000000000000000000000000000000000000000000000000000000001', ) const storageKey2 = hexToBytes( - '0x0000000000000000000000000000000000000000000000000000000000000002' + '0x0000000000000000000000000000000000000000000000000000000000000002', ) const storageValue1 = hexToBytes('0x01') const storageValue2 = hexToBytes('0x02') @@ -29,11 +28,11 @@ const main = async () => { console.log(await partialStateManager.getContractCode(contractAddress)) // contract bytecode is not included in proof console.log( await partialStateManager.getContractStorage(contractAddress, storageKey1), - storageValue1 + storageValue1, ) // should match console.log( await partialStateManager.getContractStorage(contractAddress, storageKey2), - storageValue2 + storageValue2, ) // should match const accountFromNewSM = await partialStateManager.getAccount(contractAddress) @@ -45,4 +44,4 @@ const main = async () => { console.log(slot1FromNewSM, storageValue1) // should match console.log(slot2FromNewSM, storageValue2) // should match } -main() +void main() diff --git a/packages/statemanager/examples/rpcStateManager.ts b/packages/statemanager/examples/rpcStateManager.ts index 9124f25843..f711f2804b 100644 --- a/packages/statemanager/examples/rpcStateManager.ts +++ b/packages/statemanager/examples/rpcStateManager.ts @@ -1,5 +1,5 @@ -import { Address } from '@ethereumjs/util' import { RPCStateManager } from '@ethereumjs/statemanager' +import { Address } from '@ethereumjs/util' const main = async () => { try { @@ -12,4 +12,4 @@ const main = async () => { console.log(e.message) // fetch fails because provider url is not real. please replace provider with a valid rpc url string. } } -main() +void main() diff --git a/packages/statemanager/examples/simple.ts b/packages/statemanager/examples/simple.ts index b7618b4127..308897ce95 100644 --- a/packages/statemanager/examples/simple.ts +++ b/packages/statemanager/examples/simple.ts @@ -1,6 +1,7 @@ -import { SimpleStateManager } from '../src/index.js' import { Account, Address, randomBytes } from '@ethereumjs/util' +import { SimpleStateManager } from '../src/index.js' + const main = async () => { const sm = new SimpleStateManager() const address = Address.fromPrivateKey(randomBytes(32)) @@ -9,4 +10,4 @@ const main = async () => { console.log(await sm.getAccount(address)) } -main() +void main() diff --git a/packages/statemanager/src/accessWitness.ts b/packages/statemanager/src/accessWitness.ts index 2563c91537..0bbedc7a07 100644 --- a/packages/statemanager/src/accessWitness.ts +++ b/packages/statemanager/src/accessWitness.ts @@ -76,7 +76,7 @@ export class AccessWitness implements AccessWitnessInterface { verkleCrypto?: VerkleCrypto stems?: Map chunks?: Map - } = {} + } = {}, ) { if (opts.verkleCrypto === undefined) { throw new Error('verkle crypto required') @@ -179,7 +179,7 @@ export class AccessWitness implements AccessWitnessInterface { touchCodeChunksRangeOnWriteAndChargeGas( contact: Address, startPc: number, - endPc: number + endPc: number, ): bigint { let gas = BIGINT_0 for (let chunkNum = Math.floor(startPc / 31); chunkNum <= Math.floor(endPc / 31); chunkNum++) { @@ -192,7 +192,7 @@ export class AccessWitness implements AccessWitnessInterface { touchAddressOnWriteAndComputeGas( address: Address, treeIndex: number | bigint, - subIndex: number | Uint8Array + subIndex: number | Uint8Array, ): bigint { return this.touchAddressAndChargeGas(address, treeIndex, subIndex, { isWrite: true }) } @@ -200,7 +200,7 @@ export class AccessWitness implements AccessWitnessInterface { touchAddressOnReadAndComputeGas( address: Address, treeIndex: number | bigint, - subIndex: number | Uint8Array + subIndex: number | Uint8Array, ): bigint { return this.touchAddressAndChargeGas(address, treeIndex, subIndex, { isWrite: false }) } @@ -209,7 +209,7 @@ export class AccessWitness implements AccessWitnessInterface { address: Address, treeIndex: number | bigint, subIndex: number | Uint8Array, - { isWrite }: { isWrite?: boolean } + { isWrite }: { isWrite?: boolean }, ): bigint { let gas = BIGINT_0 @@ -217,7 +217,7 @@ export class AccessWitness implements AccessWitnessInterface { address, treeIndex, subIndex, - { isWrite } + { isWrite }, ) if (stemRead === true) { @@ -238,7 +238,7 @@ export class AccessWitness implements AccessWitnessInterface { } debug( - `touchAddressAndChargeGas=${gas} address=${address} treeIndex=${treeIndex} subIndex=${subIndex}` + `touchAddressAndChargeGas=${gas} address=${address} treeIndex=${treeIndex} subIndex=${subIndex}`, ) return gas @@ -248,7 +248,7 @@ export class AccessWitness implements AccessWitnessInterface { address: Address, treeIndex: number | bigint, subIndex: number | Uint8Array, - { isWrite }: { isWrite?: boolean } = {} + { isWrite }: { isWrite?: boolean } = {}, ): AccessEventFlags { let stemRead = false, stemWrite = false, @@ -269,7 +269,7 @@ export class AccessWitness implements AccessWitnessInterface { const accessedChunkKey = getVerkleKey( accessedStemKey, - typeof subIndex === 'number' ? intToBytes(subIndex) : subIndex + typeof subIndex === 'number' ? intToBytes(subIndex) : subIndex, ) const accessedChunkKeyHex = bytesToHex(accessedChunkKey) let accessedChunk = this.chunks.get(accessedChunkKeyHex) @@ -294,7 +294,7 @@ export class AccessWitness implements AccessWitnessInterface { } debug( - `${accessedChunkKeyHex}: isWrite=${isWrite} for steamRead=${stemRead} stemWrite=${stemWrite} chunkRead=${chunkRead} chunkWrite=${chunkWrite} chunkFill=${chunkFill}` + `${accessedChunkKeyHex}: isWrite=${isWrite} for steamRead=${stemRead} stemWrite=${stemWrite} chunkRead=${chunkRead} chunkWrite=${chunkWrite} chunkFill=${chunkFill}`, ) return { stemRead, stemWrite, chunkRead, chunkWrite, chunkFill } } @@ -382,7 +382,7 @@ export function decodeAccessedState(treeIndex: number | bigint, chunkIndex: numb return { type: AccessedStateType.Storage, slot } } else { throw Error( - `Invalid treeIndex=${treeIndex} chunkIndex=${chunkIndex} for verkle tree access` + `Invalid treeIndex=${treeIndex} chunkIndex=${chunkIndex} for verkle tree access`, ) } } diff --git a/packages/statemanager/src/cache/account.ts b/packages/statemanager/src/cache/account.ts index 9100b513ec..216abeb54d 100644 --- a/packages/statemanager/src/cache/account.ts +++ b/packages/statemanager/src/cache/account.ts @@ -68,7 +68,7 @@ export class AccountCache extends Cache { put( address: Address, account: Account | undefined, - couldBeParitalAccount: boolean = false + couldBeParitalAccount: boolean = false, ): void { const addressHex = bytesToUnprefixedHex(address.bytes) this._saveCachePreState(addressHex) diff --git a/packages/statemanager/src/cache/cache.ts b/packages/statemanager/src/cache/cache.ts index 3be3a71215..d80c338a2a 100644 --- a/packages/statemanager/src/cache/cache.ts +++ b/packages/statemanager/src/cache/cache.ts @@ -29,7 +29,7 @@ export class Cache { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this._debug = debugDefault('statemanager:cache') } diff --git a/packages/statemanager/src/cache/storage.ts b/packages/statemanager/src/cache/storage.ts index a9625a1c3b..cf24607219 100644 --- a/packages/statemanager/src/cache/storage.ts +++ b/packages/statemanager/src/cache/storage.ts @@ -88,7 +88,7 @@ export class StorageCache extends Cache { this._debug( `Put storage for ${addressHex}: ${keyHex} -> ${ value !== undefined ? bytesToUnprefixedHex(value) : '' - }` + }`, ) } if (this._lruCache) { diff --git a/packages/statemanager/src/rpcStateManager.ts b/packages/statemanager/src/rpcStateManager.ts index 8b6862891a..3c4f9570d5 100644 --- a/packages/statemanager/src/rpcStateManager.ts +++ b/packages/statemanager/src/rpcStateManager.ts @@ -56,7 +56,7 @@ export class RPCStateManager implements EVMStateManagerInterface { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this._debug = debugDefault('statemanager:rpcStateManager') if (typeof opts.provider === 'string' && opts.provider.startsWith('http')) { @@ -306,7 +306,7 @@ export class RPCStateManager implements EVMStateManagerInterface { account?.balance } contract=${account && account.isContract() ? 'yes' : 'no'} empty=${ account && account.isEmpty() ? 'yes' : 'no' - }` + }`, ) } if (account !== undefined) { @@ -333,8 +333,8 @@ export class RPCStateManager implements EVMStateManagerInterface { if (k === 'nonce') return v.toString() return v }, - 2 - ) + 2, + ), ) } let account = await this.getAccount(address) diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index e4261d9163..25d7c93068 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -207,7 +207,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this._debug = debugDefault('statemanager:statemanager') @@ -297,7 +297,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { account?.balance } contract=${account && account.isContract() ? 'yes' : 'no'} empty=${ account && account.isEmpty() ? 'yes' : 'no' - }` + }`, ) } if (this._accountCacheSettings.deactivate) { @@ -431,7 +431,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { // TODO PR: have a better interface for hashed address pull? protected _getStorageTrie( addressOrHash: Address | { bytes: Uint8Array } | Uint8Array, - rootAccount?: Account + rootAccount?: Account, ): Trie { // use hashed key for lookup from storage cache const addressBytes: Uint8Array = @@ -513,7 +513,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { protected async _modifyContractStorage( address: Address, account: Account, - modifyTrie: (storageTrie: Trie, done: Function) => void + modifyTrie: (storageTrie: Trie, done: Function) => void, ): Promise { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve) => { @@ -536,7 +536,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { address: Address, account: Account, key: Uint8Array, - value: Uint8Array + value: Uint8Array, ) { await this._modifyContractStorage(address, account, async (storageTrie, done) => { if (value instanceof Uint8Array && value.length) { @@ -741,7 +741,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { return returnValue } const accountProof: PrefixedHexString[] = (await this._trie.createProof(address.bytes)).map( - (p) => bytesToHex(p) + (p) => bytesToHex(p), ) const storageProof: StorageProof[] = [] const storageTrie = this._getStorageTrie(address, account) @@ -780,7 +780,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { static async fromProof( proof: Proof | Proof[], safe: boolean = false, - opts: DefaultStateManagerOpts = {} + opts: DefaultStateManagerOpts = {}, ): Promise { if (Array.isArray(proof)) { if (proof.length === 0) { @@ -790,7 +790,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { opts.trie ?? (await createTrieFromProof( proof[0].accountProof.map((e) => hexToBytes(e)), - { useKeyHashing: true } + { useKeyHashing: true }, )) const sm = new DefaultStateManager({ ...opts, trie }) const address = Address.fromString(proof[0].address) @@ -818,14 +818,14 @@ export class DefaultStateManager implements EVMStateManagerInterface { storageProof: StorageProof[], storageHash: PrefixedHexString, address: Address, - safe: boolean = false + safe: boolean = false, ) { const trie = this._getStorageTrie(address) trie.root(hexToBytes(storageHash)) for (let i = 0; i < storageProof.length; i++) { await trie.updateFromProof( storageProof[i].proof.map((e) => hexToBytes(e)), - safe + safe, ) } } @@ -841,13 +841,13 @@ export class DefaultStateManager implements EVMStateManagerInterface { for (let i = 0; i < proof.length; i++) { await this._trie.updateFromProof( proof[i].accountProof.map((e) => hexToBytes(e)), - safe + safe, ) await this.addStorageProof( proof[i].storageProof, proof[i].storageHash, Address.fromString(proof[i].address), - safe + safe, ) } } else { @@ -862,7 +862,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { async verifyProof(proof: Proof): Promise { const key = hexToBytes(proof.address) const accountProof = proof.accountProof.map((rlpString: PrefixedHexString) => - hexToBytes(rlpString) + hexToBytes(rlpString), ) // This returns the account if the proof is valid. @@ -918,13 +918,13 @@ export class DefaultStateManager implements EVMStateManagerInterface { }) const reportedValue = setLengthLeft( RLP.decode(proofValue ?? new Uint8Array(0)) as Uint8Array, - 32 + 32, ) if (!equalsBytes(reportedValue, storageValue)) { throw new Error( `Reported trie value does not match storage, key: ${stProof.key}, reported: ${bytesToHex( - reportedValue - )}, actual: ${bytesToHex(storageValue)}` + reportedValue, + )}, actual: ${bytesToHex(storageValue)}`, ) } } diff --git a/packages/statemanager/src/statelessVerkleStateManager.ts b/packages/statemanager/src/statelessVerkleStateManager.ts index b3b604d19c..498842f074 100644 --- a/packages/statemanager/src/statelessVerkleStateManager.ts +++ b/packages/statemanager/src/statelessVerkleStateManager.ts @@ -239,7 +239,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } async getTransitionStateRoot(_: DefaultStateManager, __: Uint8Array): Promise { @@ -249,7 +249,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { public initVerkleExecutionWitness( blockNum: bigint, executionWitness?: VerkleExecutionWitness | null, - accessWitness?: AccessWitness + accessWitness?: AccessWitness, ) { this._blockNum = blockNum if (executionWitness === null || executionWitness === undefined) { @@ -316,7 +316,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { async checkChunkWitnessPresent(address: Address, codeOffset: number) { const chunkId = codeOffset / 31 const chunkKey = bytesToHex( - await getVerkleTreeKeyForCodeChunk(address, chunkId, this.verkleCrypto) + await getVerkleTreeKeyForCodeChunk(address, chunkId, this.verkleCrypto), ) return this._state[chunkKey] !== undefined } @@ -389,7 +389,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const chunks = Math.floor(codeSize / 31) + 1 for (let chunkId = 0; chunkId < chunks; chunkId++) { const chunkKey = bytesToHex( - await getVerkleTreeKeyForCodeChunk(address, chunkId, this.verkleCrypto) + await getVerkleTreeKeyForCodeChunk(address, chunkId, this.verkleCrypto), ) const codeChunk = this._state[chunkKey] if (codeChunk === null) { @@ -463,7 +463,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const storageKey = await getVerkleTreeKeyForStorageSlot( address, BigInt(bytesToHex(key)), - this.verkleCrypto + this.verkleCrypto, ) const storageValue = toBytes(this._state[bytesToHex(storageKey)]) @@ -489,7 +489,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const storageKey = await getVerkleTreeKeyForStorageSlot( address, BigInt(bytesToHex(key)), - this.verkleCrypto + this.verkleCrypto, ) this._state[bytesToHex(storageKey)] = bytesToHex(setLengthRight(value, 32)) } @@ -542,7 +542,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { typeof codeHashRaw === 'string' ) { const errorMsg = `Invalid witness for a non existing address=${address} stem=${bytesToHex( - stem + stem, )}` debug(errorMsg) throw Error(errorMsg) @@ -554,7 +554,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { // check if codehash is correct 32 bytes prefixed hex string if (codeHashRaw !== undefined && codeHashRaw !== null && codeHashRaw.length !== 66) { const errorMsg = `Invalid codeHashRaw=${codeHashRaw} for address=${address} chunkKey=${bytesToHex( - codeHashKey + codeHashKey, )}` debug(errorMsg) throw Error(errorMsg) @@ -584,8 +584,8 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { typeof codeSizeRaw === 'string' ? bytesToInt32(hexToBytes(codeSizeRaw), true) : codeSizeRaw === null - ? 0 - : null, + ? 0 + : null, storageRoot: null, }) @@ -695,7 +695,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { const computedValue = this.getComputedValue(accessedState) ?? this._preState[chunkKey] if (computedValue === undefined) { debug( - `Block accesses missing in canonical address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}` + `Block accesses missing in canonical address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}`, ) postFailures++ continue @@ -705,7 +705,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { if (canonicalValue === undefined) { debug( - `Block accesses missing in canonical address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}` + `Block accesses missing in canonical address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}`, ) postFailures++ continue @@ -738,7 +738,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { : `${canonicalValue} (${decodedCanonicalValue})` debug( - `Block accesses mismatch address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}` + `Block accesses mismatch address=${address} type=${type} ${extraMeta} chunkKey=${chunkKey}`, ) debug(`expected=${displayCanonicalValue}`) debug(`computed=${displayComputedValue}`) diff --git a/packages/statemanager/test/cache/account.spec.ts b/packages/statemanager/test/cache/account.spec.ts index 6570b3f62f..533f62d095 100644 --- a/packages/statemanager/test/cache/account.spec.ts +++ b/packages/statemanager/test/cache/account.spec.ts @@ -65,7 +65,7 @@ describe('Account Cache: checkpointing', () => { let elem = cache.get(addr) assert.ok( - elem !== undefined && elem.accountRLP && equalsBytes(elem.accountRLP, updatedAccRLP) + elem !== undefined && elem.accountRLP && equalsBytes(elem.accountRLP, updatedAccRLP), ) cache.revert() diff --git a/packages/statemanager/test/checkpointing.account.spec.ts b/packages/statemanager/test/checkpointing.account.spec.ts index 5222174b2c..edc19c25f1 100644 --- a/packages/statemanager/test/checkpointing.account.spec.ts +++ b/packages/statemanager/test/checkpointing.account.spec.ts @@ -12,7 +12,7 @@ import type { Account } from '@ethereumjs/util' const accountEval = async ( sm: StateManagerInterface, address: Address, - compare: bigint | undefined + compare: bigint | undefined, ) => { const account = await sm.getAccount(address) if (compare === undefined) { diff --git a/packages/statemanager/test/checkpointing.code.spec.ts b/packages/statemanager/test/checkpointing.code.spec.ts index 673451c1c3..ddda37eb50 100644 --- a/packages/statemanager/test/checkpointing.code.spec.ts +++ b/packages/statemanager/test/checkpointing.code.spec.ts @@ -8,7 +8,7 @@ const codeEval = async ( sm: StateManagerInterface, address: Address, value: Uint8Array, - root: Uint8Array + root: Uint8Array, ) => { assert.deepEqual(await sm.getContractCode(address), value, 'contract code value should be equal') const accountCMP = await sm.getAccount(address) diff --git a/packages/statemanager/test/checkpointing.storage.spec.ts b/packages/statemanager/test/checkpointing.storage.spec.ts index 0e6d5a2a1e..21a8613746 100644 --- a/packages/statemanager/test/checkpointing.storage.spec.ts +++ b/packages/statemanager/test/checkpointing.storage.spec.ts @@ -11,12 +11,12 @@ const storageEval = async ( key: Uint8Array, value: Uint8Array, root: Uint8Array, - rootCheck = true + rootCheck = true, ) => { assert.deepEqual( await sm.getContractStorage(address, key), value, - 'storage value should be equal' + 'storage value should be equal', ) if (rootCheck) { const accountCMP = await sm.getAccount(address) diff --git a/packages/statemanager/test/proofStateManager.spec.ts b/packages/statemanager/test/proofStateManager.spec.ts index 1be393a655..9bc74fdd86 100644 --- a/packages/statemanager/test/proofStateManager.spec.ts +++ b/packages/statemanager/test/proofStateManager.spec.ts @@ -101,7 +101,7 @@ describe('ProofStateManager', () => { assert.equal( await stateManager.verifyProof(nonExistenceProof), true, - 'verified proof of non-existence of account' + 'verified proof of non-existence of account', ) }) diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index e563feacc6..1e425abbe8 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -49,20 +49,20 @@ describe('RPC State Manager initialization tests', async () => { assert.equal( (state as any)._blockTag, '0x1', - 'State manager starts with default block tag of 1' + 'State manager starts with default block tag of 1', ) state = new RPCStateManager({ provider, blockTag: 1n }) assert.equal( (state as any)._blockTag, '0x1', - 'State Manager instantiated with predefined blocktag' + 'State Manager instantiated with predefined blocktag', ) state = new RPCStateManager({ provider: 'https://google.com', blockTag: 1n }) assert.ok( state instanceof RPCStateManager, - 'was able to instantiate state manager with valid url' + 'was able to instantiate state manager with valid url', ) const invalidProvider = 'google.com' @@ -70,7 +70,7 @@ describe('RPC State Manager initialization tests', async () => { () => new RPCStateManager({ provider: invalidProvider as any, blockTag: 1n }), undefined, undefined, - 'cannot instantiate state manager with invalid provider' + 'cannot instantiate state manager with invalid provider', ) }) }) @@ -86,12 +86,12 @@ describe('RPC State Manager API tests', () => { await state.putAccount(vitalikDotEth, account!) const retrievedVitalikAccount = createAccountFromRLP( - (state as any)._accountCache.get(vitalikDotEth)!.accountRLP + (state as any)._accountCache.get(vitalikDotEth)!.accountRLP, ) assert.ok(retrievedVitalikAccount.nonce > 0n, 'Vitalik.eth is stored in cache') const doesThisAccountExist = await state.accountExists( - Address.fromString('0xccAfdD642118E5536024675e776d32413728DD07') + Address.fromString('0xccAfdD642118E5536024675e776d32413728DD07'), ) assert.ok(!doesThisAccountExist, 'getAccount returns undefined for non-existent account') @@ -104,12 +104,12 @@ describe('RPC State Manager API tests', () => { await state.putContractCode(UNIerc20ContractAddress, UNIContractCode) assert.ok( typeof (state as any)._contractCache.get(UNIerc20ContractAddress.toString()) !== 'undefined', - 'UNI ERC20 contract code was found in cache' + 'UNI ERC20 contract code was found in cache', ) const storageSlot = await state.getContractStorage( UNIerc20ContractAddress, - setLengthLeft(bigIntToBytes(1n), 32) + setLengthLeft(bigIntToBytes(1n), 32), ) assert.ok(storageSlot.length > 0, 'was able to retrieve storage slot 1 for the UNI contract') @@ -120,11 +120,11 @@ describe('RPC State Manager API tests', () => { await state.putContractStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), - utf8ToBytes('abcd') + utf8ToBytes('abcd'), ) const slotValue = await state.getContractStorage( UNIerc20ContractAddress, - setLengthLeft(bigIntToBytes(2n), 32) + setLengthLeft(bigIntToBytes(2n), 32), ) assert.ok(equalsBytes(slotValue, utf8ToBytes('abcd')), 'should retrieve slot 2 value') @@ -144,19 +144,19 @@ describe('RPC State Manager API tests', () => { await state.putContractStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), - new Uint8Array(0) + new Uint8Array(0), ) await state.modifyAccountFields(vitalikDotEth, { nonce: 39n }) assert.equal( (await state.getAccount(vitalikDotEth))?.nonce, 39n, - 'modified account fields successfully' + 'modified account fields successfully', ) assert.doesNotThrow( async () => state.getAccount(vitalikDotEth), - 'does not call getAccountFromProvider' + 'does not call getAccountFromProvider', ) try { @@ -167,7 +167,7 @@ describe('RPC State Manager API tests', () => { const deletedSlot = await state.getContractStorage( UNIerc20ContractAddress, - setLengthLeft(bigIntToBytes(2n), 32) + setLengthLeft(bigIntToBytes(2n), 32), ) assert.equal(deletedSlot.length, 0, 'deleted slot from storage cache') @@ -175,31 +175,31 @@ describe('RPC State Manager API tests', () => { await state.deleteAccount(vitalikDotEth) assert.ok( (await state.getAccount(vitalikDotEth)) === undefined, - 'account should not exist after being deleted' + 'account should not exist after being deleted', ) await state.revert() assert.ok( (await state.getAccount(vitalikDotEth)) !== undefined, - 'account deleted since last checkpoint should exist after revert called' + 'account deleted since last checkpoint should exist after revert called', ) const deletedSlotAfterRevert = await state.getContractStorage( UNIerc20ContractAddress, - setLengthLeft(bigIntToBytes(2n), 32) + setLengthLeft(bigIntToBytes(2n), 32), ) assert.equal( deletedSlotAfterRevert.length, 4, - 'slot deleted since last checkpoint should exist in storage cache after revert' + 'slot deleted since last checkpoint should exist in storage cache after revert', ) const cacheStorage = await state.dumpStorage(UNIerc20ContractAddress) assert.equal( 2, Object.keys(cacheStorage).length, - 'should have 2 storage slots in cache before clear' + 'should have 2 storage slots in cache before clear', ) await state.clearContractStorage(UNIerc20ContractAddress) const clearedStorage = await state.dumpStorage(UNIerc20ContractAddress) @@ -211,14 +211,14 @@ describe('RPC State Manager API tests', () => { } catch (err: any) { assert.ok( err.message.includes('expected blockTag to be block hash, bigint, hex prefixed string'), - 'threw with correct error when invalid blockTag provided' + 'threw with correct error when invalid blockTag provided', ) } assert.equal( (state as any)._contractCache.get(UNIerc20ContractAddress), undefined, - 'should not have any code for contract after cache is reverted' + 'should not have any code for contract after cache is reverted', ) assert.equal((state as any)._blockTag, '0x1', 'blockTag defaults to 1') @@ -240,11 +240,11 @@ describe('runTx custom transaction test', () => { const vitalikDotEth = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const tx = create1559FeeMarketTx( { to: vitalikDotEth, value: '0x100', gasLimit: 500000n, maxFeePerGas: 7 }, - { common } + { common }, ).sign(privateKey) const result = await runTx(vm, { @@ -274,7 +274,7 @@ describe('runTx test: replay mainnet transactions', () => { assert.equal( res.totalGasSpent, 21000n, - 'calculated correct total gas spent for simple transfer' + 'calculated correct total gas spent for simple transfer', ) }) }) @@ -305,7 +305,7 @@ describe('runBlock test', () => { assert.equal( res.gasUsed, block.header.gasUsed, - 'should compute correct cumulative gas for block' + 'should compute correct cumulative gas for block', ) } catch (err: any) { assert.fail(`should have successfully ran block; got error ${err.message}`) @@ -325,7 +325,7 @@ describe('blockchain', () => const caller = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') await evm.stateManager.setStateRoot( - hexToBytes('0xf8506f559699a58a4724df4fcf2ad4fd242d20324db541823f128f5974feb6c7') + hexToBytes('0xf8506f559699a58a4724df4fcf2ad4fd242d20324db541823f128f5974feb6c7'), ) const block = await createBlockFromJsonRpcProvider(provider, 500000n, { setHardfork: true }) await evm.stateManager.putContractCode(contractAddress, hexToBytes(code)) @@ -338,7 +338,7 @@ describe('blockchain', () => const res = await evm.runCall(runCallArgs) assert.ok( bytesToHex(res.execResult.returnValue), - '0xd5ba853bc7151fc044b9d273a57e3f9ed35e66e0248ab4a571445650cc4fcaa6' + '0xd5ba853bc7151fc044b9d273a57e3f9ed35e66e0248ab4a571445650cc4fcaa6', ) })) @@ -352,7 +352,7 @@ describe('Should return same value as DefaultStateManager when account does not assert.equal( account0, account1, - 'Should return same value as DefaultStateManager when account does not exist' + 'Should return same value as DefaultStateManager when account does not exist', ) }) }) diff --git a/packages/statemanager/test/stateManager.account.spec.ts b/packages/statemanager/test/stateManager.account.spec.ts index 5da058107b..9b4b01989a 100644 --- a/packages/statemanager/test/stateManager.account.spec.ts +++ b/packages/statemanager/test/stateManager.account.spec.ts @@ -62,7 +62,7 @@ describe('StateManager -> General/Account', () => { const contract0 = await stateManager.getContractStorage(address, key) assert.ok( equalsBytes(contract0, value), - "contract key's value is set in the _storageTries cache" + "contract key's value is set in the _storageTries cache", ) await stateManager.commit() @@ -135,7 +135,7 @@ describe('StateManager -> General/Account', () => { await stateManager.modifyAccountFields(address, { codeHash: hexToBytes('0xd748bf26ab37599c944babfdbeecf6690801bd61bf2670efb0a34adfc6dca10b'), storageRoot: hexToBytes( - '0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7' + '0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7', ), }) @@ -143,11 +143,11 @@ describe('StateManager -> General/Account', () => { assert.equal( bytesToHex(res3!.codeHash), - '0xd748bf26ab37599c944babfdbeecf6690801bd61bf2670efb0a34adfc6dca10b' + '0xd748bf26ab37599c944babfdbeecf6690801bd61bf2670efb0a34adfc6dca10b', ) assert.equal( bytesToHex(res3!.storageRoot), - '0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7' + '0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7', ) }) } diff --git a/packages/statemanager/test/stateManager.code.spec.ts b/packages/statemanager/test/stateManager.code.spec.ts index 3ceea7791c..98e713b23c 100644 --- a/packages/statemanager/test/stateManager.code.spec.ts +++ b/packages/statemanager/test/stateManager.code.spec.ts @@ -84,7 +84,7 @@ describe('StateManager -> Code', () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) const code = hexToBytes( - '0x73095e7baea6a6c7c4c2dfeb977efac326af552d873173095e7baea6a6c7c4c2dfeb977efac326af552d873157' + '0x73095e7baea6a6c7c4c2dfeb977efac326af552d873173095e7baea6a6c7c4c2dfeb977efac326af552d873157', ) const raw: AccountData = { nonce: '0x0', diff --git a/packages/statemanager/test/stateManager.spec.ts b/packages/statemanager/test/stateManager.spec.ts index bd8cf6dc4d..9c1b019f3d 100644 --- a/packages/statemanager/test/stateManager.spec.ts +++ b/packages/statemanager/test/stateManager.spec.ts @@ -24,7 +24,7 @@ function verifyAccount( codeHash: Uint8Array nonce: BigInt storageRoot: Uint8Array - } + }, ) { assert.equal(account.balance, state.balance) assert.equal(account.nonce, state.nonce) @@ -60,7 +60,7 @@ describe('StateManager -> General', () => { assert.equal( JSON.stringify(storage), JSON.stringify(new Uint8Array()), - 'clears contract storage' + 'clears contract storage', ) }) @@ -75,7 +75,7 @@ describe('StateManager -> General', () => { assert.equal( smCopy['_prefixCodeHashes'], sm['_prefixCodeHashes'], - 'should retain non-default values' + 'should retain non-default values', ) sm = new DefaultStateManager({ @@ -92,12 +92,12 @@ describe('StateManager -> General', () => { assert.equal( smCopy['_accountCacheSettings'].type, CacheType.ORDERED_MAP, - 'should switch to ORDERED_MAP account cache on copy()' + 'should switch to ORDERED_MAP account cache on copy()', ) assert.equal( smCopy['_storageCacheSettings'].type, CacheType.ORDERED_MAP, - 'should switch to ORDERED_MAP storage cache on copy()' + 'should switch to ORDERED_MAP storage cache on copy()', ) assert.equal(smCopy['_trie']['_opts'].cacheSize, 0, 'should set trie cache size to 0') @@ -105,17 +105,17 @@ describe('StateManager -> General', () => { assert.equal( smCopy['_accountCacheSettings'].type, CacheType.LRU, - 'should retain account cache type when deactivate cache downleveling' + 'should retain account cache type when deactivate cache downleveling', ) assert.equal( smCopy['_storageCacheSettings'].type, CacheType.LRU, - 'should retain storage cache type when deactivate cache downleveling' + 'should retain storage cache type when deactivate cache downleveling', ) assert.equal( smCopy['_trie']['_opts'].cacheSize, 1000, - 'should retain trie cache size when deactivate cache downleveling' + 'should retain trie cache size when deactivate cache downleveling', ) }) @@ -304,12 +304,12 @@ describe('StateManager -> General', () => { const keys = Object.keys(storage) as PrefixedHexString[] const proof = await sm.getProof( address, - keys.map((key) => hexToBytes(key)) + keys.map((key) => hexToBytes(key)), ) const proof2 = await sm.getProof(address2) const newTrie = await createTrieFromProof( proof.accountProof.map((e) => hexToBytes(e)), - { useKeyHashing: false } + { useKeyHashing: false }, ) const partialSM = await DefaultStateManager.fromProof([proof, proof2], true, { trie: newTrie, @@ -317,11 +317,11 @@ describe('StateManager -> General', () => { assert.equal( partialSM['_trie']['_opts'].useKeyHashing, false, - 'trie opts are preserved in new sm' + 'trie opts are preserved in new sm', ) assert.deepEqual( intToBytes(32), - await partialSM.getContractStorage(address, hexToBytes(keys[0])) + await partialSM.getContractStorage(address, hexToBytes(keys[0])), ) assert.equal((await partialSM.getAccount(address2))?.balance, 100n) const partialSM2 = await DefaultStateManager.fromProof(proof, true, { @@ -331,13 +331,13 @@ describe('StateManager -> General', () => { assert.equal( partialSM2['_trie']['_opts'].useKeyHashing, false, - 'trie opts are preserved in new sm' + 'trie opts are preserved in new sm', ) assert.deepEqual( intToBytes(32), - await partialSM2.getContractStorage(address, hexToBytes(keys[0])) + await partialSM2.getContractStorage(address, hexToBytes(keys[0])), ) assert.equal((await partialSM2.getAccount(address2))?.balance, 100n) - } + }, ) }) diff --git a/packages/statemanager/test/statelessVerkleStateManager.spec.ts b/packages/statemanager/test/statelessVerkleStateManager.spec.ts index e78030455e..76c36e0dfd 100644 --- a/packages/statemanager/test/statelessVerkleStateManager.spec.ts +++ b/packages/statemanager/test/statelessVerkleStateManager.spec.ts @@ -33,13 +33,13 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { eips: [2935, 4895, 6800], }) const decodedTxs = verkleBlockJSON.transactions.map((tx) => - createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)) + createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)), ) const block = createBlockFromBlockData( { ...verkleBlockJSON, transactions: decodedTxs } as BlockData, { common, - } + }, ) it('initPreState()', async () => { @@ -54,7 +54,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { stateManager.initVerkleExecutionWitness(block.header.number, block.executionWitness) const account = await stateManager.getAccount( - Address.fromString('0x6177843db3138ae69679a54b95cf345ed759450d') + Address.fromString('0x6177843db3138ae69679a54b95cf345ed759450d'), ) assert.equal(account!.balance, 288610978528114322n, 'should have correct balance') @@ -63,7 +63,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.equal( bytesToHex(account!.codeHash), '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', - 'should have correct codeHash' + 'should have correct codeHash', ) }) @@ -80,7 +80,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.equal( e.message.slice(0, 25), 'No witness bundled for ad', - 'should throw on getting account that does not exist in cache and witness' + 'should throw on getting account that does not exist in cache and witness', ) } @@ -92,7 +92,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.deepEqual( await stateManager.getAccount(address), account, - 'should return correct account' + 'should return correct account', ) await stateManager.modifyAccountFields(address, { @@ -102,14 +102,14 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.deepEqual( await stateManager.getAccount(address), account, - 'should return correct account' + 'should return correct account', ) await stateManager.deleteAccount(address) assert.isUndefined( await stateManager.getAccount(address), - 'should return undefined for deleted account' + 'should return undefined for deleted account', ) }) @@ -133,12 +133,12 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.equal( account!.balance, bytesToBigInt(hexToBytes(balanceRaw!), true), - 'should have correct balance' + 'should have correct balance', ) assert.equal( account!.nonce, bytesToBigInt(hexToBytes(nonceRaw!), true), - 'should have correct nonce' + 'should have correct nonce', ) assert.equal(bytesToHex(account!.codeHash), codeHash, 'should have correct codeHash') }) @@ -161,12 +161,12 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { assert.equal( (stateManagerCopy as any)['_accountCacheSettings'].type, CacheType.ORDERED_MAP, - 'should switch to ORDERED_MAP account cache on copy()' + 'should switch to ORDERED_MAP account cache on copy()', ) assert.equal( (stateManagerCopy as any)['_storageCacheSettings'].type, CacheType.ORDERED_MAP, - 'should switch to ORDERED_MAP storage cache on copy()' + 'should switch to ORDERED_MAP storage cache on copy()', ) }) @@ -181,11 +181,11 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { await stateManager.putContractStorage( contractAddress, hexToBytes(storageKey), - hexToBytes(storageValue) + hexToBytes(storageValue), ) let contractStorage = await stateManager.getContractStorage( contractAddress, - hexToBytes(storageKey) + hexToBytes(storageKey), ) assert.equal(bytesToHex(contractStorage), storageValue) diff --git a/packages/statemanager/test/testdata/providerData/mockProvider.ts b/packages/statemanager/test/testdata/providerData/mockProvider.ts index 4e56e4d128..c984b0835e 100644 --- a/packages/statemanager/test/testdata/providerData/mockProvider.ts +++ b/packages/statemanager/test/testdata/providerData/mockProvider.ts @@ -17,7 +17,7 @@ export type JsonReturnType = { export const getValues = async ( method: Method, id: number, - params: any[] + params: any[], ): Promise => { switch (method) { case 'eth_getProof': diff --git a/packages/statemanager/test/vmState.spec.ts b/packages/statemanager/test/vmState.spec.ts index 79b73acca5..d486f191ca 100644 --- a/packages/statemanager/test/vmState.spec.ts +++ b/packages/statemanager/test/vmState.spec.ts @@ -20,7 +20,7 @@ describe('stateManager', () => { return } const expectedStateRoot = hexToBytes( - '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' + '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544', ) const stateManager = new StateManager({}) @@ -30,7 +30,7 @@ describe('stateManager', () => { assert.deepEqual( stateRoot, expectedStateRoot, - `generateCanonicalGenesis should produce correct state root for mainnet from common` + `generateCanonicalGenesis should produce correct state root for mainnet from common`, ) }) @@ -55,7 +55,7 @@ describe('stateManager', () => { assert.deepEqual( stateRoot, expectedStateRoot, - `generateCanonicalGenesis should produce correct state root for ${Chain[chain]}` + `generateCanonicalGenesis should produce correct state root for ${Chain[chain]}`, ) } }) diff --git a/packages/statemanager/tsconfig.lint.json b/packages/statemanager/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/statemanager/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/trie/.eslintrc.cjs b/packages/trie/.eslintrc.cjs index 884b3d6ebe..4a13163a7d 100644 --- a/packages/trie/.eslintrc.cjs +++ b/packages/trie/.eslintrc.cjs @@ -1,11 +1,11 @@ module.exports = { extends: '../../config/eslint.cjs', parserOptions: { - project: ['./tsconfig.json', './tsconfig.benchmarks.json'], + project: ['./tsconfig.lint.json'], }, overrides: [ { - files: ['benchmarks/*.ts'], + files: ['benchmarks/*.ts', 'examples/**/*'], rules: { 'no-console': 'off', }, diff --git a/packages/trie/examples/basicUsage.ts b/packages/trie/examples/basicUsage.ts index b669197bf9..5a008b3b8b 100644 --- a/packages/trie/examples/basicUsage.ts +++ b/packages/trie/examples/basicUsage.ts @@ -1,5 +1,5 @@ -import { createTrie, Trie } from '@ethereumjs/trie' -import { bytesToUtf8, MapDB, utf8ToBytes } from '@ethereumjs/util' +import { createTrie } from '@ethereumjs/trie' +import { MapDB, bytesToUtf8, utf8ToBytes } from '@ethereumjs/util' async function test() { const trie = await createTrie({ db: new MapDB() }) @@ -8,4 +8,4 @@ async function test() { console.log(value ? bytesToUtf8(value) : 'not found') // 'one' } -test() +void test() diff --git a/packages/trie/examples/createFromProof.ts b/packages/trie/examples/createFromProof.ts index 4b3cb284d5..f3db4f5867 100644 --- a/packages/trie/examples/createFromProof.ts +++ b/packages/trie/examples/createFromProof.ts @@ -1,6 +1,5 @@ import { Trie, createTrieFromProof } from '@ethereumjs/trie' -import { bytesToUtf8 } from '@ethereumjs/util' -import { utf8ToBytes } from '@ethereumjs/util' +import { bytesToUtf8, utf8ToBytes } from '@ethereumjs/util' async function main() { const k1 = utf8ToBytes('keyOne') @@ -23,4 +22,4 @@ async function main() { console.log(bytesToUtf8(otherValue!)) // valueTwo } -main() +void main() diff --git a/packages/trie/examples/customLevelDB.ts b/packages/trie/examples/customLevelDB.ts index a4ca04b502..0ed657cb71 100644 --- a/packages/trie/examples/customLevelDB.ts +++ b/packages/trie/examples/customLevelDB.ts @@ -1,7 +1,6 @@ import { Trie } from '@ethereumjs/trie' -import { Level } from 'level' - import { KeyEncoding, ValueEncoding } from '@ethereumjs/util' +import { Level } from 'level' import { MemoryLevel } from 'memory-level' import type { BatchDBOp, DB, DBObject, EncodingOpts } from '@ethereumjs/util' @@ -44,7 +43,7 @@ const getEncodings = (opts: EncodingOpts = {}) => { */ export class LevelDB< TKey extends Uint8Array | string = Uint8Array | string, - TValue extends Uint8Array | string | DBObject = Uint8Array | string | DBObject + TValue extends Uint8Array | string | DBObject = Uint8Array | string | DBObject, > implements DB { _leveldb: AbstractLevel @@ -55,7 +54,7 @@ export class LevelDB< * @param leveldb - An abstract-leveldown compliant store */ constructor( - leveldb?: AbstractLevel + leveldb?: AbstractLevel, ) { this._leveldb = leveldb ?? new MemoryLevel() } @@ -126,6 +125,6 @@ export class LevelDB< async function main() { const trie = new Trie({ db: new LevelDB(new Level('MY_TRIE_DB_LOCATION') as any) }) - console.log(await trie.database().db) // LevelDB { ... + console.log(trie.database().db) // LevelDB { ... } -main() +void main() diff --git a/packages/trie/examples/level-legacy.js b/packages/trie/examples/level-legacy.js index 5f2dfeffd9..196a93cb4e 100644 --- a/packages/trie/examples/level-legacy.js +++ b/packages/trie/examples/level-legacy.js @@ -1,9 +1,10 @@ // LevelDB from https://github.com/ethereumjs/ethereumjs-monorepo/blob/ac053e1f9a364f8ae489159fecb79a3d0ddd7053/packages/trie/src/db.ts // eslint-disable-next-line implicit-dependencies/no-implicit +const { utf8ToBytes, bytesToUtf8 } = require('ethereum-cryptography/utils') const level = require('level-mem') -const { Trie } = require('../dist') +const { Trie } = require('../../dist/cjs/index.js') const ENCODING_OPTS = { keyEncoding: 'binary', valueEncoding: 'binary' } @@ -19,7 +20,7 @@ class LevelDB { try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error) { - if (error.notFound) { + if (error.notFound !== undefined) { // not found, returning null } else { throw error @@ -48,9 +49,9 @@ class LevelDB { const trie = new Trie({ db: new LevelDB(level('MY_TRIE_DB_LOCATION')) }) async function test() { - await trie.put(Buffer.from('test'), Buffer.from('one')) - const value = await trie.get(Buffer.from('test')) - console.log(value.toString()) // 'one' + await trie.put(utf8ToBytes('test'), utf8ToBytes('one')) + const value = await trie.get(utf8ToBytes('test')) + console.log(bytesToUtf8(value)) // 'one' } -test() +void test() diff --git a/packages/trie/examples/level.js b/packages/trie/examples/level.js index 43edb67780..b67f57f491 100644 --- a/packages/trie/examples/level.js +++ b/packages/trie/examples/level.js @@ -1,7 +1,8 @@ +const { utf8ToBytes, bytesToUtf8 } = require('ethereum-cryptography/utils') const { Level } = require('level') const { MemoryLevel } = require('memory-level') -const { Trie } = require('../dist') +const { Trie } = require('../../dist/cjs/index.js') const ENCODING_OPTS = { keyEncoding: 'view', valueEncoding: 'view' } @@ -46,9 +47,9 @@ class LevelDB { const trie = new Trie({ db: new LevelDB(new Level('MY_TRIE_DB_LOCATION')) }) async function test() { - await trie.put(Buffer.from('test'), Buffer.from('one')) - const value = await trie.get(Buffer.from('test')) - console.log(value.toString()) // 'one' + await trie.put(utf8ToBytes('test'), utf8ToBytes('one')) + const value = await trie.get(utf8ToBytes('test')) + console.log(bytesToUtf8(value)) // 'one' } -test() +void test() diff --git a/packages/trie/examples/lmdb.js b/packages/trie/examples/lmdb.js index dd5bee3438..73da2d99ed 100644 --- a/packages/trie/examples/lmdb.js +++ b/packages/trie/examples/lmdb.js @@ -1,6 +1,7 @@ +const { utf8ToBytes, bytesToUtf8 } = require('ethereum-cryptography/utils') const { open } = require('lmdb') -const { Trie } = require('../dist') +const { Trie } = require('../../dist/cjs/index.js') class LMDB { constructor(path) { @@ -44,9 +45,9 @@ class LMDB { const trie = new Trie({ db: new LMDB('MY_TRIE_DB_LOCATION') }) async function test() { - await trie.put(Buffer.from('test'), Buffer.from('one')) - const value = await trie.get(Buffer.from('test')) - console.log(value.toString()) // 'one' + await trie.put(utf8ToBytes('test'), utf8ToBytes('one')) + const value = await trie.get(utf8ToBytes('test')) + console.log(bytesToUtf8(value)) // 'one' } -test() +void test() diff --git a/packages/trie/examples/logDemo.ts b/packages/trie/examples/logDemo.ts index f3b77fe7a5..536ec7e2a0 100644 --- a/packages/trie/examples/logDemo.ts +++ b/packages/trie/examples/logDemo.ts @@ -1,8 +1,8 @@ /** * Run with DEBUG=ethjs,trie:* to see debug log ouput */ -import { utf8ToBytes } from '@ethereumjs/util' import { Trie } from '@ethereumjs/trie' +import { utf8ToBytes } from '@ethereumjs/util' const trie_entries: [string, string | null][] = [ ['do', 'verb'], @@ -27,4 +27,4 @@ const main = async () => { console.log('valid', valid) } -main() +void main() diff --git a/packages/trie/examples/merkle_patricia_trees/example1a.js b/packages/trie/examples/merkle_patricia_trees/example1a.js index 4b70ee7160..4ee751e9fc 100644 --- a/packages/trie/examples/merkle_patricia_trees/example1a.js +++ b/packages/trie/examples/merkle_patricia_trees/example1a.js @@ -1,8 +1,9 @@ /* Example 1a - Creating and Updating a Base Trie*/ -const { Trie } = require('../../dist/cjs') // We import the library required to create a basic Merkle Patricia Tree const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') // We import the library required to create a basic Merkle Patricia Tree + const trie = new Trie() // We create an empty Merkle Patricia Tree console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) @@ -16,7 +17,7 @@ async function test() { console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) } -test() +void test() /* Results: diff --git a/packages/trie/examples/merkle_patricia_trees/example1b.js b/packages/trie/examples/merkle_patricia_trees/example1b.js index a7c690b832..fb320edc87 100644 --- a/packages/trie/examples/merkle_patricia_trees/example1b.js +++ b/packages/trie/examples/merkle_patricia_trees/example1b.js @@ -1,9 +1,10 @@ /* Example 1b - Manually Creating and Updating a Secure Trie*/ -const { Trie } = require('../../dist/cjs') const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') const { keccak256 } = require('ethereum-cryptography/keccak') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) @@ -15,7 +16,7 @@ async function test() { console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) } -test() +void test() /* Results: diff --git a/packages/trie/examples/merkle_patricia_trees/example1c.js b/packages/trie/examples/merkle_patricia_trees/example1c.js index 64f2c02e54..01c175cfbc 100644 --- a/packages/trie/examples/merkle_patricia_trees/example1c.js +++ b/packages/trie/examples/merkle_patricia_trees/example1c.js @@ -1,8 +1,8 @@ /* Example 1c - Creating an empty Merkle Patricia Tree and updating it with a single key-value pair */ - -const { Trie } = require('../../dist/cjs') const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie({ useKeyHashing: true }) // We create an empty Merkle Patricia Tree with key hashing enabled console.log('Empty trie root (Bytes): ', bytesToHex(trie.root())) // The trie root (32 bytes) @@ -14,7 +14,7 @@ async function test() { console.log('Updated trie root:', bytesToHex(trie.root())) // The new trie root (32 bytes) } -test() +void test() /* Results: diff --git a/packages/trie/examples/merkle_patricia_trees/example1d.js b/packages/trie/examples/merkle_patricia_trees/example1d.js index d205a6f183..892aef301e 100644 --- a/packages/trie/examples/merkle_patricia_trees/example1d.js +++ b/packages/trie/examples/merkle_patricia_trees/example1d.js @@ -1,8 +1,9 @@ /* Example 1d - Deleting a Key-Value Pair from a Trie*/ -const { Trie } = require('../../dist/cjs') const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() console.log('Empty trie root: ', bytesToHex(trie.root())) // The trie root @@ -20,7 +21,7 @@ async function test() { console.log('Trie root after deletion:', bytesToHex(trie.root())) // Our trie root is back to its initial value } -test() +void test() /* Results: diff --git a/packages/trie/examples/merkle_patricia_trees/example2a.js b/packages/trie/examples/merkle_patricia_trees/example2a.js index 5ce8c3f514..d83537fba9 100644 --- a/packages/trie/examples/merkle_patricia_trees/example2a.js +++ b/packages/trie/examples/merkle_patricia_trees/example2a.js @@ -1,8 +1,9 @@ // Example 2a - Creating and looking up a null node -const { Trie } = require('../../dist/cjs') const { utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() async function test() { @@ -10,7 +11,7 @@ async function test() { console.log('Node 1: ', node1.node) // null } -test() +void test() /* Result: diff --git a/packages/trie/examples/merkle_patricia_trees/example2b.js b/packages/trie/examples/merkle_patricia_trees/example2b.js index e607b94e0a..1906d0ab48 100644 --- a/packages/trie/examples/merkle_patricia_trees/example2b.js +++ b/packages/trie/examples/merkle_patricia_trees/example2b.js @@ -1,8 +1,9 @@ // Example 2b - Creating and looking up a branch node -const { Trie } = require('../../dist/cjs') const { bytesToHex, bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() async function test() { @@ -31,13 +32,13 @@ async function test() { 'Node 1 branch 3 (hex): path: ', bytesToHex(node1.node._branches[3][0]), ' | value: ', - bytesToHex(node1.node._branches[3][1]) + bytesToHex(node1.node._branches[3][1]), ) console.log( 'Node 1 branch 4 (hex): path: ', bytesToHex(node1.node._branches[4][0]), ' | value:', - bytesToHex(node1.node._branches[4][1]) + bytesToHex(node1.node._branches[4][1]), ) console.log('Value of branch at index 3: ', bytesToUtf8(node1.node._branches[3][1])) @@ -47,4 +48,4 @@ async function test() { console.log('Node 2: ', node2.node) } -test() +void test() diff --git a/packages/trie/examples/merkle_patricia_trees/example2c.js b/packages/trie/examples/merkle_patricia_trees/example2c.js index 3259817050..cb4f9381f6 100644 --- a/packages/trie/examples/merkle_patricia_trees/example2c.js +++ b/packages/trie/examples/merkle_patricia_trees/example2c.js @@ -1,8 +1,9 @@ // Example 2c - Creating and looking up a leaf node -const { Trie } = require('../../dist/cjs') const { bytesToUtf8, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() async function test() { @@ -14,4 +15,4 @@ async function test() { console.log('Node 1 value: ', bytesToUtf8(node1.node._value)) // The leaf node's value } -test() +void test() diff --git a/packages/trie/examples/merkle_patricia_trees/example2d.js b/packages/trie/examples/merkle_patricia_trees/example2d.js index ac9933ec3a..6ecaabeec7 100644 --- a/packages/trie/examples/merkle_patricia_trees/example2d.js +++ b/packages/trie/examples/merkle_patricia_trees/example2d.js @@ -1,8 +1,9 @@ // Example 2d - Creating and looking up an extension node -const { Trie } = require('../../dist/cjs') const { bytesToHex, utf8ToBytes } = require('@ethereumjs/util') +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() async function test() { @@ -25,4 +26,4 @@ async function test() { console.log(node3) } -test() +void test() diff --git a/packages/trie/examples/merkle_patricia_trees/example3a.js b/packages/trie/examples/merkle_patricia_trees/example3a.js index ea4a8b1747..688fface41 100644 --- a/packages/trie/examples/merkle_patricia_trees/example3a.js +++ b/packages/trie/examples/merkle_patricia_trees/example3a.js @@ -1,9 +1,11 @@ // Example 3a - Generating a hash -const { Trie } = require('../../dist/cjs') const rlp = require('@ethereumjs/rlp') const { bytesToHex, utf8ToBytes } = require('@ethereumjs/util') const { keccak256 } = require('ethereum-cryptography/keccak') + +const { Trie } = require('../../dist/cjs/index.js') + const trie = new Trie() async function test() { @@ -24,7 +26,7 @@ async function test() { 'path: ', bytesToHex(node3._branches[4][0]), ' | value: ', - bytesToHex(node3._branches[4][1]) + bytesToHex(node3._branches[4][1]), ) console.log('Raw node:', bytesToHex(rlp.encode(node2.raw()))) @@ -32,4 +34,4 @@ async function test() { console.log('The extension node hash: ', bytesToHex(node1.node._branches[3])) } -test() +void test() diff --git a/packages/trie/examples/merkle_patricia_trees/example3b.js b/packages/trie/examples/merkle_patricia_trees/example3b.js index bbb2605cd8..6fa833ba58 100644 --- a/packages/trie/examples/merkle_patricia_trees/example3b.js +++ b/packages/trie/examples/merkle_patricia_trees/example3b.js @@ -1,7 +1,9 @@ // Example 3b - Verification using a hash -const { Trie } = require('../../dist/cjs') const { bytesToHex, utf8ToBytes } = require('@ethereumjs/util') + +const { Trie } = require('../../dist/cjs/index.js') + const trie1 = new Trie() const trie2 = new Trie() @@ -27,4 +29,4 @@ async function test() { console.log('Root of trie 2: ', bytesToHex(trie2.root())) } -test() +void test() diff --git a/packages/trie/examples/merkle_patricia_trees/example4a.js b/packages/trie/examples/merkle_patricia_trees/example4a.js index 3d940e470f..c649c661d3 100644 --- a/packages/trie/examples/merkle_patricia_trees/example4a.js +++ b/packages/trie/examples/merkle_patricia_trees/example4a.js @@ -1,8 +1,9 @@ // Example 4a - Retrieving a Transaction from the Ethereum Blockchain -const INFURA_ENDPOINT = require('./infura_endpoint') const https = require('https') +const INFURA_ENDPOINT = require('./infura_endpoint.js') + // Looking up an individual transaction function lookupTransaction(transactionHash) { const data = JSON.stringify({ diff --git a/packages/trie/examples/merkle_patricia_trees/example4b.js b/packages/trie/examples/merkle_patricia_trees/example4b.js index d3fb8574db..a8e0fe3b2a 100644 --- a/packages/trie/examples/merkle_patricia_trees/example4b.js +++ b/packages/trie/examples/merkle_patricia_trees/example4b.js @@ -3,9 +3,10 @@ const rlp = require('@ethereumjs/rlp') const { bytesToHex } = require('@ethereumjs/util') const { keccak256 } = require('ethereum-cryptography/keccak') -const INFURA_ENDPOINT = require('./infura_endpoint') const https = require('https') +const INFURA_ENDPOINT = require('./infura_endpoint.js') + function recomputeTransactionHash(transactionHash) { const data = JSON.stringify({ jsonrpc: '2.0', diff --git a/packages/trie/examples/proofs.ts b/packages/trie/examples/proofs.ts index fffac8b346..4f618a688b 100644 --- a/packages/trie/examples/proofs.ts +++ b/packages/trie/examples/proofs.ts @@ -28,10 +28,10 @@ async function main() { proof = await trie.createProof(k2) proof[0].reverse() try { - const value = await trie.verifyProof(trie.root(), k2, proof) // results in error + const _value = await trie.verifyProof(trie.root(), k2, proof) // results in error } catch (err) { console.log(err) } } -main() +void main() diff --git a/packages/trie/examples/rootPersistence.ts b/packages/trie/examples/rootPersistence.ts index dadb55411d..e22841a585 100644 --- a/packages/trie/examples/rootPersistence.ts +++ b/packages/trie/examples/rootPersistence.ts @@ -1,4 +1,4 @@ -import { createTrie, Trie } from '@ethereumjs/trie' +import { createTrie } from '@ethereumjs/trie' import { bytesToHex } from '@ethereumjs/util' async function main() { @@ -9,4 +9,4 @@ async function main() { // this logs the empty root value that has been persisted to the trie db console.log(bytesToHex(trie.root())) // 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 } -main() +void main() diff --git a/packages/trie/examples/trieWalking.ts b/packages/trie/examples/trieWalking.ts index 7d63c26212..a384fa661f 100644 --- a/packages/trie/examples/trieWalking.ts +++ b/packages/trie/examples/trieWalking.ts @@ -1,4 +1,4 @@ -import { createTrie, Trie } from '@ethereumjs/trie' +import { createTrie } from '@ethereumjs/trie' import { utf8ToBytes } from '@ethereumjs/util' async function main() { @@ -11,4 +11,4 @@ async function main() { console.log({ node, currentKey }) } } -main() +void main() diff --git a/packages/trie/src/constructors.ts b/packages/trie/src/constructors.ts index c8fff50896..42676729ad 100644 --- a/packages/trie/src/constructors.ts +++ b/packages/trie/src/constructors.ts @@ -44,7 +44,7 @@ export async function createTrie(opts?: TrieOpts) { { keyEncoding: KeyEncoding.String, valueEncoding: encoding, - } + }, ) } } diff --git a/packages/trie/src/proof/index.ts b/packages/trie/src/proof/index.ts index a789891216..022acdaf27 100644 --- a/packages/trie/src/proof/index.ts +++ b/packages/trie/src/proof/index.ts @@ -19,7 +19,7 @@ import type { Proof, TrieOpts } from '../index.js' export async function verifyTrieProof( key: Uint8Array, proof: Proof, - opts?: TrieOpts + opts?: TrieOpts, ): Promise { try { const proofTrie = await createTrieFromProof(proof, opts) @@ -51,7 +51,7 @@ export function verifyTrieRangeProof( keys: Uint8Array[], values: Uint8Array[], proof: Uint8Array[] | null, - opts?: TrieOpts + opts?: TrieOpts, ): Promise { return verifyRangeProof( rootHash, @@ -60,7 +60,7 @@ export function verifyTrieRangeProof( keys.map((k) => k).map(bytesToNibbles), values, proof, - opts?.useKeyHashingFunction ?? keccak256 + opts?.useKeyHashingFunction ?? keccak256, ) } diff --git a/packages/trie/src/proof/range.ts b/packages/trie/src/proof/range.ts index 98003d2dc1..3c5e9f5566 100644 --- a/packages/trie/src/proof/range.ts +++ b/packages/trie/src/proof/range.ts @@ -27,7 +27,7 @@ async function unset( key: Nibbles, pos: number, removeLeft: boolean, - stack: TrieNode[] + stack: TrieNode[], ): Promise { if (child instanceof BranchNode) { /** @@ -321,7 +321,7 @@ async function verifyProof( rootHash: Uint8Array, key: Uint8Array, proof: Uint8Array[], - useKeyHashingFunction: HashKeysFunction + useKeyHashingFunction: HashKeysFunction, ): Promise<{ value: Uint8Array | null; trie: Trie }> { const proofTrie = await createTrieFromProof(proof, { root: rootHash, @@ -416,7 +416,7 @@ export async function verifyRangeProof( keys: Nibbles[], values: Uint8Array[], proof: Uint8Array[] | null, - useKeyHashingFunction: HashKeysFunction + useKeyHashingFunction: HashKeysFunction, ): Promise { if (keys.length !== values.length) { throw new Error('invalid keys length or values length') @@ -454,7 +454,7 @@ export async function verifyRangeProof( rootHash, nibblesTypeToPackedBytes(firstKey), proof, - useKeyHashingFunction + useKeyHashingFunction, ) if (value !== null || (await hasRightElement(trie, firstKey))) { @@ -467,7 +467,7 @@ export async function verifyRangeProof( if (proof === null || firstKey === null || lastKey === null) { throw new Error( - 'invalid all elements proof: proof, firstKey, lastKey must be null at the same time' + 'invalid all elements proof: proof, firstKey, lastKey must be null at the same time', ) } @@ -477,7 +477,7 @@ export async function verifyRangeProof( rootHash, nibblesTypeToPackedBytes(firstKey), proof, - useKeyHashingFunction + useKeyHashingFunction, ) if (nibblesCompare(firstKey, keys[0]) !== 0) { @@ -496,7 +496,7 @@ export async function verifyRangeProof( } if (firstKey.length !== lastKey.length) { throw new Error( - 'invalid two edge elements proof: the length of firstKey should be equal to the length of lastKey' + 'invalid two edge elements proof: the length of firstKey should be equal to the length of lastKey', ) } diff --git a/packages/trie/src/trie.ts b/packages/trie/src/trie.ts index 1792c30b30..53f8cea120 100644 --- a/packages/trie/src/trie.ts +++ b/packages/trie/src/trie.ts @@ -96,7 +96,7 @@ export class Trie { opts.common?.customCrypto.keccak256 ?? opts.useKeyHashingFunction ?? keccak256 valueEncoding = - opts.db !== undefined ? opts.valueEncoding ?? ValueEncoding.String : ValueEncoding.Bytes + opts.db !== undefined ? (opts.valueEncoding ?? ValueEncoding.String) : ValueEncoding.Bytes } else { // No opts are given, so create a MapDB later on // Use `Bytes` for ValueEncoding @@ -104,7 +104,7 @@ export class Trie { } this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this.debug = this.DEBUG ? (message: string, namespaces: string[] = []) => { let log = this._debug @@ -153,7 +153,7 @@ export class Trie { lastKey: Uint8Array | null, keys: Uint8Array[], values: Uint8Array[], - proof: Uint8Array[] | null + proof: Uint8Array[] | null, ): Promise { return verifyRangeProof( rootHash, @@ -162,7 +162,7 @@ export class Trie { keys.map((k) => this.appliedKey(k)).map(bytesToNibbles), values, proof, - this._opts.useKeyHashingFunction + this._opts.useKeyHashingFunction, ) } @@ -228,15 +228,15 @@ export class Trie { async verifyProof( rootHash: Uint8Array, key: Uint8Array, - proof: Proof + proof: Proof, ): Promise { this.DEBUG && this.debug( `Verifying Proof:\n|| Key: ${bytesToHex(key)}\n|| Root: ${bytesToHex( - rootHash + rootHash, )}\n|| Proof: (${proof.length}) nodes `, - ['VERIFY_PROOF'] + ['VERIFY_PROOF'], ) const proofTrie = new Trie({ root: rootHash, @@ -308,7 +308,7 @@ export class Trie { this.DEBUG && this.debug(`Setting root to ${bytesToHex(value)}`) if (value.length !== this._hashLen) { throw new Error( - `Invalid root length. Roots are ${this._hashLen} bytes, got ${value.length} bytes` + `Invalid root length. Roots are ${this._hashLen} bytes, got ${value.length} bytes`, ) } @@ -360,7 +360,7 @@ export class Trie { async put( key: Uint8Array, value: Uint8Array | null, - skipKeyTransform: boolean = false + skipKeyTransform: boolean = false, ): Promise { this.DEBUG && this.debug(`Key: ${bytesToHex(key)}`, ['PUT']) this.DEBUG && this.debug(`Value: ${value === null ? 'null' : bytesToHex(key)}`, ['PUT']) @@ -474,7 +474,7 @@ export class Trie { stack: TrieNode[] } = { stack: [], - } + }, ): Promise { const targetKey = bytesToNibbles(key) const keyLen = targetKey.length @@ -505,9 +505,9 @@ export class Trie { branchNode === null ? 'NULL' : branchNode instanceof Uint8Array - ? `NodeHash: ${bytesToHex(branchNode)}` - : `Raw_Node: ${branchNode.toString()}`, - ['FIND_PATH', 'BranchNode', branchIndex.toString()] + ? `NodeHash: ${bytesToHex(branchNode)}` + : `Raw_Node: ${branchNode.toString()}`, + ['FIND_PATH', 'BranchNode', branchIndex.toString()], ) if (!branchNode) { result = { node: null, remaining: targetKey.slice(progress), stack } @@ -535,13 +535,13 @@ export class Trie { this.debug( `Comparing node key to expected\n|| Node_Key: [${node.key()}]\n|| Expected: [${targetKey.slice( progress, - progress + node.key().length + progress + node.key().length, )}]\n|| Matching: [${ targetKey.slice(progress, progress + node.key().length).toString() === node.key().toString() }] `, - ['FIND_PATH', 'ExtensionNode'] + ['FIND_PATH', 'ExtensionNode'], ) const _progress = progress for (const k of node.key()) { @@ -561,9 +561,9 @@ export class Trie { this.DEBUG && this.debug( `Walking trie from ${startingNode === undefined ? 'ROOT' : 'NODE'}: ${bytesToHex( - start as Uint8Array + start as Uint8Array, )}`, - ['FIND_PATH'] + ['FIND_PATH'], ) await this.walkTrie(start, onFound) } catch (error: any) { @@ -580,7 +580,7 @@ export class Trie { result.node !== null ? `Target Node FOUND for ${bytesToNibbles(key)}` : `Target Node NOT FOUND`, - ['FIND_PATH'] + ['FIND_PATH'], ) result.stack = result.stack.filter((e) => e !== undefined) @@ -591,7 +591,7 @@ export class Trie { || Remaining: [${result.remaining}]\n|| Stack: ${result.stack .map((e) => e.constructor.name) .join(', ')}`, - ['FIND_PATH'] + ['FIND_PATH'], ) return result } @@ -631,7 +631,7 @@ export class Trie { undefined, async (node) => { return node instanceof LeafNode || (node instanceof BranchNode && node.value() !== null) - } + }, )) { await onFound(node, currentKey) } @@ -687,7 +687,7 @@ export class Trie { k: Uint8Array, value: Uint8Array, keyRemainder: Nibbles, - stack: TrieNode[] + stack: TrieNode[], ): Promise { const toSave: BatchDBOp[] = [] const lastNode = stack.pop() @@ -792,7 +792,7 @@ export class Trie { branchKey: number, branchNode: TrieNode, parentNode: TrieNode, - stack: TrieNode[] + stack: TrieNode[], ) => { // branchNode is the node ON the branch node not THE branch node if (parentNode === null || parentNode === undefined || parentNode instanceof BranchNode) { @@ -966,7 +966,7 @@ export class Trie { node: TrieNode, topLevel: boolean, opStack: BatchDBOp[], - remove: boolean = false + remove: boolean = false, ): Uint8Array | (EmbeddedNode | null)[] { const encoded = node.serialize() @@ -1053,7 +1053,7 @@ export class Trie { if ( item !== null && bytesToUnprefixedHex( - isRawNode(item) ? controller.trie.appliedKey(RLP.encode(item)) : item + isRawNode(item) ? controller.trie.appliedKey(RLP.encode(item)) : item, ) === dbkey ) { found = true @@ -1117,9 +1117,9 @@ export class Trie { this.DEBUG && this.debug( `Persisting root: \n|| RootHash: ${bytesToHex(this.root())}\n|| RootKey: ${bytesToHex( - this.appliedKey(ROOT_DB_KEY) + this.appliedKey(ROOT_DB_KEY), )}`, - ['PERSIST_ROOT'] + ['PERSIST_ROOT'], ) let key = this.appliedKey(ROOT_DB_KEY) key = this._opts.keyPrefix ? concatBytes(this._opts.keyPrefix, key) : key @@ -1229,7 +1229,7 @@ export class Trie { */ async getValueMap( startKey = BIGINT_0, - limit?: number + limit?: number, ): Promise<{ values: { [key: string]: string }; nextKey: null | string }> { // If limit is undefined, all keys are inRange let inRange = limit !== undefined ? false : true diff --git a/packages/trie/src/types.ts b/packages/trie/src/types.ts index 5928c2ee8a..f17ecc424c 100644 --- a/packages/trie/src/types.ts +++ b/packages/trie/src/types.ts @@ -30,7 +30,7 @@ export type FoundNodeFunction = ( nodeRef: Uint8Array, node: TrieNode | null, key: Nibbles, - walkController: WalkController + walkController: WalkController, ) => void export type HashKeysFunction = (msg: Uint8Array) => Uint8Array diff --git a/packages/trie/src/util/asyncWalk.ts b/packages/trie/src/util/asyncWalk.ts index 2074302193..28e57586eb 100644 --- a/packages/trie/src/util/asyncWalk.ts +++ b/packages/trie/src/util/asyncWalk.ts @@ -29,7 +29,7 @@ export async function* _walkTrie( currentKey: number[] = [], onFound: OnFound = async (_trieNode: TrieNode, _key: number[]) => {}, filter: NodeFilter = async (_trieNode: TrieNode, _key: number[]) => true, - visited: Set = new Set() + visited: Set = new Set(), ): AsyncIterable<{ node: TrieNode; currentKey: number[] }> { if (equalsBytes(nodeHash, this.EMPTY_TRIE_ROOT)) { return diff --git a/packages/trie/src/util/encoding.ts b/packages/trie/src/util/encoding.ts index 5212d2f708..1e0708ec75 100644 --- a/packages/trie/src/util/encoding.ts +++ b/packages/trie/src/util/encoding.ts @@ -205,6 +205,6 @@ export const mergeAndFormatKeyPaths = (pathStrings: string[]) => { // full path is keybyte encoded return hexToKeybytes(unprefixedHexToBytes(s)) } - }) + }), ) } diff --git a/packages/trie/src/util/genesisState.ts b/packages/trie/src/util/genesisState.ts index ed8adce049..d6171d8088 100644 --- a/packages/trie/src/util/genesisState.ts +++ b/packages/trie/src/util/genesisState.ts @@ -36,7 +36,7 @@ export async function genesisStateRoot(genesisState: GenesisState) { for (const [k, val] of storage) { const storageKey = isHexString(k) ? hexToBytes(k) : unprefixedHexToBytes(k) const storageVal = RLP.encode( - unpadBytes(isHexString(val) ? hexToBytes(val) : unprefixedHexToBytes(val)) + unpadBytes(isHexString(val) ? hexToBytes(val) : unprefixedHexToBytes(val)), ) await storageTrie.put(storageKey, storageVal) } diff --git a/packages/trie/src/util/walkController.ts b/packages/trie/src/util/walkController.ts index 593bf45683..6c35761308 100644 --- a/packages/trie/src/util/walkController.ts +++ b/packages/trie/src/util/walkController.ts @@ -40,7 +40,7 @@ export class WalkController { onNode: FoundNodeFunction, trie: Trie, root: Uint8Array, - poolSize?: number + poolSize?: number, ): Promise { const strategy = new WalkController(onNode, trie, poolSize ?? 500) await strategy.startWalk(root) @@ -106,7 +106,7 @@ export class WalkController { } taskFinishedCallback() // this marks the current task as finished. If there are any tasks left in the queue, this will immediately execute the first task. this.processNode(nodeRef as Uint8Array, childNode as TrieNode, key) - } + }, ) } diff --git a/packages/trie/test/encoding.spec.ts b/packages/trie/test/encoding.spec.ts index d02d80b368..dc4ecace68 100644 --- a/packages/trie/test/encoding.spec.ts +++ b/packages/trie/test/encoding.spec.ts @@ -51,7 +51,7 @@ describe('support for Uint8Array', () => { for (const value of db._database.values()) { assert.ok( typeof value === 'string', - 'if a database is provided, string values will be used internally' + 'if a database is provided, string values will be used internally', ) } }) diff --git a/packages/trie/test/index.spec.ts b/packages/trie/test/index.spec.ts index 1d901575e9..276c51cd0b 100644 --- a/packages/trie/test/index.spec.ts +++ b/packages/trie/test/index.spec.ts @@ -22,7 +22,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { describe('simple save and retrieve', () => { it('should not crash if given a non-existent root', async () => { const root = hexToBytes( - '0x3f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d' + '0x3f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d', ) const trie = new Trie({ root, keyPrefix }) @@ -67,7 +67,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trie.put(utf8ToBytes('doge'), utf8ToBytes('coin')) assert.equal( '0xde8a34a8c1d558682eae1528b47523a483dd8685d6db14b291451a66066bf0fc', - bytesToHex(trie.root()) + bytesToHex(trie.root()), ) }) @@ -114,7 +114,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trie.put(utf8ToBytes('do'), utf8ToBytes('verb')) assert.equal( '0xf803dfcb7e8f1afd45e88eedb4699a7138d6c07b71243d9ae9bff720c99925f9', - bytesToHex(trie.root()) + bytesToHex(trie.root()), ) }) @@ -122,7 +122,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trie.put(utf8ToBytes('done'), utf8ToBytes('finished')) assert.equal( '0x409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb', - bytesToHex(trie.root()) + bytesToHex(trie.root()), ) }) }) @@ -142,7 +142,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trie.put(utf8ToBytes('done'), utf8ToBytes('finished')) assert.equal( '0x409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb', - bytesToHex(trie.root()) + bytesToHex(trie.root()), ) }) }) @@ -158,11 +158,11 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trieSetup.trie.put(new Uint8Array([11, 11, 11]), utf8ToBytes('first')) await trieSetup.trie.put( new Uint8Array([12, 22, 22]), - utf8ToBytes('create the first branch') + utf8ToBytes('create the first branch'), ) await trieSetup.trie.put( new Uint8Array([12, 34, 44]), - utf8ToBytes('create the last branch') + utf8ToBytes('create the last branch'), ) await trieSetup.trie.del(new Uint8Array([12, 22, 22])) @@ -174,15 +174,15 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trieSetup.trie.put(new Uint8Array([11, 11, 11]), utf8ToBytes('first')) await trieSetup.trie.put( new Uint8Array([12, 22, 22]), - utf8ToBytes('create the first branch') + utf8ToBytes('create the first branch'), ) await trieSetup.trie.put( new Uint8Array([12, 33, 33]), - utf8ToBytes('create the middle branch') + utf8ToBytes('create the middle branch'), ) await trieSetup.trie.put( new Uint8Array([12, 34, 44]), - utf8ToBytes('create the last branch') + utf8ToBytes('create the last branch'), ) await trieSetup.trie.del(new Uint8Array([12, 22, 22])) @@ -194,15 +194,15 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trieSetup.trie.put(new Uint8Array([11, 11, 11]), utf8ToBytes('first')) await trieSetup.trie.put( new Uint8Array([12, 22, 22]), - utf8ToBytes('create the first branch') + utf8ToBytes('create the first branch'), ) await trieSetup.trie.put( new Uint8Array([12, 33, 33]), - utf8ToBytes('create the middle branch') + utf8ToBytes('create the middle branch'), ) await trieSetup.trie.put( new Uint8Array([12, 34, 44]), - utf8ToBytes('create the last branch') + utf8ToBytes('create the last branch'), ) // delete the middle branch @@ -215,15 +215,15 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { await trieSetup.trie.put(new Uint8Array([11, 11, 11]), utf8ToBytes('first')) await trieSetup.trie.put( new Uint8Array([12, 22, 22]), - utf8ToBytes('create the first branch') + utf8ToBytes('create the first branch'), ) await trieSetup.trie.put( new Uint8Array([12, 33, 33]), - utf8ToBytes('create the middle branch') + utf8ToBytes('create the middle branch'), ) await trieSetup.trie.put( new Uint8Array([12, 34, 44]), - utf8ToBytes('create the last branch') + utf8ToBytes('create the last branch'), ) // delete the middle branch await trieSetup.trie.del(new Uint8Array([11, 11, 11])) @@ -259,7 +259,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { assert.ok(path.node === null, 'findPath should not return a node now') assert.ok( path.stack.length === 1, - 'findPath should find the first extension node which is still in the DB' + 'findPath should find the first extension node which is still in the DB', ) }) }) @@ -310,7 +310,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { const v2 = utf8ToBytes('this-is-some-longer-value-to-test-the-delete-operation-value2') const rootAfterK1 = hexToBytes( - '0x809e75931f394603657e113eb7244794f35b8d326cff99407111d600722e9425' + '0x809e75931f394603657e113eb7244794f35b8d326cff99407111d600722e9425', ) const trieSetup = { @@ -325,7 +325,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { assert.equal( await trieSetup.trie.get(k1), null, - 'should return null on latest state root independently from deleteFromDB setting' + 'should return null on latest state root independently from deleteFromDB setting', ) trieSetup.trie.root(rootAfterK1) @@ -341,7 +341,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { return concatBytes( utf8ToBytes('hash_'), new Uint8Array(hashLen - msg.length).fill(0), - msg + msg, ) } else { return concatBytes(utf8ToBytes('hash_'), msg.slice(0, hashLen - 5)) @@ -364,7 +364,7 @@ for (const keyPrefix of [undefined, hexToBytes('0x1234')]) { assert.equal( bytesToHex(trie.root()), - '0xe118db4e01512253df38daafa16fc1d69e03e755595b5847d275d7404ebdc74a' + '0xe118db4e01512253df38daafa16fc1d69e03e755595b5847d275d7404ebdc74a', ) }) }) diff --git a/packages/trie/test/proof.spec.ts b/packages/trie/test/proof.spec.ts index e74313a367..2a5b751830 100644 --- a/packages/trie/test/proof.spec.ts +++ b/packages/trie/test/proof.spec.ts @@ -100,11 +100,11 @@ describe('simple merkle proofs generation and verification', () => { await trie.put( utf8ToBytes('key1aa'), - utf8ToBytes('0123456789012345678901234567890123456789xxx') + utf8ToBytes('0123456789012345678901234567890123456789xxx'), ) await trie.put( utf8ToBytes('key1'), - utf8ToBytes('0123456789012345678901234567890123456789Very_Long') + utf8ToBytes('0123456789012345678901234567890123456789Very_Long'), ) await trie.put(utf8ToBytes('key2bb'), utf8ToBytes('aval3')) await trie.put(utf8ToBytes('key2'), utf8ToBytes('short')) @@ -203,7 +203,7 @@ describe('simple merkle proofs generation and verification', () => { const updatedNewSafeValue = await newTrie.get(safeKey) assert.ok( equalsBytes(updatedNewSafeValue!, safeValue), - 'succesfully set the trie to the new root and got the correct value' + 'succesfully set the trie to the new root and got the correct value', ) }) }) diff --git a/packages/trie/test/proof/range.spec.ts b/packages/trie/test/proof/range.spec.ts index 8bde035b5f..3fb45cf464 100644 --- a/packages/trie/test/proof/range.spec.ts +++ b/packages/trie/test/proof/range.spec.ts @@ -83,7 +83,7 @@ async function verify( startKey?: Uint8Array, endKey?: Uint8Array, keys?: Uint8Array[], - vals?: Uint8Array[] + vals?: Uint8Array[], ) { startKey = startKey ?? entries[start][0] endKey = endKey ?? entries[end][0] @@ -94,7 +94,7 @@ async function verify( endKey, keys ?? targetRange.map(([key]) => key), vals ?? targetRange.map(([, val]) => val), - [...(await trie.createProof(startKey)), ...(await trie.createProof(endKey))] + [...(await trie.createProof(startKey)), ...(await trie.createProof(endKey))], ) } @@ -136,7 +136,7 @@ describe('simple merkle range proofs generation and verification', () => { assert.equal( await verify(trie, entries, start, end, startKey, endKey), - end !== entries.length - 1 + end !== entries.length - 1, ) } @@ -195,7 +195,7 @@ describe('simple merkle range proofs generation and verification', () => { // One element with two non-existent edge proofs assert.equal( await verify(trie, entries, start, start, decreasedStartKey, increasedEndKey), - true + true, ) // Test the mini trie with only a single element. @@ -217,9 +217,9 @@ describe('simple merkle range proofs generation and verification', () => { null, entries.map(([key]) => key), entries.map(([, val]) => val), - null + null, ), - false + false, ) // With edge proofs, it should still work. @@ -233,9 +233,9 @@ describe('simple merkle range proofs generation and verification', () => { 0, entries.length - 1, hexToBytes(`0x${'00'.repeat(32)}`), - hexToBytes(`0x${'ff'.repeat(32)}`) + hexToBytes(`0x${'ff'.repeat(32)}`), ), - false + false, ) }) @@ -261,7 +261,7 @@ describe('simple merkle range proofs generation and verification', () => { it('create a bad range proof and verify it', async () => { const runTest = async ( - cb: (trie: Trie, entries: [Uint8Array, Uint8Array][]) => Promise + cb: (trie: Trie, entries: [Uint8Array, Uint8Array][]) => Promise, ) => { const { trie, entries } = await randomTrie(new MapDB(), false) @@ -349,7 +349,7 @@ describe('simple merkle range proofs generation and verification', () => { undefined, undefined, targetRange.map(([key]) => key), - targetRange.map(([, val]) => val) + targetRange.map(([, val]) => val), ) result = true } catch (err) { diff --git a/packages/trie/test/trie/checkpoint.spec.ts b/packages/trie/test/trie/checkpoint.spec.ts index c5ea661609..aac6de1dfb 100644 --- a/packages/trie/test/trie/checkpoint.spec.ts +++ b/packages/trie/test/trie/checkpoint.spec.ts @@ -234,11 +234,11 @@ describe('testing checkpoints', () => { assert.equal(bytesToUtf8((await CommittedState.get(KEY))!), '1') assert.equal( bytesToHex((await CommittedState['_db'].get(KEY_ROOT))!), - '0x77ddd505d2a5b76a2a6ee34b827a0d35ca19f8d358bee3d74a84eab59794487c' + '0x77ddd505d2a5b76a2a6ee34b827a0d35ca19f8d358bee3d74a84eab59794487c', ) assert.equal( bytesToHex(CommittedState.root()), - '0x77ddd505d2a5b76a2a6ee34b827a0d35ca19f8d358bee3d74a84eab59794487c' + '0x77ddd505d2a5b76a2a6ee34b827a0d35ca19f8d358bee3d74a84eab59794487c', ) // From MemoryState, now take the final checkpoint @@ -264,7 +264,7 @@ describe('testing checkpoints', () => { [ hexToBytes('0xd7eba6ee0f011acb031b79554d57001c42fbfabb150eb9fdd3b6d434f7b791eb'), hexToBytes('0xe3a1202418cf7414b1e6c2c8d92b4673eecdb4aac88f7f58623e3be903aefb2fd4655c32'), - ] + ], ) // Verify that the key is updated assert.equal(bytesToUtf8((await CommittedState.get(KEY))!), '2') diff --git a/packages/trie/test/trie/secure.spec.ts b/packages/trie/test/trie/secure.spec.ts index f6b46483e8..2a866250af 100644 --- a/packages/trie/test/trie/secure.spec.ts +++ b/packages/trie/test/trie/secure.spec.ts @@ -128,35 +128,35 @@ describe('secure tests', () => { const trie = new Trie({ useKeyHashing: true, db: new MapDB() }) const a = hexToBytes( - '0xf8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf' + '0xf8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf', ) const ak = hexToBytes('0x095e7baea6a6c7c4c2dfeb977efac326af552d87') const b = hexToBytes( - '0xf844802ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0db94dc4aab9b6a1a11956906ea34f3252f394576aece12199b23b269bb2738ab' + '0xf844802ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0db94dc4aab9b6a1a11956906ea34f3252f394576aece12199b23b269bb2738ab', ) const bk = hexToBytes('0x945304eb96065b2a98b57a48a06ae28d285a71b5') const c = hexToBytes( - '0xf84c80880de0b6b3a7640000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xf84c80880de0b6b3a7640000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) const ck = hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') // checkpoint // checkpoint // commit const d = hexToBytes( - '0xf8488084535500b1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf' + '0xf8488084535500b1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf', ) const dk = hexToBytes('0x095e7baea6a6c7c4c2dfeb977efac326af552d87') const e = hexToBytes( - '0xf8478083010851a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0db94dc4aab9b6a1a11956906ea34f3252f394576aece12199b23b269bb2738ab' + '0xf8478083010851a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0db94dc4aab9b6a1a11956906ea34f3252f394576aece12199b23b269bb2738ab', ) const ek = hexToBytes('0x945304eb96065b2a98b57a48a06ae28d285a71b5') const f = hexToBytes( - '0xf84c01880de0b6b3540df72ca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xf84c01880de0b6b3540df72ca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) const fk = hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') // commit const g = hexToBytes( - '0xf8488084535500b1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf' + '0xf8488084535500b1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0a155280bc3c09fd31b0adebbdd4ef3d5128172c0d2008be964dc9e10e0f0fedf', ) const gk = hexToBytes('0x095e7baea6a6c7c4c2dfeb977efac326af552d87') diff --git a/packages/trie/test/trie/trie.spec.ts b/packages/trie/test/trie/trie.spec.ts index a3f35ca252..b74d13d717 100644 --- a/packages/trie/test/trie/trie.spec.ts +++ b/packages/trie/test/trie/trie.spec.ts @@ -47,7 +47,7 @@ for (const { constructor, defaults, title } of [ it('creates an instance via createTrie and defaults to `false` with a database', async () => { // TODO: check this test assert.isUndefined( - ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence + ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence, ) }) @@ -60,7 +60,7 @@ for (const { constructor, defaults, title } of [ db: new MapDB(), useRootPersistence: false, })) as any - )._useRootPersistence + )._useRootPersistence, ) }) @@ -73,14 +73,14 @@ for (const { constructor, defaults, title } of [ db: new MapDB(), useRootPersistence: false, })) as any - )._useRootPersistence + )._useRootPersistence, ) }) it('creates an instance via createTrie and defaults to `false` without a database', async () => { // TODO: check this test assert.isUndefined( - ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence + ((await createTrie({ ...defaults, db: new MapDB() })) as any)._useRootPersistence, ) }) @@ -189,7 +189,7 @@ for (const { constructor, defaults, title } of [ for (const root of roots) { assert.isTrue( await trie.checkRoot(unprefixedHexToBytes(root)), - 'Should return true for all nodes in trie' + 'Should return true for all nodes in trie', ) } }) @@ -207,16 +207,16 @@ for (const { constructor, defaults, title } of [ assert.deepEqual(emptyTrie.EMPTY_TRIE_ROOT, emptyTrie.root(), 'Should return empty trie root') assert.isTrue( await emptyTrie.checkRoot(emptyTrie.EMPTY_TRIE_ROOT), - 'Should return true for empty root' + 'Should return true for empty root', ) assert.isFalse( await emptyTrie.checkRoot(emptyTrie['appliedKey'](ROOT_DB_KEY)), - 'Should return false for persistence key' + 'Should return false for persistence key', ) for (const root of roots) { assert.isFalse( await emptyTrie.checkRoot(unprefixedHexToBytes(root)), - 'Should always return false' + 'Should always return false', ) } }) @@ -235,7 +235,7 @@ for (const { constructor, defaults, title } of [ assert.notEqual( 'Missing node in DB', e.message, - 'Should throw when error is unrelated to checkroot' + 'Should throw when error is unrelated to checkroot', ) } }) @@ -259,7 +259,7 @@ describe('keyHashingFunction', async () => { assert.equal( bytesToHex(trieWithHashFunction.root()), '0x8001', - 'used hash function from customKeyHashingFunction' + 'used hash function from customKeyHashingFunction', ) assert.equal(bytesToHex(trieWithCommon.root()), '0x80', 'used hash function from common') }) @@ -282,7 +282,7 @@ describe('keyHashingFunction', async () => { assert.equal( bytesToHex(trieWithHashFunctionCopy.root()), '0x8001', - 'used hash function from customKeyHashingFunction' + 'used hash function from customKeyHashingFunction', ) assert.equal(bytesToHex(trieWithCommonCopy.root()), '0x80', 'used hash function from common') }) diff --git a/packages/trie/test/util/encodingUtils.spec.ts b/packages/trie/test/util/encodingUtils.spec.ts index cf09a89d8d..d647c47929 100644 --- a/packages/trie/test/util/encodingUtils.spec.ts +++ b/packages/trie/test/util/encodingUtils.spec.ts @@ -81,7 +81,7 @@ describe('encoding', () => { assert.deepEqual( result, expected, - 'Returned hex-encoded key does not match the expected result' + 'Returned hex-encoded key does not match the expected result', ) }) @@ -98,7 +98,7 @@ describe('encoding', () => { assert.deepEqual( result, expected, - 'Returned hex-encoded key in "keybyte" encoding does not match the expected result' + 'Returned hex-encoded key in "keybyte" encoding does not match the expected result', ) }) @@ -110,7 +110,7 @@ describe('encoding', () => { assert.throws( () => pathToHexKey(path, extension, 'invalid'), Error, - 'retType must be either "keybyte" or "hex"' + 'retType must be either "keybyte" or "hex"', ) }) @@ -122,17 +122,17 @@ describe('encoding', () => { assert.equal( paths.reduce((count, subArray) => count + subArray.length, 0), pathStrings.length, - 'should have correct number of paths' + 'should have correct number of paths', ) assert.deepEqual( paths[0], [Uint8Array.of(26), Uint8Array.of(27), Uint8Array.of(28), Uint8Array.of(29)], - 'should merge paths correctly' + 'should merge paths correctly', ) assert.deepEqual( paths[1], [Uint8Array.of(30), Uint8Array.of(26)], - 'should merge paths correctly' + 'should merge paths correctly', ) assert.deepEqual(paths[2], [Uint8Array.of(31)], 'should merge paths correctly') }) diff --git a/packages/trie/test/util/genesisState.spec.ts b/packages/trie/test/util/genesisState.spec.ts index 77fc886905..9a672da74f 100644 --- a/packages/trie/test/util/genesisState.spec.ts +++ b/packages/trie/test/util/genesisState.spec.ts @@ -15,7 +15,7 @@ describe('[Util/genesisStateRoot]', () => { assert.equal( bytesToHex(stateRoot), '0x52e628c7f35996ba5a0402d02b34535993c89ff7fc4c430b2763ada8554bee62', - 'kiln stateRoot matches' + 'kiln stateRoot matches', ) }) }) @@ -25,6 +25,6 @@ it('should correctly derive mainnet stateRoot from ethereumjs genesis', async () assert.equal( bytesToHex(stateRoot), '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544', - 'mainnet stateRoot matches' + 'mainnet stateRoot matches', ) }) diff --git a/packages/trie/tsconfig.lint.json b/packages/trie/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/trie/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/tx/.eslintrc.cjs b/packages/tx/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/tx/.eslintrc.cjs +++ b/packages/tx/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/tx/examples/blobTx.ts b/packages/tx/examples/blobTx.ts index 03f38924fe..fd4fc5ccaa 100644 --- a/packages/tx/examples/blobTx.ts +++ b/packages/tx/examples/blobTx.ts @@ -36,4 +36,4 @@ const main = async () => { console.log(bytesToHex(tx.hash())) //0x3c3e7c5e09c250d2200bcc3530f4a9088d7e3fb4ea3f4fccfd09f535a3539e84 } -main() +void main() diff --git a/packages/tx/examples/custom-chain-id-tx.ts b/packages/tx/examples/custom-chain-id-tx.ts index 30d5baf394..1402244dc9 100644 --- a/packages/tx/examples/custom-chain-id-tx.ts +++ b/packages/tx/examples/custom-chain-id-tx.ts @@ -1,9 +1,9 @@ +import { Hardfork, createCustomCommon } from '@ethereumjs/common' import { createLegacyTxFromRLP } from '@ethereumjs/tx' import { toBytes } from '@ethereumjs/util' -import { createCustomCommon, Hardfork } from '@ethereumjs/common' const txData = toBytes( - '0xf9010b82930284d09dc30083419ce0942d18de92e0f9aee1a29770c3b15c6cf8ac5498e580b8a42f43f4fb0000000000000000000000000000000000000000000000000000016b78998da900000000000000000000000000000000000000000000000000000000000cb1b70000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000001363e4f00000000000000000000000000000000000000000000000000000000000186a029a0fac36e66d329af0e831b2e61179b3ec8d7c7a8a2179e303cfed3364aff2bc3e4a07cb73d56e561ccbd838818dd3dea5fa0b5158577ffc61c0e6ec1f0ed55716891' + '0xf9010b82930284d09dc30083419ce0942d18de92e0f9aee1a29770c3b15c6cf8ac5498e580b8a42f43f4fb0000000000000000000000000000000000000000000000000000016b78998da900000000000000000000000000000000000000000000000000000000000cb1b70000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000001363e4f00000000000000000000000000000000000000000000000000000000000186a029a0fac36e66d329af0e831b2e61179b3ec8d7c7a8a2179e303cfed3364aff2bc3e4a07cb73d56e561ccbd838818dd3dea5fa0b5158577ffc61c0e6ec1f0ed55716891', ) const common = createCustomCommon({ chainId: 3 }) diff --git a/packages/tx/examples/custom-chain-tx.ts b/packages/tx/examples/custom-chain-tx.ts index 8ac85170fd..8d111ff918 100644 --- a/packages/tx/examples/custom-chain-tx.ts +++ b/packages/tx/examples/custom-chain-tx.ts @@ -1,7 +1,6 @@ -import { Address } from '@ethereumjs/util' import { createCustomCommon } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' -import { hexToBytes } from '@ethereumjs/util' +import { Address, hexToBytes } from '@ethereumjs/util' // In this example we create a transaction for a custom network. @@ -15,7 +14,7 @@ const customCommon = createCustomCommon( { baseChain: 'mainnet', hardfork: 'petersburg', - } + }, ) // We pass our custom Common object whenever we create a transaction @@ -27,7 +26,7 @@ const tx = createLegacyTx( gasLimit: 1000000000, value: 100000, }, - opts + opts, ) // Once we created the transaction using the custom Common object, we can use it as a normal tx. diff --git a/packages/tx/examples/initKzg.ts b/packages/tx/examples/initKzg.ts index de6276d97f..9ed4303631 100644 --- a/packages/tx/examples/initKzg.ts +++ b/packages/tx/examples/initKzg.ts @@ -1,5 +1,5 @@ -import { loadKZG } from 'kzg-wasm' import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { loadKZG } from 'kzg-wasm' const main = async () => { const kzg = await loadKZG() @@ -14,4 +14,4 @@ const main = async () => { console.log(common.customCrypto.kzg) // should output the KZG API as an object } -main() +void main() diff --git a/packages/tx/examples/l2tx.ts b/packages/tx/examples/l2tx.ts index 5b9dd1ad55..15977fb777 100644 --- a/packages/tx/examples/l2tx.ts +++ b/packages/tx/examples/l2tx.ts @@ -1,4 +1,4 @@ -import { createCustomCommon, CustomChain } from '@ethereumjs/common' +import { CustomChain, createCustomCommon } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' diff --git a/packages/tx/examples/legacyTx.ts b/packages/tx/examples/legacyTx.ts index 69dd8220c1..7e96043564 100644 --- a/packages/tx/examples/legacyTx.ts +++ b/packages/tx/examples/legacyTx.ts @@ -1,9 +1,10 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' +import { hexToBytes } from 'ethereum-cryptography/utils' const txParams = { - nonce: '0x00', + nonce: '0x0', gasPrice: '0x09184e72a000', gasLimit: '0x2710', to: '0x0000000000000000000000000000000000000000', @@ -14,12 +15,9 @@ const txParams = { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) const tx = createLegacyTx(txParams, { common }) -const privateKey = Buffer.from( - 'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', - 'hex' -) +const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109') const signedTx = tx.sign(privateKey) -const serializedTx = signedTx.serialize() +const _serializedTx = signedTx.serialize() console.log(bytesToHex(signedTx.hash())) // 0x894b72d87f8333fccd29d1b3aca39af69d97a6bc281e7e7a3a60640690a3cd2b diff --git a/packages/tx/examples/londonTx.ts b/packages/tx/examples/londonTx.ts index 00bb618fe7..bff302f2ba 100644 --- a/packages/tx/examples/londonTx.ts +++ b/packages/tx/examples/londonTx.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { create1559FeeMarketTx, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' +import { create1559FeeMarketTx } from '@ethereumjs/tx' import { bytesToHex } from '@ethereumjs/util' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) diff --git a/packages/tx/examples/transactions.ts b/packages/tx/examples/transactions.ts index 4104b91435..8d7509bde3 100644 --- a/packages/tx/examples/transactions.ts +++ b/packages/tx/examples/transactions.ts @@ -2,8 +2,8 @@ // You can run them with tsx, as this project is developed in TypeScript. // Install the dependencies and run `npx tsx examples/transactions.ts` -import { bytesToHex, toBytes, hexToBytes } from '@ethereumjs/util' import { createLegacyTx, createLegacyTxFromBytesArray } from '@ethereumjs/tx' +import { bytesToHex, hexToBytes, toBytes } from '@ethereumjs/util' // We create an unsigned transaction. // Notice we don't set the `to` field because we are creating a new contract. diff --git a/packages/tx/examples/txFactory.ts b/packages/tx/examples/txFactory.ts index dd967de644..fb23713107 100644 --- a/packages/tx/examples/txFactory.ts +++ b/packages/tx/examples/txFactory.ts @@ -1,5 +1,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Capability, createTxFromTxData, EIP1559CompatibleTx } from '@ethereumjs/tx' +import { Capability, createTxFromTxData } from '@ethereumjs/tx' + +import type { EIP1559CompatibleTx } from '@ethereumjs/tx' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) @@ -8,6 +10,6 @@ const tx = createTxFromTxData(txData, { common }) if (tx.supports(Capability.EIP1559FeeMarket)) { console.log( - `The max fee per gas for this transaction is ${(tx as EIP1559CompatibleTx).maxFeePerGas}` + `The max fee per gas for this transaction is ${(tx as EIP1559CompatibleTx).maxFeePerGas}`, ) } diff --git a/packages/tx/src/1559/constructors.ts b/packages/tx/src/1559/constructors.ts index 6972a8bdfd..2465046fd5 100644 --- a/packages/tx/src/1559/constructors.ts +++ b/packages/tx/src/1559/constructors.ts @@ -31,11 +31,11 @@ export function create1559FeeMarketTx(txData: TxData, opts: TxOptions = {}) { */ export function createEIP1559FeeMarketTxFromBytesArray( values: TxValuesArray, - opts: TxOptions = {} + opts: TxOptions = {}, ) { if (values.length !== 9 && values.length !== 12) { throw new Error( - 'Invalid EIP-1559 transaction. Only expecting 9 values (for unsigned tx) or 12 values (for signed tx).' + 'Invalid EIP-1559 transaction. Only expecting 9 values (for unsigned tx) or 12 values (for signed tx).', ) } @@ -72,7 +72,7 @@ export function createEIP1559FeeMarketTxFromBytesArray( r, s, }, - opts + opts, ) } @@ -89,7 +89,7 @@ export function create1559FeeMarketTxFromRLP(serialized: Uint8Array, opts: TxOpt throw new Error( `Invalid serialized tx input: not an EIP-1559 transaction (wrong tx type, expected: ${ TransactionType.FeeMarketEIP1559 - }, received: ${bytesToHex(serialized.subarray(0, 1))}` + }, received: ${bytesToHex(serialized.subarray(0, 1))}`, ) } diff --git a/packages/tx/src/1559/tx.ts b/packages/tx/src/1559/tx.ts index df4a3f155a..464b255b2a 100644 --- a/packages/tx/src/1559/tx.ts +++ b/packages/tx/src/1559/tx.ts @@ -90,7 +90,7 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction { if (!(blobVersionedHashes.length === blobs.length && blobs.length === commitments.length)) { throw new Error('Number of blobVersionedHashes, blobs, and commitments not all equal') @@ -73,7 +73,7 @@ const validateBlobTransactionNetworkWrapper = ( export function create4844BlobTx(txData: TxData, opts?: TxOptions) { if (opts?.common?.customCrypto?.kzg === undefined) { throw new Error( - 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx', ) } const kzg = opts!.common!.customCrypto!.kzg! @@ -96,7 +96,7 @@ export function create4844BlobTx(txData: TxData, opts?: TxOptions) { txData.kzgProofs = blobsToProofs( kzg, txData.blobs as Uint8Array[], - txData.kzgCommitments as Uint8Array[] + txData.kzgCommitments as Uint8Array[], ) } @@ -112,13 +112,13 @@ export function create4844BlobTx(txData: TxData, opts?: TxOptions) { export function create4844BlobTxFromBytesArray(values: TxValuesArray, opts: TxOptions = {}) { if (opts.common?.customCrypto?.kzg === undefined) { throw new Error( - 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx', ) } if (values.length !== 11 && values.length !== 14) { throw new Error( - 'Invalid EIP-4844 transaction. Only expecting 11 values (for unsigned tx) or 14 values (for signed tx).' + 'Invalid EIP-4844 transaction. Only expecting 11 values (for unsigned tx) or 14 values (for signed tx).', ) } @@ -169,7 +169,7 @@ export function create4844BlobTxFromBytesArray(values: TxValuesArray, opts: TxOp r, s, }, - opts + opts, ) } @@ -182,7 +182,7 @@ export function create4844BlobTxFromBytesArray(values: TxValuesArray, opts: TxOp export function create4844BlobTxFromRLP(serialized: Uint8Array, opts: TxOptions = {}) { if (opts.common?.customCrypto?.kzg === undefined) { throw new Error( - 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx', ) } @@ -190,7 +190,7 @@ export function create4844BlobTxFromRLP(serialized: Uint8Array, opts: TxOptions throw new Error( `Invalid serialized tx input: not an EIP-4844 transaction (wrong tx type, expected: ${ TransactionType.BlobEIP4844 - }, received: ${bytesToHex(serialized.subarray(0, 1))}` + }, received: ${bytesToHex(serialized.subarray(0, 1))}`, ) } @@ -211,7 +211,7 @@ export function create4844BlobTxFromRLP(serialized: Uint8Array, opts: TxOptions */ export function create4844BlobTxFromSerializedNetworkWrapper( serialized: Uint8Array, - opts?: TxOptions + opts?: TxOptions, ): BlobEIP4844Transaction { if (!opts || !opts.common) { throw new Error('common instance required to validate versioned hashes') @@ -219,7 +219,7 @@ export function create4844BlobTxFromSerializedNetworkWrapper( if (opts.common?.customCrypto?.kzg === undefined) { throw new Error( - 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx', ) } @@ -227,7 +227,7 @@ export function create4844BlobTxFromSerializedNetworkWrapper( throw new Error( `Invalid serialized tx input: not an EIP-4844 transaction (wrong tx type, expected: ${ TransactionType.BlobEIP4844 - }, received: ${bytesToHex(serialized.subarray(0, 1))}` + }, received: ${bytesToHex(serialized.subarray(0, 1))}`, ) } @@ -252,7 +252,7 @@ export function create4844BlobTxFromSerializedNetworkWrapper( kzgCommitments, kzgProofs, version, - opts.common.customCrypto.kzg + opts.common.customCrypto.kzg, ) // set the network blob data on the tx @@ -278,11 +278,11 @@ export function create4844BlobTxFromSerializedNetworkWrapper( */ export function createMinimal4844TxFromNetworkWrapper( txData: BlobEIP4844Transaction, - opts?: TxOptions + opts?: TxOptions, ): BlobEIP4844Transaction { if (opts?.common?.customCrypto?.kzg === undefined) { throw new Error( - 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx' + 'A common object with customCrypto.kzg initialized required to instantiate a 4844 blob tx', ) } @@ -291,7 +291,7 @@ export function createMinimal4844TxFromNetworkWrapper( ...txData, ...{ blobs: undefined, kzgCommitments: undefined, kzgProofs: undefined }, }, - opts + opts, ) return tx } @@ -305,7 +305,7 @@ export function createMinimal4844TxFromNetworkWrapper( */ export function blobTxNetworkWrapperToJSON( serialized: Uint8Array, - opts?: TxOptions + opts?: TxOptions, ): JsonBlobTxNetworkWrapper { const tx = create4844BlobTxFromSerializedNetworkWrapper(serialized, opts) diff --git a/packages/tx/src/4844/tx.ts b/packages/tx/src/4844/tx.ts index 549ccd79ff..f6c69b2ad5 100644 --- a/packages/tx/src/4844/tx.ts +++ b/packages/tx/src/4844/tx.ts @@ -100,13 +100,13 @@ export class BlobEIP4844Transaction extends BaseTransaction toBytes(vh)) @@ -132,7 +132,7 @@ export class BlobEIP4844Transaction extends BaseTransaction if (this.getIntrinsicGas() > this.gasLimit) { errors.push( - `gasLimit is too low. given ${this.gasLimit}, need at least ${this.getIntrinsicGas()}` + `gasLimit is too low. given ${this.gasLimit}, need at least ${this.getIntrinsicGas()}`, ) } @@ -367,7 +367,7 @@ export abstract class BaseTransaction v: bigint, r: Uint8Array | bigint, s: Uint8Array | bigint, - convertV?: boolean + convertV?: boolean, ): Transaction[T] /** @@ -385,7 +385,7 @@ export abstract class BaseTransaction if (common) { if (common.chainId() !== chainIdBigInt) { const msg = this._errorMsg( - `The chain ID does not match the chain ID of Common. Got: ${chainIdBigInt}, expected: ${common.chainId()}` + `The chain ID does not match the chain ID of Common. Got: ${chainIdBigInt}, expected: ${common.chainId()}`, ) throw new Error(msg) } @@ -405,7 +405,7 @@ export abstract class BaseTransaction name: 'custom-chain', chainId: chainIdBigInt, }, - { baseChain: this.DEFAULT_CHAIN } + { baseChain: this.DEFAULT_CHAIN }, ) } } @@ -425,7 +425,7 @@ export abstract class BaseTransaction protected _validateCannotExceedMaxInteger( values: { [key: string]: bigint | undefined }, bits = 256, - cannotEqual = false + cannotEqual = false, ) { for (const [key, value] of Object.entries(values)) { switch (bits) { @@ -433,7 +433,7 @@ export abstract class BaseTransaction if (cannotEqual) { if (value !== undefined && value >= MAX_UINT64) { const msg = this._errorMsg( - `${key} cannot equal or exceed MAX_UINT64 (2^64-1), given ${value}` + `${key} cannot equal or exceed MAX_UINT64 (2^64-1), given ${value}`, ) throw new Error(msg) } @@ -448,14 +448,14 @@ export abstract class BaseTransaction if (cannotEqual) { if (value !== undefined && value >= MAX_INTEGER) { const msg = this._errorMsg( - `${key} cannot equal or exceed MAX_INTEGER (2^256-1), given ${value}` + `${key} cannot equal or exceed MAX_INTEGER (2^256-1), given ${value}`, ) throw new Error(msg) } } else { if (value !== undefined && value > MAX_INTEGER) { const msg = this._errorMsg( - `${key} cannot exceed MAX_INTEGER (2^256-1), given ${value}` + `${key} cannot exceed MAX_INTEGER (2^256-1), given ${value}`, ) throw new Error(msg) } diff --git a/packages/tx/src/capabilities/eip1559.ts b/packages/tx/src/capabilities/eip1559.ts index d76c744f39..7c9047ff9a 100644 --- a/packages/tx/src/capabilities/eip1559.ts +++ b/packages/tx/src/capabilities/eip1559.ts @@ -10,7 +10,7 @@ export function getUpfrontCost(tx: EIP1559CompatibleTx, baseFee: bigint): bigint export function getEffectivePriorityFee( tx: EIP1559CompatibleTx, - baseFee: bigint | undefined + baseFee: bigint | undefined, ): bigint { if (baseFee === undefined || baseFee > tx.maxFeePerGas) { throw new Error('Tx cannot pay baseFee') diff --git a/packages/tx/src/capabilities/eip7702.ts b/packages/tx/src/capabilities/eip7702.ts index 52c1b3bc91..3839485a0b 100644 --- a/packages/tx/src/capabilities/eip7702.ts +++ b/packages/tx/src/capabilities/eip7702.ts @@ -10,7 +10,7 @@ import type { EIP7702CompatibleTx } from '../types.js' export function getDataGas(tx: EIP7702CompatibleTx): bigint { const eip2930Cost = BigInt(AccessLists.getDataGasEIP2930(tx.accessList, tx.common)) const eip7702Cost = BigInt( - tx.authorizationList.length * Number(tx.common.param('perAuthBaseGas')) + tx.authorizationList.length * Number(tx.common.param('perAuthBaseGas')), ) return Legacy.getDataGas(tx, eip2930Cost + eip7702Cost) } diff --git a/packages/tx/src/capabilities/legacy.ts b/packages/tx/src/capabilities/legacy.ts index 342acd39a4..34ebd741dc 100644 --- a/packages/tx/src/capabilities/legacy.ts +++ b/packages/tx/src/capabilities/legacy.ts @@ -66,7 +66,7 @@ export function validateHighS(tx: LegacyTxInterface): void { if (tx.common.gteHardfork('homestead') && s !== undefined && s > SECP256K1_ORDER_DIV_2) { const msg = errorMsg( tx, - 'Invalid Signature: s-values greater than secp256k1n/2 are considered invalid' + 'Invalid Signature: s-values greater than secp256k1n/2 are considered invalid', ) throw new Error(msg) } @@ -90,7 +90,7 @@ export function getSenderPublicKey(tx: LegacyTxInterface): Uint8Array { v!, bigIntToUnpaddedBytes(r!), bigIntToUnpaddedBytes(s!), - tx.supports(Capability.EIP155ReplayProtection) ? tx.common.chainId() : undefined + tx.supports(Capability.EIP155ReplayProtection) ? tx.common.chainId() : undefined, ) if (Object.isFrozen(tx)) { tx.cache.senderPubKey = sender diff --git a/packages/tx/src/legacy/constructors.ts b/packages/tx/src/legacy/constructors.ts index 002d32bd55..35657d6897 100644 --- a/packages/tx/src/legacy/constructors.ts +++ b/packages/tx/src/legacy/constructors.ts @@ -28,7 +28,7 @@ export function createLegacyTxFromBytesArray(values: TxValuesArray, opts: TxOpti // This happens if you get the RLP data from `raw()` if (values.length !== 6 && values.length !== 9) { throw new Error( - 'Invalid transaction. Only expecting 6 values (for unsigned tx) or 9 values (for signed tx).' + 'Invalid transaction. Only expecting 6 values (for unsigned tx) or 9 values (for signed tx).', ) } @@ -48,7 +48,7 @@ export function createLegacyTxFromBytesArray(values: TxValuesArray, opts: TxOpti r, s, }, - opts + opts, ) } diff --git a/packages/tx/src/legacy/tx.ts b/packages/tx/src/legacy/tx.ts index 29ec2c64d2..ffec6db20f 100644 --- a/packages/tx/src/legacy/tx.ts +++ b/packages/tx/src/legacy/tx.ts @@ -219,7 +219,7 @@ export class LegacyTransaction extends BaseTransaction { v: bigint, r: Uint8Array | bigint, s: Uint8Array | bigint, - convertV: boolean = false + convertV: boolean = false, ): LegacyTransaction { r = toBytes(r) s = toBytes(s) @@ -241,7 +241,7 @@ export class LegacyTransaction extends BaseTransaction { r: bytesToBigInt(r), s: bytesToBigInt(s), }, - opts + opts, ) } @@ -268,7 +268,7 @@ export class LegacyTransaction extends BaseTransaction { // v is 2. not matching the classic v=27 or v=28 case if (v < 37 && v !== 27 && v !== 28) { throw new Error( - `Legacy txs need either v = 27/28 or v >= 37 (EIP-155 replay protection), got v = ${v}` + `Legacy txs need either v = 27/28 or v >= 37 (EIP-155 replay protection), got v = ${v}`, ) } } @@ -284,7 +284,7 @@ export class LegacyTransaction extends BaseTransaction { if (common) { if (!meetsEIP155(BigInt(v), common.chainId())) { throw new Error( - `Incompatible EIP155-based V ${v} and chain id ${common.chainId()}. See the Common parameter of the Transaction constructor to set the chain id.` + `Incompatible EIP155-based V ${v} and chain id ${common.chainId()}. See the Common parameter of the Transaction constructor to set the chain id.`, ) } } else { diff --git a/packages/tx/src/transactionFactory.ts b/packages/tx/src/transactionFactory.ts index 22ca0a7021..e543320f1d 100644 --- a/packages/tx/src/transactionFactory.ts +++ b/packages/tx/src/transactionFactory.ts @@ -29,7 +29,7 @@ import type { EthersProvider } from '@ethereumjs/util' */ export function createTxFromTxData( txData: TypedTxData, - txOptions: TxOptions = {} + txOptions: TxOptions = {}, ): Transaction[T] { if (!('type' in txData) || txData.type === undefined) { // Assume legacy transaction @@ -59,7 +59,7 @@ export function createTxFromTxData( */ export function createTxFromSerializedData( data: Uint8Array, - txOptions: TxOptions = {} + txOptions: TxOptions = {}, ): Transaction[T] { if (data[0] <= 0x7f) { // Determine the type. @@ -91,7 +91,7 @@ export function createTxFromSerializedData( */ export function createTxFromBlockBodyData( data: Uint8Array | Uint8Array[], - txOptions: TxOptions = {} + txOptions: TxOptions = {}, ) { if (data instanceof Uint8Array) { return createTxFromSerializedData(data, txOptions) @@ -112,7 +112,7 @@ export function createTxFromBlockBodyData( */ export async function createTxFromRPC( txData: TxData[T], - txOptions: TxOptions = {} + txOptions: TxOptions = {}, ): Promise { return createTxFromTxData(normalizeTxParams(txData), txOptions) } @@ -127,7 +127,7 @@ export async function createTxFromRPC( export async function createTxFromJsonRpcProvider( provider: string | EthersProvider, txHash: string, - txOptions?: TxOptions + txOptions?: TxOptions, ) { const prov = getProvider(provider) const txData = await fetchFromProvider(prov, { diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index 792fbe0427..f361532663 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -118,7 +118,7 @@ export function isAccessList(input: AccessListBytes | AccessList): input is Acce } export function isAuthorizationListBytes( - input: AuthorizationListBytes | AuthorizationList + input: AuthorizationListBytes | AuthorizationList, ): input is AuthorizationListBytes { if (input.length === 0) { return true @@ -131,7 +131,7 @@ export function isAuthorizationListBytes( } export function isAuthorizationList( - input: AuthorizationListBytes | AuthorizationList + input: AuthorizationListBytes | AuthorizationList, ): input is AuthorizationList { return !isAuthorizationListBytes(input) // This is exactly the same method, except the output is negated. } @@ -447,7 +447,7 @@ type AccessListEIP2930TxValuesArray = [ AccessListBytes, Uint8Array?, Uint8Array?, - Uint8Array? + Uint8Array?, ] /** @@ -465,7 +465,7 @@ type FeeMarketEIP1559TxValuesArray = [ AccessListBytes, Uint8Array?, Uint8Array?, - Uint8Array? + Uint8Array?, ] /** @@ -484,7 +484,7 @@ type EOACodeEIP7702TxValuesArray = [ AuthorizationListBytes, Uint8Array?, Uint8Array?, - Uint8Array? + Uint8Array?, ] /** @@ -504,14 +504,14 @@ type BlobEIP4844TxValuesArray = [ Uint8Array[], Uint8Array?, Uint8Array?, - Uint8Array? + Uint8Array?, ] export type BlobEIP4844NetworkValuesArray = [ BlobEIP4844TxValuesArray, Uint8Array[], Uint8Array[], - Uint8Array[] + Uint8Array[], ] type JsonAccessListItem = { address: string; storageKeys: string[] } diff --git a/packages/tx/src/util.ts b/packages/tx/src/util.ts index ab3594dc8e..2079045428 100644 --- a/packages/tx/src/util.ts +++ b/packages/tx/src/util.ts @@ -23,8 +23,8 @@ export function checkMaxInitCodeSize(common: Common, length: number) { if (maxInitCodeSize && BigInt(length) > maxInitCodeSize) { throw new Error( `the initcode size of this transaction is too large: it is ${length} while the max is ${common.param( - 'maxInitCodeSize' - )}` + 'maxInitCodeSize', + )}`, ) } } @@ -80,7 +80,7 @@ export class AccessLists { const storageSlots = accessListItem[1] if ((accessListItem)[2] !== undefined) { throw new Error( - 'Access list item cannot have 3 elements. It can only have an address, and an array of storage slots.' + 'Access list item cannot have 3 elements. It can only have an address, and an array of storage slots.', ) } if (address.length !== 20) { @@ -130,7 +130,7 @@ export class AccessLists { export class AuthorizationLists { public static getAuthorizationListData( - authorizationList: AuthorizationListBytes | AuthorizationList + authorizationList: AuthorizationListBytes | AuthorizationList, ) { let AuthorizationListJSON let bufferAuthorizationList diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index 6c93a58b3c..1f0d405449 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -119,7 +119,7 @@ describe('[BaseTransaction]', () => { assert.equal( tx.common.hardfork(), 'london', - `${txType.name}: should initialize with correct HF provided` + `${txType.name}: should initialize with correct HF provided`, ) assert.ok(Object.isFrozen(tx), `${txType.name}: tx should be frozen by default`) @@ -131,20 +131,20 @@ describe('[BaseTransaction]', () => { assert.equal( tx.common.hardfork(), 'london', - `${txType.name}: should initialize with correct HF provided` + `${txType.name}: should initialize with correct HF provided`, ) initCommon.setHardfork(Hardfork.Byzantium) assert.equal( tx.common.hardfork(), 'london', - `${txType.name}: should stay on correct HF if outer common HF changes` + `${txType.name}: should stay on correct HF if outer common HF changes`, ) tx = txType.create.txData({}, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), - `${txType.name}: tx should not be frozen when freeze deactivated in options` + `${txType.name}: tx should not be frozen when freeze deactivated in options`, ) // Perform the same test as above, but now using a different construction method. This also implies that passing on the @@ -156,7 +156,7 @@ describe('[BaseTransaction]', () => { assert.equal( tx.type, txType.type, - `${txType.name}: fromSerializedTx() -> should initialize correctly` + `${txType.name}: fromSerializedTx() -> should initialize correctly`, ) assert.ok(Object.isFrozen(tx), `${txType.name}: tx should be frozen by default`) @@ -164,7 +164,7 @@ describe('[BaseTransaction]', () => { tx = txType.create.rlp(rlpData, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), - `${txType.name}: tx should not be frozen when freeze deactivated in options` + `${txType.name}: tx should not be frozen when freeze deactivated in options`, ) tx = txType.create.bytesArray(txType.values as any, { common }) @@ -173,7 +173,7 @@ describe('[BaseTransaction]', () => { tx = txType.create.bytesArray(txType.values as any, { common, freeze: false }) assert.ok( !Object.isFrozen(tx), - `${txType.name}: tx should not be frozen when freeze deactivated in options` + `${txType.name}: tx should not be frozen when freeze deactivated in options`, ) } }) @@ -187,7 +187,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('nonce cannot have leading zeroes'), - 'should throw with nonce with leading zeroes' + 'should throw with nonce with leading zeroes', ) } rlpData[0] = toBytes('0x') @@ -198,7 +198,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('v cannot have leading zeroes'), - 'should throw with v with leading zeroes' + 'should throw with v with leading zeroes', ) } rlpData = eip2930Txs[0].raw() @@ -209,7 +209,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('gasLimit cannot have leading zeroes'), - 'should throw with gasLimit with leading zeroes' + 'should throw with gasLimit with leading zeroes', ) } rlpData = eip1559Txs[0].raw() @@ -220,7 +220,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('maxPriorityFeePerGas cannot have leading zeroes'), - 'should throw with maxPriorityFeePerGas with leading zeroes' + 'should throw with maxPriorityFeePerGas with leading zeroes', ) } }) @@ -230,11 +230,11 @@ describe('[BaseTransaction]', () => { for (const tx of txType.txs) { assert.ok( txType.create.rlp(tx.serialize(), { common }), - `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()` + `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()`, ) assert.ok( txType.create.rlp(tx.serialize(), { common }), - `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()` + `${txType.name}: should do roundtrip serialize() -> fromSerializedTx()`, ) } } @@ -246,13 +246,13 @@ describe('[BaseTransaction]', () => { for (const activeCapability of txType.activeCapabilities) { assert.ok( tx.supports(activeCapability), - `${txType.name}: should recognize all supported capabilities` + `${txType.name}: should recognize all supported capabilities`, ) } for (const notActiveCapability of txType.notActiveCapabilities) { assert.notOk( tx.supports(notActiveCapability), - `${txType.name}: should reject non-active existing and not existing capabilities` + `${txType.name}: should reject non-active existing and not existing capabilities`, ) } } @@ -264,7 +264,7 @@ describe('[BaseTransaction]', () => { for (const tx of txType.txs) { assert.ok( txType.create.bytesArray(tx.raw() as any, { common }), - `${txType.name}: should do roundtrip raw() -> fromValuesArray()` + `${txType.name}: should do roundtrip raw() -> fromValuesArray()`, ) } } @@ -287,7 +287,7 @@ describe('[BaseTransaction]', () => { assert.equal(tx.verifySignature(), false, `${txType.name}: signature should not be valid`) assert.ok( tx.getValidationErrors().includes('Invalid Signature'), - `${txType.name}: should return an error string about not verifying signatures` + `${txType.name}: should return an error string about not verifying signatures`, ) assert.notOk(tx.isValid(), `${txType.name}: should not validate correctly`) } @@ -306,7 +306,7 @@ describe('[BaseTransaction]', () => { () => tx.sign(utf8ToBytes('invalid')), undefined, undefined, - `${txType.name}: should fail with invalid PK` + `${txType.name}: should fail with invalid PK`, ) } } @@ -323,14 +323,14 @@ describe('[BaseTransaction]', () => { v: undefined, r: undefined, s: undefined, - }) + }), ), ] for (const tx of txs) { assert.equal( tx.isSigned(), tx.v !== undefined && tx.r !== undefined && tx.s !== undefined, - 'isSigned() returns correctly' + 'isSigned() returns correctly', ) } } @@ -345,7 +345,7 @@ describe('[BaseTransaction]', () => { assert.equal( signedTx.getSenderAddress().toString(), `0x${sendersAddress}`, - `${txType.name}: should get sender's address after signing it` + `${txType.name}: should get sender's address after signing it`, ) } } @@ -362,7 +362,7 @@ describe('[BaseTransaction]', () => { const pubKeyFromPriv = privateToPublic(hexToBytes(`0x${privateKey}`)) assert.ok( equalsBytes(txPubKey, pubKeyFromPriv), - `${txType.name}: should get sender's public key after signing it` + `${txType.name}: should get sender's public key after signing it`, ) } } @@ -385,7 +385,7 @@ describe('[BaseTransaction]', () => { }, undefined, undefined, - 'should throw when s-value is greater than secp256k1n/2' + 'should throw when s-value is greater than secp256k1n/2', ) } } @@ -435,7 +435,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('equal or exceed MAX_INTEGER'), - 'throws when value equals or exceeds MAX_INTEGER' + 'throws when value equals or exceeds MAX_INTEGER', ) } try { @@ -448,7 +448,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('unimplemented bits value'), - 'throws when bits value other than 64 or 256 provided' + 'throws when bits value other than 64 or 256 provided', ) } try { @@ -461,7 +461,7 @@ describe('[BaseTransaction]', () => { } catch (err: any) { assert.ok( err.message.includes('2^64'), - 'throws when 64 bit integer equals or exceeds MAX_UINT64' + 'throws when 64 bit integer equals or exceeds MAX_UINT64', ) } }) diff --git a/packages/tx/test/eip1559.spec.ts b/packages/tx/test/eip1559.spec.ts index 8588d7929b..6f9e7f08df 100644 --- a/packages/tx/test/eip1559.spec.ts +++ b/packages/tx/test/eip1559.spec.ts @@ -75,7 +75,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { gasLimit: 100, value: 6, }, - { common } + { common }, ) assert.equal(tx.getUpfrontCost(), BigInt(806), 'correct upfront cost with default base fee') let baseFee = BigInt(0) @@ -84,7 +84,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { assert.equal( tx.getUpfrontCost(baseFee), BigInt(1006), - 'correct upfront cost with cost-changing base fee value' + 'correct upfront cost with cost-changing base fee value', ) }) @@ -94,7 +94,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { maxFeePerGas: 10, maxPriorityFeePerGas: 8, }, - { common } + { common }, ) assert.equal(tx.getEffectivePriorityFee(BigInt(10)), BigInt(0)) assert.equal(tx.getEffectivePriorityFee(BigInt(9)), BigInt(1)) @@ -114,7 +114,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { const rlpSerialized = RLP.encode(Uint8Array.from(signed.serialize())) assert.ok( equalsBytes(rlpSerialized, hexToBytes(data.signedTransactionRLP as PrefixedHexString)), - 'Should sign txs correctly' + 'Should sign txs correctly', ) } }) @@ -160,11 +160,11 @@ describe('[FeeMarketEIP1559Transaction]', () => { let txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common }) let signed = txn.sign(pkey) const expectedHash = hexToBytes( - '0x2e564c87eb4b40e7f469b2eec5aa5d18b0b46a24e8bf0919439cfb0e8fcae446' + '0x2e564c87eb4b40e7f469b2eec5aa5d18b0b46a24e8bf0919439cfb0e8fcae446', ) assert.ok( equalsBytes(signed.hash(), expectedHash), - 'Should provide the correct hash when frozen' + 'Should provide the correct hash when frozen', ) txn = create1559FeeMarketTx(data as FeeMarketEIP1559TxData, { common, @@ -173,7 +173,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { signed = txn.sign(pkey) assert.ok( equalsBytes(signed.hash(), expectedHash), - 'Should provide the correct hash when not frozen' + 'Should provide the correct hash when not frozen', ) }) @@ -209,7 +209,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { const signedTxn = txn.sign(pkey) assert.ok( signedTxn.common.hardfork() === Hardfork.Paris, - 'signed tx common is taken from tx.common' + 'signed tx common is taken from tx.common', ) }) @@ -221,20 +221,20 @@ describe('[FeeMarketEIP1559Transaction]', () => { accessList: [[validAddress, [validSlot]]], chainId, }, - { common } + { common }, ) const expectedHash = hexToBytes( - '0xfa81814f7dd57bad435657a05eabdba2815f41e3f15ddd6139027e7db56b0dea' + '0xfa81814f7dd57bad435657a05eabdba2815f41e3f15ddd6139027e7db56b0dea', ) assert.deepEqual(unsignedTx.getHashedMessageToSign(), expectedHash), 'correct hashed version' const expectedSerialization = hexToBytes( - '0x02f85904808080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101' + '0x02f85904808080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101', ) assert.deepEqual( unsignedTx.getMessageToSign(), expectedSerialization, - 'correct serialized unhashed version' + 'correct serialized unhashed version', ) }) @@ -273,7 +273,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { gasLimit: 1, value: 6, }, - { common } + { common }, ) }, 'fee can be 2^256 - 1') assert.throws( @@ -285,12 +285,12 @@ describe('[FeeMarketEIP1559Transaction]', () => { gasLimit: 100, value: 6, }, - { common } + { common }, ) }, undefined, undefined, - 'fee must be less than 2^256' + 'fee must be less than 2^256', ) assert.throws( () => { @@ -301,12 +301,12 @@ describe('[FeeMarketEIP1559Transaction]', () => { gasLimit: 100, value: 6, }, - { common } + { common }, ) }, undefined, undefined, - 'total fee must be the larger of the two' + 'total fee must be the larger of the two', ) }) }) diff --git a/packages/tx/test/eip3860.spec.ts b/packages/tx/test/eip3860.spec.ts index 8a7a2fbf73..8230db40aa 100644 --- a/packages/tx/test/eip3860.spec.ts +++ b/packages/tx/test/eip3860.spec.ts @@ -88,15 +88,15 @@ describe('[EIP3860 tests]', () => { for (const txType of txTypes) { const eip3860ActiveTx = createTxFromTxData( { data, type: txType }, - { common, allowUnlimitedInitCodeSize: true } + { common, allowUnlimitedInitCodeSize: true }, ) const eip3860DeactivedTx = createTxFromTxData( { data, type: txType }, - { common, allowUnlimitedInitCodeSize: false } + { common, allowUnlimitedInitCodeSize: false }, ) assert.ok( eip3860ActiveTx.getDataGas() === eip3860DeactivedTx.getDataGas(), - 'charged initcode analysis gas' + 'charged initcode analysis gas', ) } }) diff --git a/packages/tx/test/eip4844.spec.ts b/packages/tx/test/eip4844.spec.ts index 4bf52bfe47..d7e8c4d363 100644 --- a/packages/tx/test/eip4844.spec.ts +++ b/packages/tx/test/eip4844.spec.ts @@ -49,7 +49,7 @@ describe('EIP4844 addSignature tests', () => { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, - { common } + { common }, ) const signedTx = tx.sign(privateKey) const addSignatureTx = tx.addSignature(signedTx.v!, signedTx.r!, signedTx.s!) @@ -64,7 +64,7 @@ describe('EIP4844 addSignature tests', () => { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, - { common } + { common }, ) const msgHash = tx.getHashedMessageToSign() @@ -83,7 +83,7 @@ describe('EIP4844 addSignature tests', () => { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, - { common } + { common }, ) const msgHash = tx.getHashedMessageToSign() @@ -129,7 +129,7 @@ describe('EIP4844 constructor tests - valid scenarios', () => { assert.equal( decodedTx.getSenderAddress().toString(), sender, - 'signature and sender were deserialized correctly' + 'signature and sender were deserialized correctly', ) }) }) @@ -188,17 +188,17 @@ describe('fromTxData using from a json', () => { assert.deepEqual( { ...txData, accessList: [] }, { gasPrice: null, ...jsonData }, - 'toJSON should give correct json' + 'toJSON should give correct json', ) const fromSerializedTx = create4844BlobTxFromRLP( hexToBytes(txMeta.serialized as PrefixedHexString), - { common: c } + { common: c }, ) assert.equal( bytesToHex(fromSerializedTx.hash()), txMeta.hash, - 'fromSerializedTx hash should match' + 'fromSerializedTx hash should match', ) } catch (e) { assert.fail('failed to parse json data') @@ -240,7 +240,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { } catch (err: any) { assert.ok( err.message.includes('versioned hash is invalid length'), - 'throws on invalid versioned hash length' + 'throws on invalid versioned hash length', ) } try { @@ -248,7 +248,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { } catch (err: any) { assert.ok( err.message.includes('does not start with KZG commitment'), - 'throws on invalid commitment version' + 'throws on invalid commitment version', ) } try { @@ -256,7 +256,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { } catch (err: any) { assert.ok( err.message.includes('tx can contain at most'), - 'throws on too many versioned hashes' + 'throws on too many versioned hashes', ) } }) @@ -288,7 +288,7 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) const signedTx = unsignedTx.sign(pk) @@ -305,7 +305,7 @@ describe('Network wrapper tests', () => { assert.equal( jsonData.kzgCommitments.length, signedTx.kzgCommitments!.length, - 'contains the correct number of commitments' + 'contains the correct number of commitments', ) for (let i = 0; i < jsonData.kzgCommitments.length; i++) { const c1 = jsonData.kzgCommitments[i] @@ -315,7 +315,7 @@ describe('Network wrapper tests', () => { assert.equal( jsonData.kzgProofs?.length, signedTx.kzgProofs!.length, - 'contains the correct number of proofs' + 'contains the correct number of proofs', ) for (let i = 0; i < jsonData.kzgProofs.length; i++) { const p1 = jsonData.kzgProofs[i] @@ -330,19 +330,19 @@ describe('Network wrapper tests', () => { assert.equal( deserializedTx.type, 0x03, - 'successfully deserialized a blob transaction network wrapper' + 'successfully deserialized a blob transaction network wrapper', ) assert.equal(deserializedTx.blobs?.length, blobs.length, 'contains the correct number of blobs') assert.equal( deserializedTx.getSenderAddress().toString(), sender, - 'decoded sender address correctly' + 'decoded sender address correctly', ) const minimalTx = createMinimal4844TxFromNetworkWrapper(deserializedTx, { common }) assert.ok(minimalTx.blobs === undefined, 'minimal representation contains no blobs') assert.ok( equalsBytes(minimalTx.hash(), deserializedTx.hash()), - 'has the same hash as the network wrapper version' + 'has the same hash as the network wrapper version', ) const simpleBlobTx = create4844BlobTx( @@ -352,13 +352,13 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) assert.equal( bytesToHex(unsignedTx.blobVersionedHashes[0]), bytesToHex(simpleBlobTx.blobVersionedHashes[0]), - 'tx versioned hash for simplified blob txData constructor matches fully specified versioned hashes' + 'tx versioned hash for simplified blob txData constructor matches fully specified versioned hashes', ) assert.throws( @@ -371,11 +371,11 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ), 'encoded blobs', undefined, - 'throws on blobsData and blobs in txData' + 'throws on blobsData and blobs in txData', ) assert.throws( @@ -388,11 +388,11 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ), 'KZG commitments', undefined, - 'throws on blobsData and KZG commitments in txData' + 'throws on blobsData and KZG commitments in txData', ) assert.throws( @@ -405,11 +405,11 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ), 'versioned hashes', undefined, - 'throws on blobsData and versioned hashes in txData' + 'throws on blobsData and versioned hashes in txData', ) assert.throws( @@ -422,11 +422,11 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ), 'KZG proofs', undefined, - 'throws on blobsData and KZG proofs in txData' + 'throws on blobsData and KZG proofs in txData', ) assert.throws( @@ -441,12 +441,12 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) }, 'tx should contain at least one blob', undefined, - 'throws a transaction with no blobs' + 'throws a transaction with no blobs', ) const txWithMissingBlob = create4844BlobTx( @@ -459,7 +459,7 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) const serializedWithMissingBlob = txWithMissingBlob.serializeNetworkWrapper() @@ -471,7 +471,7 @@ describe('Network wrapper tests', () => { }), 'Number of blobVersionedHashes, blobs, and commitments not all equal', undefined, - 'throws when blobs/commitments/hashes mismatch' + 'throws when blobs/commitments/hashes mismatch', ) const mangledValue = commitments[0][0] @@ -487,7 +487,7 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) const serializedWithInvalidCommitment = txWithInvalidCommitment.serializeNetworkWrapper() @@ -499,7 +499,7 @@ describe('Network wrapper tests', () => { }), 'KZG proof cannot be verified from blobs/commitments', undefined, - 'throws when kzg proof cant be verified' + 'throws when kzg proof cant be verified', ) blobVersionedHashes[0][1] = 2 @@ -515,7 +515,7 @@ describe('Network wrapper tests', () => { gasLimit: 0xffffffn, to: randomBytes(20), }, - { common } + { common }, ) const serializedWithInvalidVersionedHashes = @@ -527,7 +527,7 @@ describe('Network wrapper tests', () => { }), 'commitment for blob at index 0 does not match versionedHash', undefined, - 'throws when versioned hashes dont match kzg commitments' + 'throws when versioned hashes dont match kzg commitments', ) }) }) @@ -562,21 +562,21 @@ describe('hash() and signature verification', () => { ], to: Address.zero(), }, - { common } + { common }, ) assert.equal( bytesToHex(unsignedTx.getHashedMessageToSign()), '0x02560c5173b0d793ce019cfa515ece6a04a4b3f3d67eab67fbca78dd92d4ed76', - 'produced the correct transaction hash' + 'produced the correct transaction hash', ) const signedTx = unsignedTx.sign( - hexToBytes('0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8') + hexToBytes('0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8'), ) assert.equal( signedTx.getSenderAddress().toString(), '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', - 'was able to recover sender address' + 'was able to recover sender address', ) assert.ok(signedTx.verifySignature(), 'signature is valid') }) @@ -596,7 +596,7 @@ it('getEffectivePriorityFee()', async () => { to: Address.zero(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, - { common } + { common }, ) assert.equal(tx.getEffectivePriorityFee(BigInt(10)), BigInt(0)) assert.equal(tx.getEffectivePriorityFee(BigInt(9)), BigInt(1)) @@ -665,7 +665,7 @@ describe('Network wrapper deserialization test', () => { assert.ok(equalsBytes(deserializedTx.blobs![0], blobs[0]), 'blobs should match') assert.ok( equalsBytes(deserializedTx.kzgCommitments![0], commitments[0]), - 'commitments should match' + 'commitments should match', ) assert.ok(equalsBytes(deserializedTx.kzgProofs![0], proofs[0]), 'proofs should match') @@ -685,7 +685,7 @@ describe('Network wrapper deserialization test', () => { sender, networkSerializedHexLength: networkSerialized.length, }, - 'txMeta should match' + 'txMeta should match', ) }) }) diff --git a/packages/tx/test/eip7702.spec.ts b/packages/tx/test/eip7702.spec.ts index 6213a1085f..47222ce5c4 100644 --- a/packages/tx/test/eip7702.spec.ts +++ b/packages/tx/test/eip7702.spec.ts @@ -27,7 +27,7 @@ describe('[EOACodeEIP7702Transaction]', () => { to: Address.zero(), data: new Uint8Array(1), }, - { common } + { common }, ) const signed = txn.sign(pkey) assert.ok(signed.getSenderAddress().equals(addr)) @@ -50,7 +50,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'address length should be 20 bytes') @@ -68,7 +68,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'nonce list should consist of at most 1 item') @@ -86,7 +86,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 's is not defined') @@ -104,7 +104,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'r is not defined') @@ -122,7 +122,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'yParity is not defined') @@ -140,7 +140,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'nonce is not defined') @@ -158,7 +158,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'address is not defined') @@ -176,7 +176,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }, 'chainId is not defined') @@ -194,7 +194,7 @@ describe('[EOACodeEIP7702Transaction]', () => { }, ], }, - { common } + { common }, ) }) }) diff --git a/packages/tx/test/fromRpc.spec.ts b/packages/tx/test/fromRpc.spec.ts index 171d7f14b5..45106f6871 100644 --- a/packages/tx/test/fromRpc.spec.ts +++ b/packages/tx/test/fromRpc.spec.ts @@ -64,7 +64,7 @@ describe('[fromJsonRpcProvider]', () => { } catch (err: any) { assert.ok( err.message.includes('No data returned from provider'), - 'throws correct error when no tx returned' + 'throws correct error when no tx returned', ) } global.fetch = realFetch diff --git a/packages/tx/test/inputValue.spec.ts b/packages/tx/test/inputValue.spec.ts index 9d718a3cbd..8fa64c4612 100644 --- a/packages/tx/test/inputValue.spec.ts +++ b/packages/tx/test/inputValue.spec.ts @@ -162,21 +162,21 @@ describe('[Invalid Array Input values]', () => { switch (txType) { case TransactionType.Legacy: assert.throws(() => - createLegacyTxFromBytesArray(rawValues as TxValuesArray[TransactionType.Legacy]) + createLegacyTxFromBytesArray(rawValues as TxValuesArray[TransactionType.Legacy]), ) break case TransactionType.AccessListEIP2930: assert.throws(() => create2930AccessListTxFromBytesArray( - rawValues as TxValuesArray[TransactionType.AccessListEIP2930] - ) + rawValues as TxValuesArray[TransactionType.AccessListEIP2930], + ), ) break case TransactionType.FeeMarketEIP1559: assert.throws(() => createEIP1559FeeMarketTxFromBytesArray( - rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559] - ) + rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559], + ), ) break } @@ -243,15 +243,15 @@ describe('[Invalid Access Lists]', () => { case TransactionType.AccessListEIP2930: assert.throws(() => create2930AccessListTxFromBytesArray( - rawValues as TxValuesArray[TransactionType.AccessListEIP2930] - ) + rawValues as TxValuesArray[TransactionType.AccessListEIP2930], + ), ) break case TransactionType.FeeMarketEIP1559: assert.throws(() => createEIP1559FeeMarketTxFromBytesArray( - rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559] - ) + rawValues as TxValuesArray[TransactionType.FeeMarketEIP1559], + ), ) break } diff --git a/packages/tx/test/legacy.spec.ts b/packages/tx/test/legacy.spec.ts index 0f23043122..181400ba56 100644 --- a/packages/tx/test/legacy.spec.ts +++ b/packages/tx/test/legacy.spec.ts @@ -62,7 +62,7 @@ describe('[Transaction]', () => { const nonEIP2930Common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) assert.ok( createLegacyTx({}, { common: nonEIP2930Common }), - 'should initialize on a pre-Berlin Harfork (EIP-2930 not activated)' + 'should initialize on a pre-Berlin Harfork (EIP-2930 not activated)', ) const txData = txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) @@ -70,14 +70,14 @@ describe('[Transaction]', () => { let tx = createLegacyTxFromBytesArray(txData) assert.ok( tx.common.chainId() === BigInt(5), - 'should initialize Common with chain ID (supported) derived from v value (v with 0-parity)' + 'should initialize Common with chain ID (supported) derived from v value (v with 0-parity)', ) txData[6] = intToBytes(46) // v with 1-parity and chain ID 5 tx = createLegacyTxFromBytesArray(txData) assert.ok( tx.common.chainId() === BigInt(5), - 'should initialize Common with chain ID (supported) derived from v value (v with 1-parity)' + 'should initialize Common with chain ID (supported) derived from v value (v with 1-parity)', ) txData[6] = intToBytes(2033) // v with 0-parity and chain ID 999 @@ -85,7 +85,7 @@ describe('[Transaction]', () => { assert.equal( tx.common.chainId(), BigInt(999), - 'should initialize Common with chain ID (unsupported) derived from v value (v with 0-parity)' + 'should initialize Common with chain ID (unsupported) derived from v value (v with 0-parity)', ) txData[6] = intToBytes(2034) // v with 1-parity and chain ID 999 @@ -93,7 +93,7 @@ describe('[Transaction]', () => { assert.equal( tx.common.chainId(), BigInt(999), - 'should initialize Common with chain ID (unsupported) derived from v value (v with 1-parity)' + 'should initialize Common with chain ID (unsupported) derived from v value (v with 1-parity)', ) }) @@ -191,13 +191,13 @@ describe('[Transaction]', () => { assert.equal(tx.getDataGas(), BigInt(0)) tx = createLegacyTxFromBytesArray( - txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) + txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), ) assert.equal(tx.getDataGas(), BigInt(1716)) tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), - { freeze: false } + { freeze: false }, ) assert.equal(tx.getDataGas(), BigInt(1716)) }) @@ -211,7 +211,7 @@ describe('[Transaction]', () => { txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, - } + }, ) assert.equal(tx.getDataGas(), BigInt(1716)) }) @@ -222,7 +222,7 @@ describe('[Transaction]', () => { txFixtures[0].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, - } + }, ) assert.equal(tx.getDataGas(), BigInt(656)) tx.common.setHardfork(Hardfork.Istanbul) @@ -277,7 +277,7 @@ describe('[Transaction]', () => { txFixtures[3].raw.slice(0, 6).map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, - } + }, ) assert.throws( () => { @@ -285,44 +285,44 @@ describe('[Transaction]', () => { }, undefined, undefined, - 'should throw calling hash with unsigned tx' + 'should throw calling hash with unsigned tx', ) tx = createLegacyTxFromBytesArray( txFixtures[3].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, - } + }, ) assert.deepEqual( tx.hash(), - hexToBytes('0x375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa') + hexToBytes('0x375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa'), ) assert.deepEqual( tx.getHashedMessageToSign(), - hexToBytes('0x61e1ec33764304dddb55348e7883d4437426f44ab3ef65e6da1e025734c03ff0') + hexToBytes('0x61e1ec33764304dddb55348e7883d4437426f44ab3ef65e6da1e025734c03ff0'), ) assert.equal(tx.getMessageToSign().length, 6) assert.deepEqual( tx.hash(), - hexToBytes('0x375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa') + hexToBytes('0x375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa'), ) }) it('hash() -> with defined chainId', () => { const tx = createLegacyTxFromBytesArray( - txFixtures[4].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) + txFixtures[4].raw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), ) assert.equal( bytesToHex(tx.hash()), - '0x0f09dc98ea85b7872f4409131a790b91e7540953992886fc268b7ba5c96820e4' + '0x0f09dc98ea85b7872f4409131a790b91e7540953992886fc268b7ba5c96820e4', ) assert.equal( bytesToHex(tx.hash()), - '0x0f09dc98ea85b7872f4409131a790b91e7540953992886fc268b7ba5c96820e4' + '0x0f09dc98ea85b7872f4409131a790b91e7540953992886fc268b7ba5c96820e4', ) assert.equal( bytesToHex(tx.getHashedMessageToSign()), - '0xf97c73fdca079da7652dbc61a46cd5aeef804008e057be3e712c43eac389aaf0' + '0xf97c73fdca079da7652dbc61a46cd5aeef804008e057be3e712c43eac389aaf0', ) }) @@ -346,10 +346,10 @@ describe('[Transaction]', () => { '0x', ] const privateKey = hexToBytes( - '0x4646464646464646464646464646464646464646464646464646464646464646' + '0x4646464646464646464646464646464646464646464646464646464646464646', ) const pt = createLegacyTxFromBytesArray( - txRaw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)) + txRaw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), ) // Note that Vitalik's example has a very similar value denoted "signing data". @@ -357,16 +357,16 @@ describe('[Transaction]', () => { // We don't have a getter for such a value in LegacyTransaction. assert.equal( bytesToHex(pt.serialize()), - '0xec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080808080' + '0xec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080808080', ) const signedTx = pt.sign(privateKey) assert.equal( bytesToHex(signedTx.getHashedMessageToSign()), - '0xdaf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53' + '0xdaf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53', ) assert.equal( bytesToHex(signedTx.serialize()), - '0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83' + '0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83', ) }) @@ -377,7 +377,7 @@ describe('[Transaction]', () => { txData.raw.slice(0, 6).map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), { common, - } + }, ) const privKey = hexToBytes(`0x${txData.privateKey}`) @@ -386,7 +386,7 @@ describe('[Transaction]', () => { assert.equal( txSigned.getSenderAddress().toString(), '0x' + txData.sendersAddress, - "computed sender address should equal the fixture's one" + "computed sender address should equal the fixture's one", ) } }) @@ -401,17 +401,17 @@ describe('[Transaction]', () => { '0x', ] const privateKey = hexToBytes( - '0xDE3128752F183E8930D7F00A2AAA302DCB5E700B2CBA2D8CA5795660F07DEFD5' + '0xDE3128752F183E8930D7F00A2AAA302DCB5E700B2CBA2D8CA5795660F07DEFD5', ) const common = createCustomCommon({ chainId: 3 }) const tx = createLegacyTxFromBytesArray( txRaw.map((rawTxData) => hexToBytes(rawTxData as PrefixedHexString)), - { common } + { common }, ) const signedTx = tx.sign(privateKey) assert.equal( bytesToHex(signedTx.serialize()), - '0xf86c018502540be40082520894d7250824390ec5c8b71d856b5de895e271170d9d880de0b6b3a76400008029a0d3512c68099d184ccf54f44d9d6905bff303128574b663dcf10b4c726ddd8133a0628acc8f481dea593f13309dfc5f0340f83fdd40cf9fbe47f782668f6f3aec74' + '0xf86c018502540be40082520894d7250824390ec5c8b71d856b5de895e271170d9d880de0b6b3a76400008029a0d3512c68099d184ccf54f44d9d6905bff303128574b663dcf10b4c726ddd8133a0628acc8f481dea593f13309dfc5f0340f83fdd40cf9fbe47f782668f6f3aec74', ) }) @@ -426,7 +426,7 @@ describe('[Transaction]', () => { } const privateKey = hexToBytes( - '0x4646464646464646464646464646464646464646464646464646464646464646' + '0x4646464646464646464646464646464646464646464646464646464646464646', ) const common = new Common({ @@ -457,7 +457,7 @@ describe('[Transaction]', () => { assert.isTrue(signedWithoutEIP155.verifySignature()) assert.isTrue( signedWithoutEIP155.v?.toString(16) === '1c' || signedWithoutEIP155.v?.toString(16) === '1b', - "v shouldn't be EIP155 encoded" + "v shouldn't be EIP155 encoded", ) signedWithoutEIP155 = createLegacyTx(txData, { @@ -467,7 +467,7 @@ describe('[Transaction]', () => { assert.isTrue(signedWithoutEIP155.verifySignature()) assert.isTrue( signedWithoutEIP155.v?.toString(16) === '1c' || signedWithoutEIP155.v?.toString(16) === '1b', - "v shouldn't be EIP155 encoded" + "v shouldn't be EIP155 encoded", ) }) @@ -525,7 +525,7 @@ describe('[Transaction]', () => { const signedTxn = txn.sign(pkey) assert.ok( signedTxn.common.hardfork() === Hardfork.Paris, - 'signed tx common is taken from tx.common' + 'signed tx common is taken from tx.common', ) }) @@ -542,7 +542,7 @@ describe('[Transaction]', () => { value: '0x0', } const privateKey = hexToBytes( - '0x4646464646464646464646464646464646464646464646464646464646464646' + '0x4646464646464646464646464646464646464646464646464646464646464646', ) tx = createLegacyTx(txData) assert.notOk(tx.isSigned()) diff --git a/packages/tx/test/testLoader.ts b/packages/tx/test/testLoader.ts index 62bcaa6adf..eea8a394fe 100644 --- a/packages/tx/test/testLoader.ts +++ b/packages/tx/test/testLoader.ts @@ -23,7 +23,7 @@ export async function getTests( fileFilter: RegExp | string[] = /.json$/, skipPredicate: (...args: any[]) => boolean = falsePredicate, directory: string, - excludeDir: RegExp | string[] = [] + excludeDir: RegExp | string[] = [], ): Promise { const options = { match: fileFilter, @@ -41,7 +41,7 @@ export async function getTests( err: Error | undefined, content: string | Uint8Array, fileName: string, - next: Function + next: Function, ) => { if (err) { reject(err) diff --git a/packages/tx/test/transactionFactory.spec.ts b/packages/tx/test/transactionFactory.spec.ts index ddb7c6f5ea..90cdeac4ba 100644 --- a/packages/tx/test/transactionFactory.spec.ts +++ b/packages/tx/test/transactionFactory.spec.ts @@ -65,7 +65,7 @@ describe('[TransactionFactory]: Basic functions', () => { assert.equal( factoryTx.constructor.name, txType.class.name, - `should return the right type (${txType.name})` + `should return the right type (${txType.name})`, ) } }) @@ -82,7 +82,7 @@ describe('[TransactionFactory]: Basic functions', () => { }, undefined, undefined, - `should throw when trying to create typed tx when not allowed in Common (${txType.name})` + `should throw when trying to create typed tx when not allowed in Common (${txType.name})`, ) assert.throws( @@ -93,7 +93,7 @@ describe('[TransactionFactory]: Basic functions', () => { }, undefined, undefined, - `should throw when trying to create typed tx with wrong type (${txType.name})` + `should throw when trying to create typed tx with wrong type (${txType.name})`, ) } } @@ -111,19 +111,19 @@ describe('[TransactionFactory]: Basic functions', () => { assert.equal( tx.constructor.name, txType.name, - `should return the right type (${txType.name})` + `should return the right type (${txType.name})`, ) if (txType.eip2718) { assert.deepEqual( tx.serialize(), rawTx, - `round-trip serialization should match (${txType.name})` + `round-trip serialization should match (${txType.name})`, ) } else { assert.deepEqual( tx.raw(), rawTx as Uint8Array[], - `round-trip raw() creation should match (${txType.name})` + `round-trip raw() creation should match (${txType.name})`, ) } } @@ -135,14 +135,14 @@ describe('[TransactionFactory]: Basic functions', () => { assert.equal( tx.constructor.name, txType.class.name, - `should return the right type (${txType.name})` + `should return the right type (${txType.name})`, ) if (!txType.eip2718) { const tx = createTxFromTxData({}) assert.equal( tx.constructor.name, txType.class.name, - `should return the right type (${txType.name})` + `should return the right type (${txType.name})`, ) } } diff --git a/packages/tx/test/transactionRunner.spec.ts b/packages/tx/test/transactionRunner.spec.ts index ac0a458161..cade96c4a5 100644 --- a/packages/tx/test/transactionRunner.spec.ts +++ b/packages/tx/test/transactionRunner.spec.ts @@ -52,7 +52,7 @@ describe('TransactionTests', async () => { _filename: string, subDir: string, testName: string, - testData: OfficialTransactionTestData + testData: OfficialTransactionTestData, ) => { it(testName, () => { for (const forkName of forkNames) { @@ -83,7 +83,7 @@ describe('TransactionTests', async () => { } else { assert.ok( hashAndSenderAreCorrect && txIsValid, - `Transaction should be valid on ${forkName}` + `Transaction should be valid on ${forkName}`, ) } } catch (e: any) { @@ -98,6 +98,6 @@ describe('TransactionTests', async () => { }, fileFilterRegex, undefined, - 'TransactionTests' + 'TransactionTests', ) }) diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index 5edf37d877..dbf8d5136c 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -71,7 +71,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }) assert.ok( tx.common.chainId() === BigInt(5), - 'should initialize Common with chain ID provided (supported chain ID)' + 'should initialize Common with chain ID provided (supported chain ID)', ) tx = txType.create.txData({ @@ -79,7 +79,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }) assert.ok( tx.common.chainId() === BigInt(99999), - 'should initialize Common with chain ID provided (unsupported chain ID)' + 'should initialize Common with chain ID provided (unsupported chain ID)', ) const nonEIP2930Common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) @@ -89,7 +89,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - `should throw on a pre-Berlin Hardfork (EIP-2930 not activated) (${txType.name})` + `should throw on a pre-Berlin Hardfork (EIP-2930 not activated) (${txType.name})`, ) assert.throws( @@ -98,12 +98,12 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 { chainId: chainId + BigInt(1), }, - { common } + { common }, ) }, undefined, undefined, - `should reject transactions with wrong chain ID (${txType.name})` + `should reject transactions with wrong chain ID (${txType.name})`, ) assert.throws( @@ -112,12 +112,12 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 { v: 2, }, - { common } + { common }, ) }, undefined, undefined, - `should reject transactions with invalid yParity (v) values (${txType.name})` + `should reject transactions with invalid yParity (v) values (${txType.name})`, ) } }) @@ -168,7 +168,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 } catch (e: any) { assert.ok( e.message.includes('wrong tx type'), - `should throw on wrong tx type (${txType.name})` + `should throw on wrong tx type (${txType.name})`, ) } @@ -179,7 +179,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 } catch (e: any) { assert.ok( e.message.includes('must be array'), - `should throw when RLP payload not an array (${txType.name})` + `should throw when RLP payload not an array (${txType.name})`, ) } @@ -190,7 +190,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 } catch (e: any) { assert.ok( e.message.includes('values (for unsigned tx)'), - `should throw with invalid number of values (${txType.name})` + `should throw with invalid number of values (${txType.name})`, ) } } @@ -209,7 +209,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 accessList: access, chainId: Chain.Mainnet, }, - { common } + { common }, ) // Check if everything is converted @@ -229,7 +229,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 accessList: bytes, chainId: Chain.Mainnet, }, - { common } + { common }, ) const JSONRaw = txnRaw.AccessListJSON @@ -253,7 +253,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) accessList = [ @@ -271,7 +271,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) accessList = [[]] // Address does not exist @@ -282,7 +282,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) accessList = [[validAddress]] // Slots does not exist @@ -293,7 +293,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) accessList = [[validAddress, validSlot]] // Slots is not an array @@ -304,7 +304,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) accessList = [[validAddress, [], []]] // 3 items where 2 are expected @@ -315,7 +315,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - txType.name + txType.name, ) } }) @@ -329,13 +329,13 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 accessList: [[validAddress, [validSlot]]], chainId, }, - { common } + { common }, ) let signed = tx.sign(pKey) const signedAddress = signed.getSenderAddress() assert.ok( equalsBytes(signedAddress.bytes, address), - `should sign a transaction (${txType.name})` + `should sign a transaction (${txType.name})`, ) signed.verifySignature() // If this throws, test will not end. @@ -345,7 +345,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 assert.deepEqual( tx.accessList, [], - `should create and sign transactions without passing access list value (${txType.name})` + `should create and sign transactions without passing access list value (${txType.name})`, ) assert.deepEqual(signed.accessList, []) @@ -357,7 +357,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - `should throw calling hash with unsigned tx (${txType.name})` + `should throw calling hash with unsigned tx (${txType.name})`, ) assert.throws(() => { @@ -373,7 +373,7 @@ describe('[AccessListEIP2930Transaction / FeeMarketEIP1559Transaction] -> EIP-29 }, undefined, undefined, - `should throw with invalid s value (${txType.name})` + `should throw with invalid s value (${txType.name})`, ) } }) @@ -434,7 +434,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const tx = create2930AccessListTx({}, { common }) assert.ok( create2930AccessListTx(tx, { common }), - 'should initialize correctly from its own data' + 'should initialize correctly from its own data', ) const validAddress = hexToBytes(`0x${'01'.repeat(20)}`) @@ -450,12 +450,12 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { gasLimit: MAX_UINT64, gasPrice: MAX_INTEGER, }, - { common } + { common }, ) } catch (err: any) { assert.ok( err.message.includes('gasLimit * gasPrice cannot exceed MAX_INTEGER'), - 'throws when gasLimit * gasPrice exceeds MAX_INTEGER' + 'throws when gasLimit * gasPrice exceeds MAX_INTEGER', ) } }) @@ -468,12 +468,12 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const aclBytes: AccessListBytesItem = [address, storageKeys] create2930AccessListTxFromBytesArray( [bytes, bytes, bytes, bytes, bytes, bytes, bytes, [aclBytes], bytes], - {} + {}, ) }, undefined, undefined, - 'should throw with values array with length different than 8 or 11' + 'should throw with values array with length different than 8 or 11', ) it(`should return right upfront cost`, () => { @@ -484,7 +484,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { accessList: [[validAddress, [validSlot]]], chainId, }, - { common } + { common }, ) // Cost should be: // Base fee + 2*TxDataNonZero + TxDataZero + AccessListAddressCost + AccessListSlotCost @@ -502,8 +502,8 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { txDataZero + baseFee + accessListAddressCost + - accessListStorageKeyCost - ) + accessListStorageKeyCost, + ), ) // In this Tx, `to` is `undefined`, so we should charge homestead creation gas. @@ -513,7 +513,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { accessList: [[validAddress, [validSlot]]], chainId, }, - { common } + { common }, ) assert.ok( @@ -524,8 +524,8 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { creationFee + baseFee + accessListAddressCost + - accessListStorageKeyCost - ) + accessListStorageKeyCost, + ), ) // Explicitly check that even if we have duplicates in our list, we still charge for those @@ -538,12 +538,12 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { ], chainId, }, - { common } + { common }, ) assert.ok( tx.getIntrinsicGas() === - BigInt(baseFee + accessListAddressCost * 2 + accessListStorageKeyCost * 3) + BigInt(baseFee + accessListAddressCost * 2 + accessListStorageKeyCost * 3), ) }) @@ -565,7 +565,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { gasLimit: 10000000, value: 42, }, - { common } + { common }, ) assert.equal(tx.getUpfrontCost(), BigInt(10000000042)) }) @@ -578,20 +578,20 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { accessList: [[validAddress, [validSlot]]], chainId, }, - { common } + { common }, ) const expectedHash = hexToBytes( - '0x78528e2724aa359c58c13e43a7c467eb721ce8d410c2a12ee62943a3aaefb60b' + '0x78528e2724aa359c58c13e43a7c467eb721ce8d410c2a12ee62943a3aaefb60b', ) assert.deepEqual(unsignedTx.getHashedMessageToSign(), expectedHash), 'correct hashed version' const expectedSerialization = hexToBytes( - '0x01f858018080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101' + '0x01f858018080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101', ) assert.deepEqual( unsignedTx.getMessageToSign(), expectedSerialization, - 'correct serialized unhashed version' + 'correct serialized unhashed version', ) }) @@ -624,21 +624,21 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { usedCommon.setEIPs([2718, 2929, 2930]) const expectedUnsignedRaw = hexToBytes( - '0x01f86587796f6c6f76337880843b9aca008262d494df0a88b2b68c673713a8ec826003676f272e35730180f838f7940000000000000000000000000000000000001337e1a00000000000000000000000000000000000000000000000000000000000000000808080' + '0x01f86587796f6c6f76337880843b9aca008262d494df0a88b2b68c673713a8ec826003676f272e35730180f838f7940000000000000000000000000000000000001337e1a00000000000000000000000000000000000000000000000000000000000000000808080', ) const pkey = hexToBytes('0xfad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19') const expectedSigned = hexToBytes( - '0x01f8a587796f6c6f76337880843b9aca008262d494df0a88b2b68c673713a8ec826003676f272e35730180f838f7940000000000000000000000000000000000001337e1a0000000000000000000000000000000000000000000000000000000000000000080a0294ac94077b35057971e6b4b06dfdf55a6fbed819133a6c1d31e187f1bca938da00be950468ba1c25a5cb50e9f6d8aa13c8cd21f24ba909402775b262ac76d374d' + '0x01f8a587796f6c6f76337880843b9aca008262d494df0a88b2b68c673713a8ec826003676f272e35730180f838f7940000000000000000000000000000000000001337e1a0000000000000000000000000000000000000000000000000000000000000000080a0294ac94077b35057971e6b4b06dfdf55a6fbed819133a6c1d31e187f1bca938da00be950468ba1c25a5cb50e9f6d8aa13c8cd21f24ba909402775b262ac76d374d', ) const expectedHash = hexToBytes( - '0xbbd570a3c6acc9bb7da0d5c0322fe4ea2a300db80226f7df4fef39b2d6649eec' + '0xbbd570a3c6acc9bb7da0d5c0322fe4ea2a300db80226f7df4fef39b2d6649eec', ) const v = BigInt(0) const r = bytesToBigInt( - hexToBytes('0x294ac94077b35057971e6b4b06dfdf55a6fbed819133a6c1d31e187f1bca938d') + hexToBytes('0x294ac94077b35057971e6b4b06dfdf55a6fbed819133a6c1d31e187f1bca938d'), ) const s = bytesToBigInt( - hexToBytes('0x0be950468ba1c25a5cb50e9f6d8aa13c8cd21f24ba909402775b262ac76d374d') + hexToBytes('0x0be950468ba1c25a5cb50e9f6d8aa13c8cd21f24ba909402775b262ac76d374d'), ) const unsignedTx = create2930AccessListTx(txData, { common: usedCommon }) @@ -647,7 +647,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { assert.ok( equalsBytes(expectedUnsignedRaw, serializedMessageRaw), - 'serialized unsigned message correct' + 'serialized unsigned message correct', ) const signed = unsignedTx.sign(pkey) @@ -701,7 +701,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const signedTxn = txn.sign(pKey) assert.ok( signedTxn.common.hardfork() === Hardfork.Paris, - 'signed tx common is taken from tx.common' + 'signed tx common is taken from tx.common', ) }) }) diff --git a/packages/tx/tsconfig.lint.json b/packages/tx/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/tx/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/util/.eslintrc.cjs b/packages/util/.eslintrc.cjs index 80869b21ea..ed6ce7f539 100644 --- a/packages/util/.eslintrc.cjs +++ b/packages/util/.eslintrc.cjs @@ -1 +1,15 @@ -module.exports = require('../../config/eslint.cjs') +module.exports = { + extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, + overrides: [ + { + files: ['examples/**/*'], + rules: { + 'no-console': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], + } \ No newline at end of file diff --git a/packages/util/src/account.ts b/packages/util/src/account.ts index 2ade70908d..081288cba3 100644 --- a/packages/util/src/account.ts +++ b/packages/util/src/account.ts @@ -135,7 +135,7 @@ export class Account { storageRoot: Uint8Array | null = KECCAK256_RLP, codeHash: Uint8Array | null = KECCAK256_NULL, codeSize: number | null = null, - version: number | null = 0 + version: number | null = 0, ) { this._nonce = nonce this._balance = balance @@ -280,7 +280,7 @@ export function createAccount(accountData: AccountData) { nonce !== undefined ? bytesToBigInt(toBytes(nonce)) : undefined, balance !== undefined ? bytesToBigInt(toBytes(balance)) : undefined, storageRoot !== undefined ? toBytes(storageRoot) : undefined, - codeHash !== undefined ? toBytes(codeHash) : undefined + codeHash !== undefined ? toBytes(codeHash) : undefined, ) } @@ -310,7 +310,7 @@ export function createPartialAccount(partialAccountData: PartialAccountData) { storageRoot !== undefined && storageRoot !== null ? toBytes(storageRoot) : storageRoot, codeHash !== undefined && codeHash !== null ? toBytes(codeHash) : codeHash, codeSize !== undefined && codeSize !== null ? bytesToInt(toBytes(codeSize)) : codeSize, - version !== undefined && version !== null ? bytesToInt(toBytes(version)) : version + version !== undefined && version !== null ? bytesToInt(toBytes(version)) : version, ) } @@ -439,7 +439,7 @@ export const isValidAddress = function (hexAddress: string): hexAddress is Prefi */ export const toChecksumAddress = function ( hexAddress: string, - eip1191ChainId?: BigIntLike + eip1191ChainId?: BigIntLike, ): PrefixedHexString { assertIsHexString(hexAddress) const address = stripHexPrefix(hexAddress).toLowerCase() @@ -472,7 +472,7 @@ export const toChecksumAddress = function ( */ export const isValidChecksumAddress = function ( hexAddress: string, - eip1191ChainId?: BigIntLike + eip1191ChainId?: BigIntLike, ): boolean { return isValidAddress(hexAddress) && toChecksumAddress(hexAddress, eip1191ChainId) === hexAddress } @@ -505,7 +505,7 @@ export const generateAddress = function (from: Uint8Array, nonce: Uint8Array): U export const generateAddress2 = function ( from: Uint8Array, salt: Uint8Array, - initCode: Uint8Array + initCode: Uint8Array, ): Uint8Array { assertIsBytes(from) assertIsBytes(salt) diff --git a/packages/util/src/asyncEventEmitter.ts b/packages/util/src/asyncEventEmitter.ts index 7085b0a672..e5eefc1ffe 100644 --- a/packages/util/src/asyncEventEmitter.ts +++ b/packages/util/src/asyncEventEmitter.ts @@ -18,7 +18,7 @@ export interface EventMap { async function runInSeries( context: any, tasks: Array<(data: unknown, callback?: (error?: Error) => void) => void>, - data: unknown + data: unknown, ): Promise { let error: Error | undefined for await (const task of tasks) { @@ -132,7 +132,7 @@ export class AsyncEventEmitter extends EventEmitter { event: E & string, target: T[E], listener: T[E], - beforeOrAfter?: string + beforeOrAfter?: string, ) { let listeners = (this as any)._events[event] ?? [] let i diff --git a/packages/util/src/bytes.ts b/packages/util/src/bytes.ts index 8ab36fb35e..7226c5b4b5 100644 --- a/packages/util/src/bytes.ts +++ b/packages/util/src/bytes.ts @@ -125,7 +125,7 @@ export const hexToBytes = (hex: PrefixedHexString): Uint8Array => { const unprefixedHex = hex.slice(2) return _unprefixedHexToBytes( - unprefixedHex.length % 2 === 0 ? unprefixedHex : padToEven(unprefixedHex) + unprefixedHex.length % 2 === 0 ? unprefixedHex : padToEven(unprefixedHex), ) } @@ -226,7 +226,7 @@ export const setLengthRight = (msg: Uint8Array, length: number): Uint8Array => { * @return {Uint8Array|number[]|string} */ const stripZeros = ( - a: T + a: T, ): T => { let first = a[0] while (a.length > 0 && first.toString() === '0') { @@ -296,7 +296,7 @@ export const toBytes = (v: ToBytesInputTypes): Uint8Array => { if (typeof v === 'string') { if (!isHexString(v)) { throw new Error( - `Cannot convert string to Uint8Array. toBytes only supports 0x-prefixed hex strings and this string was given: ${v}` + `Cannot convert string to Uint8Array. toBytes only supports 0x-prefixed hex strings and this string was given: ${v}`, ) } return hexToBytes(v) diff --git a/packages/util/src/constants.ts b/packages/util/src/constants.ts index d1c8110465..b1587c9bc7 100644 --- a/packages/util/src/constants.ts +++ b/packages/util/src/constants.ts @@ -11,7 +11,7 @@ export const MAX_UINT64 = BigInt('0xffffffffffffffff') * The max integer that the evm can handle (2^256-1) */ export const MAX_INTEGER = BigInt( - '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', ) /** @@ -20,7 +20,7 @@ export const MAX_INTEGER = BigInt( * We use literal value instead of calculated value for compatibility issue. */ export const MAX_INTEGER_BIGINT = BigInt( - '115792089237316195423570985008687907853269984665640564039457584007913129639935' + '115792089237316195423570985008687907853269984665640564039457584007913129639935', ) export const SECP256K1_ORDER = secp256k1.CURVE.n @@ -30,7 +30,7 @@ export const SECP256K1_ORDER_DIV_2 = secp256k1.CURVE.n / BigInt(2) * 2^256 */ export const TWO_POW256 = BigInt( - '0x10000000000000000000000000000000000000000000000000000000000000000' + '0x10000000000000000000000000000000000000000000000000000000000000000', ) /** diff --git a/packages/util/src/db.ts b/packages/util/src/db.ts index 9bdfabcd90..cc0e8a2a21 100644 --- a/packages/util/src/db.ts +++ b/packages/util/src/db.ts @@ -3,7 +3,7 @@ export type DBObject = { } export type BatchDBOp< TKey extends Uint8Array | string | number = Uint8Array, - TValue extends Uint8Array | string | DBObject = Uint8Array + TValue extends Uint8Array | string | DBObject = Uint8Array, > = PutBatch | DelBatch export enum KeyEncoding { @@ -24,7 +24,7 @@ export type EncodingOpts = { } export interface PutBatch< TKey extends Uint8Array | string | number = Uint8Array, - TValue extends Uint8Array | string | DBObject = Uint8Array + TValue extends Uint8Array | string | DBObject = Uint8Array, > { type: 'put' key: TKey @@ -40,7 +40,7 @@ export interface DelBatch { /** * Retrieves a raw value from db. diff --git a/packages/util/src/genesis.ts b/packages/util/src/genesis.ts index 8ad5426d6f..4cfebc2f70 100644 --- a/packages/util/src/genesis.ts +++ b/packages/util/src/genesis.ts @@ -9,7 +9,7 @@ export type AccountState = [ balance: PrefixedHexString, code: PrefixedHexString, storage: Array, - nonce: PrefixedHexString + nonce: PrefixedHexString, ] /** diff --git a/packages/util/src/internal.ts b/packages/util/src/internal.ts index 6333fe40a5..4af836eaa4 100644 --- a/packages/util/src/internal.ts +++ b/packages/util/src/internal.ts @@ -93,16 +93,16 @@ export function getBinarySize(str: string) { export function arrayContainsArray( superset: unknown[], subset: unknown[], - some?: boolean + some?: boolean, ): boolean { if (Array.isArray(superset) !== true) { throw new Error( - `[arrayContainsArray] method requires input 'superset' to be an array, got type '${typeof superset}'` + `[arrayContainsArray] method requires input 'superset' to be an array, got type '${typeof superset}'`, ) } if (Array.isArray(subset) !== true) { throw new Error( - `[arrayContainsArray] method requires input 'subset' to be an array, got type '${typeof subset}'` + `[arrayContainsArray] method requires input 'subset' to be an array, got type '${typeof subset}'`, ) } @@ -179,7 +179,7 @@ export function getKeys(params: Record[], key: string, allowEmpt } if (typeof key !== 'string') { throw new Error( - `[getKeys] method expects input 'key' to be type 'string', got ${typeof params}` + `[getKeys] method expects input 'key' to be type 'string', got ${typeof params}`, ) } diff --git a/packages/util/src/kzg.ts b/packages/util/src/kzg.ts index 4930b161ca..256d2e35a4 100644 --- a/packages/util/src/kzg.ts +++ b/packages/util/src/kzg.ts @@ -14,12 +14,12 @@ export interface Kzg { polynomialKzg: Uint8Array, z: Uint8Array, y: Uint8Array, - kzgProof: Uint8Array + kzgProof: Uint8Array, ): boolean verifyBlobKzgProofBatch( blobs: Uint8Array[], expectedKzgCommitments: Uint8Array[], - kzgProofs: Uint8Array[] + kzgProofs: Uint8Array[], ): boolean } diff --git a/packages/util/src/mapDB.ts b/packages/util/src/mapDB.ts index 4df7954fdb..88957cb19a 100644 --- a/packages/util/src/mapDB.ts +++ b/packages/util/src/mapDB.ts @@ -4,7 +4,7 @@ import type { BatchDBOp, DB, DBObject } from './db.js' export class MapDB< TKey extends Uint8Array | string | number, - TValue extends Uint8Array | string | DBObject + TValue extends Uint8Array | string | DBObject, > implements DB { _database: Map diff --git a/packages/util/src/provider.ts b/packages/util/src/provider.ts index bc8dfa009b..28bc74a766 100644 --- a/packages/util/src/provider.ts +++ b/packages/util/src/provider.ts @@ -47,8 +47,8 @@ export const fetchFromProvider = async (url: string, params: rpcParams) => { }), }, null, - 2 - )}` + 2, + )}`, ) } const json = await res.json() diff --git a/packages/util/src/requests.ts b/packages/util/src/requests.ts index 576ae52856..3490e06977 100644 --- a/packages/util/src/requests.ts +++ b/packages/util/src/requests.ts @@ -96,7 +96,7 @@ export class DepositRequest extends CLRequest { public readonly withdrawalCredentials: Uint8Array, public readonly amount: bigint, public readonly signature: Uint8Array, - public readonly index: bigint + public readonly index: bigint, ) { super(CLRequestType.Deposit) } @@ -124,7 +124,13 @@ export class DepositRequest extends CLRequest { return concatBytes( Uint8Array.from([this.type]), - RLP.encode([this.pubkey, this.withdrawalCredentials, amountBytes, this.signature, indexBytes]) + RLP.encode([ + this.pubkey, + this.withdrawalCredentials, + amountBytes, + this.signature, + indexBytes, + ]), ) } @@ -140,7 +146,7 @@ export class DepositRequest extends CLRequest { public static deserialize(bytes: Uint8Array): DepositRequest { const [pubkey, withdrawalCredentials, amount, signature, index] = RLP.decode( - bytes.slice(1) + bytes.slice(1), ) as [Uint8Array, Uint8Array, Uint8Array, Uint8Array, Uint8Array] return this.fromRequestData({ pubkey, @@ -156,7 +162,7 @@ export class WithdrawalRequest extends CLRequest { constructor( public readonly sourceAddress: Uint8Array, public readonly validatorPubkey: Uint8Array, - public readonly amount: bigint + public readonly amount: bigint, ) { super(CLRequestType.Withdrawal) } @@ -180,7 +186,7 @@ export class WithdrawalRequest extends CLRequest { return concatBytes( Uint8Array.from([this.type]), - RLP.encode([this.sourceAddress, this.validatorPubkey, amountBytes]) + RLP.encode([this.sourceAddress, this.validatorPubkey, amountBytes]), ) } @@ -196,7 +202,7 @@ export class WithdrawalRequest extends CLRequest { const [sourceAddress, validatorPubkey, amount] = RLP.decode(bytes.slice(1)) as [ Uint8Array, Uint8Array, - Uint8Array + Uint8Array, ] return this.fromRequestData({ sourceAddress, @@ -210,7 +216,7 @@ export class ConsolidationRequest extends CLRequest constructor( public readonly sourceAddress: Uint8Array, public readonly sourcePubkey: Uint8Array, - public readonly targetPubkey: Uint8Array + public readonly targetPubkey: Uint8Array, ) { super(CLRequestType.Consolidation) } @@ -232,7 +238,7 @@ export class ConsolidationRequest extends CLRequest serialize() { return concatBytes( Uint8Array.from([this.type]), - RLP.encode([this.sourceAddress, this.sourcePubkey, this.targetPubkey]) + RLP.encode([this.sourceAddress, this.sourcePubkey, this.targetPubkey]), ) } @@ -248,7 +254,7 @@ export class ConsolidationRequest extends CLRequest const [sourceAddress, sourcePubkey, targetPubkey] = RLP.decode(bytes.slice(1)) as [ Uint8Array, Uint8Array, - Uint8Array + Uint8Array, ] return this.fromRequestData({ sourceAddress, diff --git a/packages/util/src/signature.ts b/packages/util/src/signature.ts index 9dd8466836..03d43da741 100644 --- a/packages/util/src/signature.ts +++ b/packages/util/src/signature.ts @@ -37,7 +37,7 @@ export interface ECDSASignature { export function ecsign( msgHash: Uint8Array, privateKey: Uint8Array, - chainId?: bigint + chainId?: bigint, ): ECDSASignature { const sig = secp256k1.sign(msgHash, privateKey) const buf = sig.toCompactRawBytes() @@ -75,7 +75,7 @@ export const ecrecover = function ( v: bigint, r: Uint8Array, s: Uint8Array, - chainId?: bigint + chainId?: bigint, ): Uint8Array { const signature = concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32)) const recovery = calculateSigRecovery(v, chainId) @@ -97,7 +97,7 @@ export const toRpcSig = function ( v: bigint, r: Uint8Array, s: Uint8Array, - chainId?: bigint + chainId?: bigint, ): string { const recovery = calculateSigRecovery(v, chainId) if (!isValidSigRecovery(recovery)) { @@ -118,7 +118,7 @@ export const toCompactSig = function ( v: bigint, r: Uint8Array, s: Uint8Array, - chainId?: bigint + chainId?: bigint, ): string { const recovery = calculateSigRecovery(v, chainId) if (!isValidSigRecovery(recovery)) { @@ -183,7 +183,7 @@ export const isValidSignature = function ( r: Uint8Array, s: Uint8Array, homesteadOrLater: boolean = true, - chainId?: bigint + chainId?: bigint, ): boolean { if (r.length !== 32 || s.length !== 32) { return false diff --git a/packages/util/src/types.ts b/packages/util/src/types.ts index f81a7ed70e..2cc0df8f9c 100644 --- a/packages/util/src/types.ts +++ b/packages/util/src/types.ts @@ -79,11 +79,11 @@ export function toType(input: null, outputType: T): null export function toType(input: undefined, outputType: T): undefined export function toType( input: ToBytesInputTypes, - outputType: T + outputType: T, ): TypeOutputReturnType[T] export function toType( input: ToBytesInputTypes, - outputType: T + outputType: T, ): TypeOutputReturnType[T] | undefined | null { if (input === null) { return null @@ -96,7 +96,7 @@ export function toType( throw new Error(`A string must be provided with a 0x-prefix, given: ${input}`) } else if (typeof input === 'number' && !Number.isSafeInteger(input)) { throw new Error( - 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)' + 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)', ) } @@ -111,7 +111,7 @@ export function toType( const bigInt = bytesToBigInt(output) if (bigInt > BigInt(Number.MAX_SAFE_INTEGER)) { throw new Error( - 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative output type)' + 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative output type)', ) } return Number(bigInt) as TypeOutputReturnType[T] diff --git a/packages/util/src/units.ts b/packages/util/src/units.ts index dfbca2d2de..5465baf5b1 100644 --- a/packages/util/src/units.ts +++ b/packages/util/src/units.ts @@ -5,7 +5,7 @@ export const GWEI_TO_WEI = BigInt(1000000000) export function formatBigDecimal( numerator: bigint, denominator: bigint, - maxDecimalFactor: bigint + maxDecimalFactor: bigint, ): string { if (denominator === BIGINT_0) { denominator = BIGINT_1 diff --git a/packages/util/src/verkle.ts b/packages/util/src/verkle.ts index 959559f701..7f6e2dc3cf 100644 --- a/packages/util/src/verkle.ts +++ b/packages/util/src/verkle.ts @@ -26,7 +26,7 @@ export interface VerkleCrypto { commitment: Uint8Array, commitmentIndex: number, oldScalarValue: Uint8Array, - newScalarValue: Uint8Array + newScalarValue: Uint8Array, ) => Uint8Array // Commitment zeroCommitment: Uint8Array verifyExecutionWitnessPreState: (prestateRoot: string, execution_witness_json: string) => boolean @@ -45,7 +45,7 @@ export interface VerkleCrypto { export function getVerkleStem( ffi: VerkleCrypto, address: Address, - treeIndex: number | bigint = 0 + treeIndex: number | bigint = 0, ): Uint8Array { const address32 = setLengthLeft(address.toBytes(), 32) @@ -71,11 +71,11 @@ export function getVerkleStem( export function verifyVerkleProof( ffi: VerkleCrypto, prestateRoot: Uint8Array, - executionWitness: VerkleExecutionWitness + executionWitness: VerkleExecutionWitness, ): boolean { return ffi.verifyExecutionWitnessPreState( bytesToHex(prestateRoot), - JSON.stringify(executionWitness) + JSON.stringify(executionWitness), ) } @@ -190,7 +190,7 @@ export function getVerkleTreeIndicesForCodeChunk(chunkId: number) { export const getVerkleTreeKeyForCodeChunk = async ( address: Address, chunkId: number, - verkleCrypto: VerkleCrypto + verkleCrypto: VerkleCrypto, ) => { const { treeIndex, subIndex } = getVerkleTreeIndicesForCodeChunk(chunkId) return concatBytes(getVerkleStem(verkleCrypto, address, treeIndex), toBytes(subIndex)) @@ -209,7 +209,7 @@ export const chunkifyCode = (code: Uint8Array) => { export const getVerkleTreeKeyForStorageSlot = async ( address: Address, storageKey: bigint, - verkleCrypto: VerkleCrypto + verkleCrypto: VerkleCrypto, ) => { const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(storageKey) diff --git a/packages/util/src/withdrawal.ts b/packages/util/src/withdrawal.ts index 1724aef448..d8f2a133e7 100644 --- a/packages/util/src/withdrawal.ts +++ b/packages/util/src/withdrawal.ts @@ -45,7 +45,7 @@ export class Withdrawal { /** * withdrawal amount in Gwei to match the CL repesentation and eventually ssz withdrawalsRoot */ - public readonly amount: bigint + public readonly amount: bigint, ) {} public static fromWithdrawalData(withdrawalData: WithdrawalData) { diff --git a/packages/util/test/account.spec.ts b/packages/util/test/account.spec.ts index b7a37eb53d..b9ef96541d 100644 --- a/packages/util/test/account.spec.ts +++ b/packages/util/test/account.spec.ts @@ -48,12 +48,12 @@ describe('Account', () => { assert.equal( bytesToHex(account.storageRoot), '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - 'should have storageRoot equal to KECCAK256_RLP' + 'should have storageRoot equal to KECCAK256_RLP', ) assert.equal( bytesToHex(account.codeHash), '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', - 'should have codeHash equal to KECCAK256_NULL' + 'should have codeHash equal to KECCAK256_NULL', ) }) @@ -71,12 +71,12 @@ describe('Account', () => { assert.equal( bytesToHex(account.storageRoot), '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - 'should have correct storageRoot' + 'should have correct storageRoot', ) assert.equal( bytesToHex(account.codeHash), '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', - 'should have correct codeHash' + 'should have correct codeHash', ) }) @@ -93,18 +93,18 @@ describe('Account', () => { assert.equal( bytesToHex(account.storageRoot), '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - 'should have correct storageRoot' + 'should have correct storageRoot', ) assert.equal( bytesToHex(account.codeHash), '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', - 'should have correct codeHash' + 'should have correct codeHash', ) }) it('from RLP data', () => { const accountRlp = hexToBytes( - '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) const account = createAccountFromRLP(accountRlp) assert.equal(account.nonce, BigInt(2), 'should have correct nonce') @@ -112,12 +112,12 @@ describe('Account', () => { assert.equal( bytesToHex(account.storageRoot), '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - 'should have correct storageRoot' + 'should have correct storageRoot', ) assert.equal( bytesToHex(account.codeHash), '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', - 'should have correct codeHash' + 'should have correct codeHash', ) }) @@ -136,7 +136,7 @@ describe('Account', () => { it('isContract', () => { const accountRlp = hexToBytes( - '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xf84602820384a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) let account = createAccountFromRLP(accountRlp) assert.notOk(account.isContract(), 'should return false for a non-contract account') @@ -172,7 +172,7 @@ describe('Account', () => { }, undefined, undefined, - 'should only accept length 32 buffer for storageRoot' + 'should only accept length 32 buffer for storageRoot', ) assert.throws( @@ -181,7 +181,7 @@ describe('Account', () => { }, undefined, undefined, - 'should only accept length 32 buffer for codeHash' + 'should only accept length 32 buffer for codeHash', ) const data = { balance: BigInt(5) } @@ -191,7 +191,7 @@ describe('Account', () => { }, undefined, undefined, - 'should only accept an array in fromRlpSerializedAccount' + 'should only accept an array in fromRlpSerializedAccount', ) assert.throws( @@ -200,7 +200,7 @@ describe('Account', () => { }, undefined, undefined, - 'should not accept nonce less than 0' + 'should not accept nonce less than 0', ) assert.throws( @@ -209,7 +209,7 @@ describe('Account', () => { }, undefined, undefined, - 'should not accept balance less than 0' + 'should not accept balance less than 0', ) }) }) @@ -223,66 +223,66 @@ describe('Utility Functions', () => { assert.notOk( isValidPrivate( hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' - ) + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', + ), ), - 'should fail on too big input' + 'should fail on too big input', ) assert.notOk( isValidPrivate(('WRONG_INPUT_TYPE') as Uint8Array), - 'should fail on wrong input type' + 'should fail on wrong input type', ) assert.notOk( isValidPrivate( - hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000000') + hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), ), - 'should fail on invalid curve (zero)' + 'should fail on invalid curve (zero)', ) assert.notOk( isValidPrivate(hexToBytes(`0x${SECP256K1_N.toString(16)}`)), - 'should fail on invalid curve (== N)' + 'should fail on invalid curve (== N)', ) assert.notOk( isValidPrivate(hexToBytes(`0x${(SECP256K1_N + BigInt(1)).toString(16)}`)), - 'should fail on invalid curve (>= N)' + 'should fail on invalid curve (>= N)', ) assert.ok( isValidPrivate(hexToBytes(`0x${(SECP256K1_N - BigInt(1)).toString(16)}`)), - 'should work otherwise (< N)' + 'should work otherwise (< N)', ) }) it('isValidPublic', () => { let pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744', ) assert.notOk(isValidPublic(pubKey), 'should fail on too short input') pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d00' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d00', ) assert.notOk(isValidPublic(pubKey), 'should fail on too big input') pubKey = hexToBytes( - '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.notOk(isValidPublic(pubKey), 'should fail on SEC1 key') pubKey = hexToBytes( - '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.ok( isValidPublic(pubKey, true), - "shouldn't fail on SEC1 key wt.testh sant.testize enabled" + "shouldn't fail on SEC1 key wt.testh sant.testize enabled", ) pubKey = hexToBytes( - '0x023a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x023a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.notOk(isValidPublic(pubKey), 'should fail wt.testh an invalid SEC1 public key') @@ -290,28 +290,28 @@ describe('Utility Functions', () => { assert.notOk(isValidPublic(pubKey), 'should fail an invalid 33-byte public key') pubKey = hexToBytes( - '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000001' + '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000001', ) assert.notOk(isValidPublic(pubKey), 'should fail an invalid 64-byte public key') pubKey = hexToBytes( - '0x04fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000001' + '0x04fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000000000000000000000000000000000000000000000000000000000000001', ) assert.notOk(isValidPublic(pubKey, true), 'should fail an invalid 65-byte public key') pubKey = hexToBytes('0x033a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a') assert.ok( isValidPublic(pubKey, true), - 'should work wt.testh compressed keys wt.testh sant.testize enabled' + 'should work wt.testh compressed keys wt.testh sant.testize enabled', ) pubKey = hexToBytes( - '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.ok(isValidPublic(pubKey, true), 'should work wt.testh sant.testize enabled') pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.ok(isValidPublic(pubKey), 'should work otherwise') @@ -322,7 +322,7 @@ describe('Utility Functions', () => { } catch (err: any) { assert.ok( err.message.includes('This method only supports Uint8Array'), - 'should throw if input is not Uint8Array' + 'should throw if input is not Uint8Array', ) } }) @@ -335,34 +335,34 @@ describe('Utility Functions', () => { bytesToHex( importPublic( hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' - ) - ) + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', + ), + ), ), pubKey, - 'should work wt.testh an Ethereum public key' + 'should work wt.testh an Ethereum public key', ) assert.equal( bytesToHex( importPublic( hexToBytes( - '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' - ) - ) + '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', + ), + ), ), pubKey, - 'should work wt.testh uncompressed SEC1 keys' + 'should work wt.testh uncompressed SEC1 keys', ) assert.equal( bytesToHex( importPublic( - hexToBytes('0x033a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a') - ) + hexToBytes('0x033a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a'), + ), ), pubKey, - 'should work wt.testh compressed SEC1 keys' + 'should work wt.testh compressed SEC1 keys', ) assert.throws( @@ -371,27 +371,27 @@ describe('Utility Functions', () => { }, undefined, undefined, - 'should throw if input is not Uint8Array' + 'should throw if input is not Uint8Array', ) }) it('publicToAddress', () => { let pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) let address = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' let r = publicToAddress(pubKey) assert.equal(bytesToHex(r), address, 'should produce an address given a public key') pubKey = hexToBytes( - '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x043a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) address = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' r = publicToAddress(pubKey, true) assert.equal(bytesToHex(r), address, 'should produce an address given a SEC1 public key') pubKey = hexToBytes( - '0x023a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x023a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) assert.throws( function () { @@ -399,11 +399,11 @@ describe('Utility Functions', () => { }, undefined, undefined, - "shouldn't produce an address given an invalid SEC1 public key" + "shouldn't produce an address given an invalid SEC1 public key", ) pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744', ) assert.throws( function () { @@ -411,7 +411,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - "shouldn't produce an address given an invalid public key" + "shouldn't produce an address given an invalid public key", ) pubKey = @@ -422,7 +422,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - 'should throw if input is not a Uint8Array' + 'should throw if input is not a Uint8Array', ) }) @@ -430,7 +430,7 @@ describe('Utility Functions', () => { const pubKey = '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' let privateKey = hexToBytes( - '0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c5f' + '0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c5f', ) const r = privateToPublic(privateKey) assert.equal(bytesToHex(r), pubKey, 'should produce a public key given a private key') @@ -442,7 +442,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - "shouldn't produce a public key given an invalid private key" + "shouldn't produce a public key given an invalid private key", ) privateKey = hexToBytes('0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c') @@ -452,7 +452,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - "shouldn't produce a public key given an invalid private key" + "shouldn't produce a public key given an invalid private key", ) privateKey = '0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c5f' as any @@ -461,7 +461,7 @@ describe('Utility Functions', () => { } catch (err: any) { assert.ok( err.message.includes('This method only supports Uint8Array'), - 'should throw if private key is not Uint8Array' + 'should throw if private key is not Uint8Array', ) assert.ok(err.message.includes(privateKey), 'should throw if private key is not Uint8Array') } @@ -471,7 +471,7 @@ describe('Utility Functions', () => { const address = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' // Our private key const privateKey = hexToBytes( - '0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c5f' + '0xea54bdc52d163f88c93ab0615782cf718a2efb9e51a7989aab1b08067e9c1c5f', ) const r = privateToAddress(privateKey) assert.equal(bytesToHex(r), address, 'should produce an address given a private key') @@ -480,12 +480,12 @@ describe('Utility Functions', () => { it('generateAddress', () => { const addr = generateAddress( utf8ToBytes('990ccf8a0de58091c028d6ff76bb235ee67c1c39'), - toBytes(14) + toBytes(14), ) assert.equal( bytesToHex(addr), '0x936a4295d8d74e310c0c95f0a63e53737b998d12', - 'should produce an address given a public key' + 'should produce an address given a public key', ) }) @@ -494,7 +494,7 @@ describe('Utility Functions', () => { assert.equal( bytesToHex(addr), '0xd658a4b8247c14868f3c512fa5cbb6e458e4a989', - 'should produce an address given a public key' + 'should produce an address given a public key', ) }) @@ -503,7 +503,7 @@ describe('Utility Functions', () => { assert.equal( bytesToHex(addr), '0xbfa69ba91385206bfdd2d8b9c1a5d6c10097a85b', - 'should produce an address given a public key' + 'should produce an address given a public key', ) }) @@ -512,24 +512,24 @@ describe('Utility Functions', () => { function () { generateAddress( ('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') as Uint8Array, - toBytes(0) + toBytes(0), ) }, undefined, undefined, - 'should throw if address is not Uint8Array' + 'should throw if address is not Uint8Array', ) assert.throws( function () { generateAddress( toBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), - (0) as Uint8Array + (0) as Uint8Array, ) }, undefined, undefined, - 'should throw if nonce is not Uint8Array' + 'should throw if nonce is not Uint8Array', ) }) @@ -539,7 +539,7 @@ describe('Utility Functions', () => { const addr = generateAddress2( hexToBytes(address as PrefixedHexString), hexToBytes(salt as PrefixedHexString), - hexToBytes(initCode as PrefixedHexString) + hexToBytes(initCode as PrefixedHexString), ) assert.equal(bytesToHex(addr), result, `${comment}: should generate the addresses provided`) } @@ -553,12 +553,12 @@ describe('Utility Functions', () => { generateAddress2( (address) as Uint8Array, hexToBytes(salt as PrefixedHexString), - hexToBytes(initCode as PrefixedHexString) + hexToBytes(initCode as PrefixedHexString), ) }, undefined, undefined, - 'should throw if address is not Uint8Array' + 'should throw if address is not Uint8Array', ) assert.throws( @@ -566,12 +566,12 @@ describe('Utility Functions', () => { generateAddress2( hexToBytes(address as PrefixedHexString), (salt) as Uint8Array, - hexToBytes(initCode as PrefixedHexString) + hexToBytes(initCode as PrefixedHexString), ) }, undefined, undefined, - 'should throw if salt is not Uint8Array' + 'should throw if salt is not Uint8Array', ) assert.throws( @@ -579,12 +579,12 @@ describe('Utility Functions', () => { generateAddress2( hexToBytes(address as PrefixedHexString), hexToBytes(salt as PrefixedHexString), - (initCode) as Uint8Array + (initCode) as Uint8Array, ) }, undefined, undefined, - 'should throw if initCode is not Uint8Array' + 'should throw if initCode is not Uint8Array', ) }) @@ -657,17 +657,17 @@ describe('Utility Functions', () => { assert.equal( toChecksumAddress( addr.toLowerCase(), - hexToBytes(`0x${padToEven(chainId)}`) + hexToBytes(`0x${padToEven(chainId)}`), ).toLowerCase(), - addr.toLowerCase() + addr.toLowerCase(), ) assert.equal( toChecksumAddress(addr.toLowerCase(), BigInt(chainId)).toLowerCase(), - addr.toLowerCase() + addr.toLowerCase(), ) assert.equal( toChecksumAddress(addr.toLowerCase(), `0x${padToEven(chainId)}`).toLowerCase(), - addr.toLowerCase() + addr.toLowerCase(), ) } } @@ -688,7 +688,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - 'Should throw when the address is not hex-prefixed' + 'Should throw when the address is not hex-prefixed', ) assert.throws( @@ -697,7 +697,7 @@ describe('Utility Functions', () => { }, undefined, undefined, - 'Should throw when the chainId is not hex-prefixed' + 'Should throw when the chainId is not hex-prefixed', ) }) }) @@ -718,7 +718,7 @@ describe('Utility Functions', () => { assert.ok(isValidChecksumAddress(addr, intToBytes(parseInt(chainId)))) assert.ok(isValidChecksumAddress(addr, BigInt(chainId))) assert.ok( - isValidChecksumAddress(addr, `0x${padToEven(intToHex(parseInt(chainId)).slice(2))}`) + isValidChecksumAddress(addr, `0x${padToEven(intToHex(parseInt(chainId)).slice(2))}`), ) } } @@ -773,12 +773,12 @@ describe('Utility Functions', () => { assert.equal( JSON.stringify(result[2]), JSON.stringify(KECCAK256_RLP), - 'Empty storageRoot should be changed to hash of RLP of null' + 'Empty storageRoot should be changed to hash of RLP of null', ) assert.equal( JSON.stringify(result[3]), JSON.stringify(KECCAK256_NULL), - 'Empty codeRoot should be changed to hash of RLP of null' + 'Empty codeRoot should be changed to hash of RLP of null', ) }) diff --git a/packages/util/test/address.spec.ts b/packages/util/test/address.spec.ts index c0fc0b0e76..05e57fa3e2 100644 --- a/packages/util/test/address.spec.ts +++ b/packages/util/test/address.spec.ts @@ -38,7 +38,7 @@ describe('Address', () => { it('should instantiate from public key', () => { const pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' const addr = Address.fromPublicKey(pubKey) @@ -47,7 +47,7 @@ describe('Address', () => { it('should fail to instantiate from invalid public key', () => { const pubKey = hexToBytes( - '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744' + '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744', ) assert.throws(() => Address.fromPublicKey(pubKey)) }) @@ -75,7 +75,7 @@ describe('Address', () => { const nonPrecompile = Address.fromString('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') assert.isFalse( nonPrecompile.isPrecompileOrSystemAddress(), - 'should detect non-precompile address' + 'should detect non-precompile address', ) }) @@ -86,7 +86,7 @@ describe('Address', () => { const addr = Address.generate2( from, hexToBytes(salt as PrefixedHexString), - hexToBytes(initCode as PrefixedHexString) + hexToBytes(initCode as PrefixedHexString), ) assert.equal(addr.toString(), result) } diff --git a/packages/util/test/bytes.spec.ts b/packages/util/test/bytes.spec.ts index 3d6954b2b6..f08ce15ea3 100644 --- a/packages/util/test/bytes.spec.ts +++ b/packages/util/test/bytes.spec.ts @@ -242,7 +242,7 @@ describe('toBytes', () => { return Uint8Array.from([1]) }, }), - Uint8Array.from([1]) + Uint8Array.from([1]), ) }) it('should fail', () => { @@ -287,7 +287,7 @@ describe('intToBytes', () => { () => intToBytes(Number.MAX_SAFE_INTEGER + 1), undefined, undefined, - 'throws on unsafe integers' + 'throws on unsafe integers', ) }) @@ -316,7 +316,7 @@ describe('intToHex', () => { () => intToHex(Number.MAX_SAFE_INTEGER + 1), undefined, undefined, - 'throws on unsafe integers' + 'throws on unsafe integers', ) }) it('should pass on correct input', () => { @@ -349,19 +349,19 @@ describe('validateNoLeadingZeroes', () => { it('should pass on correct input', () => { assert.doesNotThrow( () => validateNoLeadingZeroes(noLeadingZeroes), - 'does not throw when no leading zeroes' + 'does not throw when no leading zeroes', ) assert.doesNotThrow( () => validateNoLeadingZeroes(emptyBuffer), - 'does not throw with empty buffer' + 'does not throw with empty buffer', ) assert.doesNotThrow( () => validateNoLeadingZeroes(undefinedValue), - 'does not throw when undefined passed in' + 'does not throw when undefined passed in', ) assert.doesNotThrow( () => validateNoLeadingZeroes(noleadingZeroBytes), - 'does not throw when value has leading zero bytes' + 'does not throw when value has leading zero bytes', ) }) @@ -370,13 +370,13 @@ describe('validateNoLeadingZeroes', () => { () => validateNoLeadingZeroes(leadingZeroBytes), undefined, undefined, - 'throws when value has leading zero bytes' + 'throws when value has leading zero bytes', ) assert.throws( () => validateNoLeadingZeroes(onlyZeroes), undefined, undefined, - 'throws when value has only zeroes' + 'throws when value has only zeroes', ) }) }) diff --git a/packages/util/test/constants.spec.ts b/packages/util/test/constants.spec.ts index dc2c9f758e..8b6e56f969 100644 --- a/packages/util/test/constants.spec.ts +++ b/packages/util/test/constants.spec.ts @@ -16,47 +16,47 @@ describe('constants', () => { it('should match constants', () => { assert.equal( MAX_INTEGER.toString(16), - 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', ) assert.equal( TWO_POW256.toString(16), - '10000000000000000000000000000000000000000000000000000000000000000' + '10000000000000000000000000000000000000000000000000000000000000000', ) assert.equal( TWO_POW256.toString(16), - '10000000000000000000000000000000000000000000000000000000000000000' + '10000000000000000000000000000000000000000000000000000000000000000', ) assert.equal( KECCAK256_NULL_S, - '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) assert.equal( bytesToHex(KECCAK256_NULL), - '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470', ) assert.equal( KECCAK256_RLP_ARRAY_S, - '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347' + '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', ) assert.equal( bytesToHex(KECCAK256_RLP_ARRAY), - '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347' + '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', ) assert.equal( KECCAK256_RLP_S, - '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', ) assert.equal( bytesToHex(KECCAK256_RLP), - '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', ) }) }) diff --git a/packages/util/test/genesis.spec.ts b/packages/util/test/genesis.spec.ts index 053a998f0e..43f89947a0 100644 --- a/packages/util/test/genesis.spec.ts +++ b/packages/util/test/genesis.spec.ts @@ -12,10 +12,10 @@ describe('[Util/genesis]', () => { assert.equal( genesisState['0x4242424242424242424242424242424242424242'][1].includes( // sample data check - '0x60806040526004361061003' + '0x60806040526004361061003', ), true, - 'should have deposit contract' + 'should have deposit contract', ) }) }) diff --git a/packages/util/test/internal.spec.ts b/packages/util/test/internal.spec.ts index 29f71ef84a..c8c94faf49 100644 --- a/packages/util/test/internal.spec.ts +++ b/packages/util/test/internal.spec.ts @@ -51,9 +51,9 @@ describe('internal', () => { { a: '1', b: '2' }, { a: '3', b: '4' }, ], - 'a' + 'a', ), - ['1', '3'] + ['1', '3'], ) assert.deepEqual( getKeys( @@ -62,9 +62,9 @@ describe('internal', () => { { a: '3', b: '4' }, ], 'a', - true + true, ), - ['', '3'] + ['', '3'], ) }) diff --git a/packages/util/test/provider.spec.ts b/packages/util/test/provider.spec.ts index f8a40b5b7a..bd20df314a 100644 --- a/packages/util/test/provider.spec.ts +++ b/packages/util/test/provider.spec.ts @@ -18,13 +18,13 @@ describe('getProvider', () => { assert.equal( getProvider(fakeEthersProvider), fakeEthersProvider._getConnection().url, - 'returned correct provider url string' + 'returned correct provider url string', ) assert.throws( () => getProvider(1), 'Must provide valid provider URL or Web3Provider', undefined, - 'throws correct error' + 'throws correct error', ) }) }) diff --git a/packages/util/test/requests.spec.ts b/packages/util/test/requests.spec.ts index c2f51e7f47..96b4a49f57 100644 --- a/packages/util/test/requests.spec.ts +++ b/packages/util/test/requests.spec.ts @@ -49,7 +49,7 @@ describe('Requests', () => { for (const [requestName, requestData, requestType, RequestInstanceType] of testCases) { it(`${requestName}`, () => { const requestObject = RequestInstanceType.fromRequestData( - requestData + requestData, ) as CLRequest const requestJSON = requestObject.toJSON() const serialized = requestObject.serialize() diff --git a/packages/util/test/signature.spec.ts b/packages/util/test/signature.spec.ts index b7bc655ccf..7e05c34295 100644 --- a/packages/util/test/signature.spec.ts +++ b/packages/util/test/signature.spec.ts @@ -24,11 +24,11 @@ describe('ecsign', () => { const sig = ecsign(echash, ecprivkey) assert.deepEqual( sig.r, - hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9') + hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9'), ) assert.deepEqual( sig.s, - hexToBytes('0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66') + hexToBytes('0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66'), ) assert.equal(sig.v, BigInt(27)) }) @@ -37,21 +37,21 @@ describe('ecsign', () => { const sig = ecsign(echash, ecprivkey, chainId) assert.deepEqual( sig.r, - hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9') + hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9'), ) assert.deepEqual( sig.s, - hexToBytes('0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66') + hexToBytes('0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66'), ) assert.equal(sig.v, BigInt(41)) }) it('should produce a signature for chainId=150', () => { const expectedSigR = hexToBytes( - '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9' + '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', ) const expectedSigS = hexToBytes( - '0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66' + '0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', ) const sig = ecsign(echash, ecprivkey, BigInt(150)) @@ -63,10 +63,10 @@ describe('ecsign', () => { it('should produce a signature for a high number chainId greater than MAX_SAFE_INTEGER', () => { const chainIDBuffer = hexToBytes('0x796f6c6f763378') const expectedSigR = hexToBytes( - '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9' + '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', ) const expectedSigS = hexToBytes( - '0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66' + '0x129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', ) const expectedSigV = BigInt('68361967398315795') @@ -144,7 +144,7 @@ describe('ecrecover', () => { } */ const senderPubKey = hexToBytes( - '0x78988201fbceed086cfca7b64e382d08d0bd776898731443d2907c097745b7324c54f522087f5964412cddba019f192de0fd57a0ffa63f098c2b200e53594b15' + '0x78988201fbceed086cfca7b64e382d08d0bd776898731443d2907c097745b7324c54f522087f5964412cddba019f192de0fd57a0ffa63f098c2b200e53594b15', ) const msgHash = hexToBytes('0x8ae8cb685a7a9f29494b07b287c3f6a103b73fa178419d10d1184861a40f6afe') @@ -163,7 +163,7 @@ describe('hashPersonalMessage', () => { const h = hashPersonalMessage(utf8ToBytes('Hello world')) assert.deepEqual( h, - hexToBytes('0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede') + hexToBytes('0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede'), ) }) it('should throw if input is not a Uint8Array', () => { @@ -198,7 +198,7 @@ describe('isValidSignature', () => { }) it('should fail when on homestead and s > secp256k1n/2', () => { const SECP256K1_N_DIV_2 = BigInt( - '0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0' + '0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', ) const r = hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9') @@ -209,7 +209,7 @@ describe('isValidSignature', () => { }) it('should not fail when not on homestead but s > secp256k1n/2', () => { const SECP256K1_N_DIV_2 = BigInt( - '0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0' + '0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', ) const r = hexToBytes('0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9') @@ -336,7 +336,7 @@ describe('message sig', () => { }) assert.throws(function () { fromRpcSig( - '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca' + '0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca', ) }) }) @@ -344,7 +344,7 @@ describe('message sig', () => { it('pad short r and s values', () => { assert.equal( toRpcSig(BigInt(27), r.slice(20), s.slice(20)), - '0x00000000000000000000000000000000000000004a1579cf389ef88b20a1abe90000000000000000000000000000000000000000326fa689f228040429e3ca661b' + '0x00000000000000000000000000000000000000004a1579cf389ef88b20a1abe90000000000000000000000000000000000000000326fa689f228040429e3ca661b', ) }) diff --git a/packages/util/test/verkle.spec.ts b/packages/util/test/verkle.spec.ts index 3a66f1244a..8eed055405 100644 --- a/packages/util/test/verkle.spec.ts +++ b/packages/util/test/verkle.spec.ts @@ -27,24 +27,24 @@ describe('Verkle cryptographic helpers', () => { // Empty address assert.equal( bytesToHex( - getVerkleStem(verkle, Address.fromString('0x0000000000000000000000000000000000000000')) + getVerkleStem(verkle, Address.fromString('0x0000000000000000000000000000000000000000')), ), - '0x1a100684fd68185060405f3f160e4bb6e034194336b547bdae323f888d5332' + '0x1a100684fd68185060405f3f160e4bb6e034194336b547bdae323f888d5332', ) // Non-empty address assert.equal( bytesToHex( - getVerkleStem(verkle, Address.fromString('0x71562b71999873DB5b286dF957af199Ec94617f7')) + getVerkleStem(verkle, Address.fromString('0x71562b71999873DB5b286dF957af199Ec94617f7')), ), - '0x1540dfad7755b40be0768c6aa0a5096fbf0215e0e8cf354dd928a178346466' + '0x1540dfad7755b40be0768c6aa0a5096fbf0215e0e8cf354dd928a178346466', ) }) it('verifyVerkleProof(): should verify verkle proofs', () => { // Src: Kaustinen6 testnet, block 71 state root (parent of block 72) const prestateRoot = hexToBytes( - '0x64e1a647f42e5c2e3c434531ccf529e1b3e93363a40db9fc8eec81f492123510' + '0x64e1a647f42e5c2e3c434531ccf529e1b3e93363a40db9fc8eec81f492123510', ) const executionWitness = verkleBlockJSON.executionWitness as VerkleExecutionWitness assert.isTrue(verifyVerkleProof(verkle, prestateRoot, executionWitness)) diff --git a/packages/util/test/withdrawal.spec.ts b/packages/util/test/withdrawal.spec.ts index 502d654e1f..b090ac361c 100644 --- a/packages/util/test/withdrawal.spec.ts +++ b/packages/util/test/withdrawal.spec.ts @@ -70,7 +70,7 @@ describe('Withdrawal', () => { const gethWithdrawalsRlp = bytesToHex(encode(gethWithdrawalsBuffer)) it('fromWithdrawalData and toBytesArray', () => { const withdrawals = withdrawalsGethVector.map((withdrawal) => - Withdrawal.fromWithdrawalData(withdrawal as WithdrawalData) + Withdrawal.fromWithdrawalData(withdrawal as WithdrawalData), ) const withdrawalstoBytesArr = withdrawals.map((wt) => wt.raw()) const withdrawalsToRlp = bytesToHex(encode(withdrawalstoBytesArr)) @@ -79,7 +79,7 @@ describe('Withdrawal', () => { it('toBytesArray from withdrawalData', () => { const withdrawalsDatatoBytesArr = withdrawalsGethVector.map((withdrawal) => - Withdrawal.toBytesArray(withdrawal as WithdrawalData) + Withdrawal.toBytesArray(withdrawal as WithdrawalData), ) const withdrawalsDataToRlp = bytesToHex(encode(withdrawalsDatatoBytesArr)) assert.equal(gethWithdrawalsRlp, withdrawalsDataToRlp, 'The withdrawals to buffer should match') @@ -93,7 +93,7 @@ describe('Withdrawal', () => { const withdrawalsValue = withdrawals.map((wt) => wt.toValue()) assert.deepEqual( withdrawalsValue.map((wt) => bytesToHex(wt.address)), - withdrawalsJson.map((wt) => wt.address) + withdrawalsJson.map((wt) => wt.address), ) }) }) diff --git a/packages/util/tsconfig.lint.json b/packages/util/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/util/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/verkle/.eslintrc.cjs b/packages/verkle/.eslintrc.cjs index 1fa27a8fea..887e31b0e6 100644 --- a/packages/verkle/.eslintrc.cjs +++ b/packages/verkle/.eslintrc.cjs @@ -1,12 +1,12 @@ module.exports = { extends: '../../config/eslint.cjs', parserOptions: { - project: ['./tsconfig.json', './tsconfig.benchmarks.json'], + project: ['./tsconfig.lint.json'], }, ignorePatterns: ['src/rust-verkle-wasm/rust_verkle_wasm.js', '**/vendor/*.js'], overrides: [ { - files: ['benchmarks/*.ts'], + files: ['benchmarks/*.ts', 'examples/*.ts'], rules: { 'no-console': 'off', }, diff --git a/packages/verkle/src/node/internalNode.ts b/packages/verkle/src/node/internalNode.ts index 2a401dc8d0..86a16a500e 100644 --- a/packages/verkle/src/node/internalNode.ts +++ b/packages/verkle/src/node/internalNode.ts @@ -33,7 +33,7 @@ export class InternalNode extends BaseVerkleNode { childIndex, // The hashed child commitments are used when updating the internal node commitment this.verkleCrypto.hashCommitment(oldChildReference.commitment), - this.verkleCrypto.hashCommitment(child.commitment) + this.verkleCrypto.hashCommitment(child.commitment), ) } diff --git a/packages/verkle/src/node/leafNode.ts b/packages/verkle/src/node/leafNode.ts index 8592fa4d38..ceac0b02f4 100644 --- a/packages/verkle/src/node/leafNode.ts +++ b/packages/verkle/src/node/leafNode.ts @@ -38,7 +38,7 @@ export class LeafNode extends BaseVerkleNode { static async create( stem: Uint8Array, verkleCrypto: VerkleCrypto, - values?: (Uint8Array | VerkleLeafNodeValue)[] + values?: (Uint8Array | VerkleLeafNodeValue)[], ): Promise { // Generate the value arrays for c1 and c2 values = values !== undefined ? values : createDefaultLeafValues() @@ -66,13 +66,13 @@ export class LeafNode extends BaseVerkleNode { verkleCrypto.zeroCommitment, 0, new Uint8Array(32), - setLengthLeft(intToBytes(1), 32) + setLengthLeft(intToBytes(1), 32), ) commitment = verkleCrypto.updateCommitment( commitment, 1, new Uint8Array(32), - setLengthRight(stem, 32) + setLengthRight(stem, 32), ) commitment = verkleCrypto.updateCommitment( commitment, @@ -80,13 +80,13 @@ export class LeafNode extends BaseVerkleNode { new Uint8Array(32), // We hash the commitment when using in the leaf node commitment since c1 is 64 bytes long // and we need a 32 byte input for the scalar value in `updateCommitment` - verkleCrypto.hashCommitment(c1) + verkleCrypto.hashCommitment(c1), ) commitment = verkleCrypto.updateCommitment( commitment, 3, new Uint8Array(32), - verkleCrypto.hashCommitment(c2) + verkleCrypto.hashCommitment(c2), ) return new LeafNode({ stem, @@ -164,7 +164,7 @@ export class LeafNode extends BaseVerkleNode { commitmentIndex, cValues[commitmentIndex], // Right pad the value with zeroes since commitments require 32 byte scalars - setLengthRight(val.slice(0, 16), 32) + setLengthRight(val.slice(0, 16), 32), ) // Update the commitment for the second 16 bytes of the value cCommitment = this.verkleCrypto.updateCommitment( @@ -172,7 +172,7 @@ export class LeafNode extends BaseVerkleNode { commitmentIndex + 1, cValues[commitmentIndex + 1], // Right pad the value with zeroes since commitments require 32 byte scalars - setLengthRight(val.slice(16), 32) + setLengthRight(val.slice(16), 32), ) // Update the cCommitment corresponding to the index let oldCCommitment: Uint8Array | undefined @@ -191,7 +191,7 @@ export class LeafNode extends BaseVerkleNode { this.commitment, cIndex, this.verkleCrypto.hashCommitment(oldCCommitment!), - this.verkleCrypto.hashCommitment(cCommitment) + this.verkleCrypto.hashCommitment(cCommitment), ) } diff --git a/packages/verkle/src/verkleTree.ts b/packages/verkle/src/verkleTree.ts index efebeaee67..c1839b966a 100644 --- a/packages/verkle/src/verkleTree.ts +++ b/packages/verkle/src/verkleTree.ts @@ -86,7 +86,7 @@ export class VerkleTree { this.verkleCrypto = opts?.verkleCrypto this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false this.debug = this.DEBUG ? (message: string, namespaces: string[] = []) => { let log = this._debug @@ -237,7 +237,7 @@ export class VerkleTree { // Sanity check to verify we have the right node type if (!isLeafNode(foundPath.node)) { throw new Error( - `expected leaf node found at ${bytesToHex(stem)}. Got internal node instead` + `expected leaf node found at ${bytesToHex(stem)}. Got internal node instead`, ) } leafNode = foundPath.node @@ -245,8 +245,8 @@ export class VerkleTree { if (!equalsBytes(leafNode.stem, stem)) { throw new Error( `invalid leaf node found. Expected stem: ${bytesToHex(stem)}; got ${bytesToHex( - foundPath.node.stem - )}` + foundPath.node.stem, + )}`, ) } } else { @@ -265,7 +265,7 @@ export class VerkleTree { this.DEBUG && this.debug( `Updating value for suffix: ${suffix} at leaf node with stem: ${bytesToHex(stem)}`, - ['PUT'] + ['PUT'], ) putStack.push([leafNode.hash(), leafNode]) @@ -296,9 +296,9 @@ export class VerkleTree { this.DEBUG && this.debug( `Updating child reference for node with path: ${bytesToHex( - lastPath + lastPath, )} at index ${childIndex} in internal node at path ${bytesToHex(nextPath)}`, - ['PUT'] + ['PUT'], ) // Hold onto `path` to current node for updating next parent node child index lastPath = nextPath @@ -318,7 +318,7 @@ export class VerkleTree { `Updating child reference for node with path: ${bytesToHex(lastPath)} at index ${ lastPath[0] } in root node`, - ['PUT'] + ['PUT'], ) this.DEBUG && this.debug(`Updating root node hash to ${bytesToHex(this._root)}`, ['PUT']) putStack.push([this._root, rootNode]) @@ -342,7 +342,7 @@ export class VerkleTree { updateParent( leafNode: LeafNode, nearestNode: VerkleNode, - pathToNode: Uint8Array + pathToNode: Uint8Array, ): { node: InternalNode; lastPath: Uint8Array } { // Compute the portion of leafNode.stem and nearestNode.path that match (i.e. the partial path closest to leafNode.stem) const partialMatchingStemIndex = matchingBytesLength(leafNode.stem, pathToNode) @@ -375,13 +375,13 @@ export class VerkleTree { this.DEBUG && this.debug( `Updating child reference for leaf node with stem: ${bytesToHex( - leafNode.stem + leafNode.stem, )} at index ${ leafNode.stem[partialMatchingStemIndex] } in internal node at path ${bytesToHex( - leafNode.stem.slice(0, partialMatchingStemIndex) + leafNode.stem.slice(0, partialMatchingStemIndex), )}`, - ['PUT'] + ['PUT'], ) } return { node: internalNode, lastPath: pathToNode } @@ -440,9 +440,9 @@ export class VerkleTree { this.DEBUG && this.debug( `Path ${bytesToHex(key)} - found full path to node ${bytesToHex( - decodedNode.hash() + decodedNode.hash(), )}.`, - ['FIND_PATH'] + ['FIND_PATH'], ) result.node = decodedNode result.remaining = new Uint8Array() @@ -455,9 +455,9 @@ export class VerkleTree { this.DEBUG && this.debug( `Path ${bytesToHex(pathToNearestNode)} - found path to nearest node ${bytesToHex( - decodedNode.hash() + decodedNode.hash(), )} but target node not found.`, - ['FIND_PATH'] + ['FIND_PATH'], ) result.stack.push([decodedNode, pathToNearestNode]) return result @@ -467,9 +467,9 @@ export class VerkleTree { this.DEBUG && this.debug( `Partial Path ${bytesToHex( - key.slice(0, matchingKeyLength) + key.slice(0, matchingKeyLength), )} - found next node in path ${bytesToHex(decodedNode.hash())}.`, - ['FIND_PATH'] + ['FIND_PATH'], ) // Get the next child node in the path const childIndex = key[matchingKeyLength] @@ -478,9 +478,9 @@ export class VerkleTree { this.DEBUG && this.debug( `Found partial path ${key.slice( - 31 - result.remaining.length + 31 - result.remaining.length, )} but sought node is not present in trie.`, - ['FIND_PATH'] + ['FIND_PATH'], ) return result } @@ -547,7 +547,7 @@ export class VerkleTree { async verifyProof( _rootHash: Uint8Array, _key: Uint8Array, - _proof: Proof + _proof: Proof, ): Promise { throw new Error('Not implemented') } diff --git a/packages/verkle/test/internalNode.spec.ts b/packages/verkle/test/internalNode.spec.ts index 328658d9f4..f8fd34102f 100644 --- a/packages/verkle/test/internalNode.spec.ts +++ b/packages/verkle/test/internalNode.spec.ts @@ -22,7 +22,7 @@ describe('verkle node - internal', () => { assert.equal(node.children.length, NODE_WIDTH, 'number of children should equal verkle width') assert.ok( node.children.every((child) => child === null), - 'every children should be null' + 'every children should be null', ) }) @@ -33,14 +33,14 @@ describe('verkle node - internal', () => { assert.deepEqual( node.commitment, verkleCrypto.zeroCommitment, - 'commitment should be set to point identity' + 'commitment should be set to point identity', ) // Children nodes should all default to null. assert.equal(node.children.length, NODE_WIDTH, 'number of children should equal verkle width') assert.ok( node.children.every((child) => child === null), - 'every children should be null' + 'every children should be null', ) }) it('should serialize and deserialize a node', async () => { diff --git a/packages/verkle/test/leafNode.spec.ts b/packages/verkle/test/leafNode.spec.ts index ff62de67ba..b9addecde5 100644 --- a/packages/verkle/test/leafNode.spec.ts +++ b/packages/verkle/test/leafNode.spec.ts @@ -35,14 +35,14 @@ describe('verkle node - leaf', () => { assert.equal(node.type, VerkleNodeType.Leaf, 'type should be set') assert.ok( equalsBytes(node.commitment as unknown as Uint8Array, commitment), - 'commitment should be set' + 'commitment should be set', ) assert.ok(equalsBytes(node.c1 as unknown as Uint8Array, c1), 'c1 should be set') assert.ok(equalsBytes(node.c2 as unknown as Uint8Array, c2), 'c2 should be set') assert.ok(equalsBytes(node.stem, stem), 'stem should be set') assert.ok( values.every((value, index) => equalsBytes(value, node.values[index] as Uint8Array)), - 'values should be set' + 'values should be set', ) }) diff --git a/packages/verkle/test/verkle.spec.ts b/packages/verkle/test/verkle.spec.ts index 9cbfb15fe6..c023ec604f 100644 --- a/packages/verkle/test/verkle.spec.ts +++ b/packages/verkle/test/verkle.spec.ts @@ -97,7 +97,7 @@ describe('Verkle tree', () => { assert.deepEqual( verkleCrypto.serializeCommitment(pathToNonExistentNode.stack[0][0].commitment), tree.root(), - 'contains the root node in the stack' + 'contains the root node in the stack', ) }) @@ -264,7 +264,7 @@ describe('Verkle tree', () => { assert.ok(res.node !== null) assert.deepEqual( (res.node as LeafNode).values[hexToBytes(keys[0])[31]], - VerkleLeafNodeValue.Deleted + VerkleLeafNodeValue.Deleted, ) }) }) diff --git a/packages/verkle/tsconfig.lint.json b/packages/verkle/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/verkle/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/vm/.eslintrc.cjs b/packages/vm/.eslintrc.cjs index 6aaac545e9..811a41ecc2 100644 --- a/packages/vm/.eslintrc.cjs +++ b/packages/vm/.eslintrc.cjs @@ -1,14 +1,16 @@ module.exports = { extends: '../../config/eslint.cjs', + parserOptions: { + project: ['./tsconfig.lint.json'], + }, rules: { '@typescript-eslint/no-use-before-define': 'off', 'no-invalid-this': 'off', 'no-restricted-syntax': 'off', - 'import/extensions': 'off', }, overrides: [ { - files: ['test/util.ts', 'test/tester/**/*.ts'], + files: ['test/util.ts', 'test/tester/**/*.ts', 'examples/**/*.ts'], rules: { 'no-console': 'off', }, diff --git a/packages/vm/examples/buildBlock.ts b/packages/vm/examples/buildBlock.ts index c94159478b..b6c181746d 100644 --- a/packages/vm/examples/buildBlock.ts +++ b/packages/vm/examples/buildBlock.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' -import { buildBlock, VM } from '@ethereumjs/vm' +import { VM, buildBlock } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Chain.Mainnet }) @@ -10,7 +10,7 @@ const main = async () => { const parentBlock = createBlockFromBlockData( { header: { number: 1n } }, - { skipConsensusFormatValidation: true } + { skipConsensusFormatValidation: true }, ) const headerData = { number: 2n, @@ -39,4 +39,4 @@ const main = async () => { console.log(`Built a block with hash ${bytesToHex(block.hash())}`) } -main() +void main() diff --git a/packages/vm/examples/helpers/account-utils.ts b/packages/vm/examples/helpers/account-utils.ts index 97d56a10af..55e6fc6fe3 100644 --- a/packages/vm/examples/helpers/account-utils.ts +++ b/packages/vm/examples/helpers/account-utils.ts @@ -1,5 +1,6 @@ -import { VM } from '@ethereumjs/vm' -import { Account, createAccount, Address } from '@ethereumjs/util' +import { Address, createAccount } from '@ethereumjs/util' + +import type { VM } from '@ethereumjs/vm' export const keyPair = { secretKey: '0x3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', diff --git a/packages/vm/examples/helpers/tx-builder.ts b/packages/vm/examples/helpers/tx-builder.ts index b00be99f7b..c859cb3152 100644 --- a/packages/vm/examples/helpers/tx-builder.ts +++ b/packages/vm/examples/helpers/tx-builder.ts @@ -1,12 +1,13 @@ -import { Interface, defaultAbiCoder as AbiCoder } from '@ethersproject/abi' -import { LegacyTxData } from '@ethereumjs/tx' +import { defaultAbiCoder as AbiCoder, Interface } from '@ethersproject/abi' + +import type { LegacyTxData } from '@ethereumjs/tx' export const encodeFunction = ( method: string, params?: { types: any[] values: unknown[] - } + }, ): string => { const parameters = params?.types ?? [] const methodWithParameters = `function ${method}(${parameters.join(',')})` @@ -21,7 +22,7 @@ export const encodeDeployment = ( params?: { types: any[] values: unknown[] - } + }, ) => { const deploymentData = '0x' + bytecode if (params) { diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index b50a1d44e3..92aa4b6f69 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -6,31 +6,25 @@ // 4. Puts the blocks from ../utils/blockchain-mock-data "blocks" attribute into the Blockchain // 5. Runs the Blockchain on the VM. +import { createBlockFromBlockData, createBlockFromRLPSerializedBlock } from '@ethereumjs/block' +import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' +import { Common, ConsensusAlgorithm, ConsensusType } from '@ethereumjs/common' +import { Ethash } from '@ethereumjs/ethash' import { Address, - toBytes, - setLengthLeft, bytesToHex, - hexToBytes, createAccount, + hexToBytes, + setLengthLeft, + toBytes, } from '@ethereumjs/util' -import { - Block, - createBlockFromBlockData, - createBlockFromRLPSerializedBlock, -} from '@ethereumjs/block' -import { - Blockchain, - ConsensusDict, - createBlockchain, - EthashConsensus, -} from '@ethereumjs/blockchain' -import { Common, ConsensusAlgorithm, ConsensusType } from '@ethereumjs/common' -import { Ethash } from '@ethereumjs/ethash' -import { runBlock, VM } from '@ethereumjs/vm' +import { VM, runBlock } from '@ethereumjs/vm' import testData from './helpers/blockchain-mock-data.json' +import type { Block } from '@ethereumjs/block' +import type { Blockchain, ConsensusDict } from '@ethereumjs/blockchain' + async function main() { const common = new Common({ chain: 1, hardfork: testData.network.toLowerCase() }) const validatePow = common.consensusType() === ConsensusType.ProofOfWork @@ -54,7 +48,7 @@ async function main() { await putBlocks(blockchain, common, testData) - await blockchain.iterator('vm', async (block: Block, reorg: boolean) => { + await blockchain.iterator('vm', async (block: Block, _reorg: boolean) => { const parentBlock = await blockchain!.getBlock(block.header.parentHash) const parentState = parentBlock.header.stateRoot // run block diff --git a/packages/vm/examples/run-solidity-contract.ts b/packages/vm/examples/run-solidity-contract.ts index 4e7b928c00..efb53c03dd 100644 --- a/packages/vm/examples/run-solidity-contract.ts +++ b/packages/vm/examples/run-solidity-contract.ts @@ -2,12 +2,13 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' -import { runTx, VM } from '@ethereumjs/vm' +import { VM, runTx } from '@ethereumjs/vm' import { defaultAbiCoder as AbiCoder, Interface } from '@ethersproject/abi' import { readFileSync } from 'fs' import path from 'path' import solc from 'solc' import { fileURLToPath } from 'url' + import { getAccountNonce, insertAccount } from './helpers/account-utils.js' import { buildTransaction, encodeDeployment, encodeFunction } from './helpers/tx-builder.js' @@ -65,7 +66,7 @@ function compileContracts() { let compilationFailed = false - if (output.errors) { + if (output.errors !== undefined) { for (const error of output.errors) { if (error.severity === 'error') { console.error(error.formattedMessage) @@ -91,7 +92,7 @@ async function deployContract( vm: VM, senderPrivateKey: Uint8Array, deploymentBytecode: string, - greeting: string + greeting: string, ): Promise
{ // Contracts are deployed by sending their deployment bytecode to the address 0 // The contract params should be abi-encoded and appended to the deployment bytecode. @@ -120,7 +121,7 @@ async function setGreeting( vm: VM, senderPrivateKey: Uint8Array, contractAddress: Address, - greeting: string + greeting: string, ) { const data = encodeFunction('setGreeting', { types: ['string'], @@ -147,7 +148,7 @@ async function getGreeting(vm: VM, contractAddress: Address, caller: Address) { const greetResult = await vm.evm.runCall({ to: contractAddress, - caller: caller, + caller, origin: caller, // The tx.origin is also the caller here data: hexToBytes(sigHash), block, @@ -194,7 +195,7 @@ async function main() { if (greeting !== INITIAL_GREETING) throw new Error( - `initial greeting not equal, received ${greeting}, expected ${INITIAL_GREETING}` + `initial greeting not equal, received ${greeting}, expected ${INITIAL_GREETING}`, ) console.log('Changing greeting...') diff --git a/packages/vm/examples/runGoerliBlock.ts b/packages/vm/examples/runGoerliBlock.ts index 4f821fcdcb..0acc1c9bbe 100644 --- a/packages/vm/examples/runGoerliBlock.ts +++ b/packages/vm/examples/runGoerliBlock.ts @@ -1,9 +1,11 @@ -import { Block, createBlockFromRPC } from '@ethereumjs/block' +import { createBlockFromRPC } from '@ethereumjs/block' import { Chain, Common } from '@ethereumjs/common' -import { bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex } from '@ethereumjs/util' + +import { runBlock } from '../src/index.js' import { VM } from '../src/vm.js' + import goerliBlock2 from './testData/goerliBlock2.json' -import { runBlock } from '../src/index.js' const main = async () => { const common = new Common({ chain: Chain.Goerli, hardfork: 'london' }) @@ -14,4 +16,4 @@ const main = async () => { console.log(`The state root for Goerli block 2 is ${bytesToHex(result.stateRoot)}`) } -main() +void main() diff --git a/packages/vm/examples/runTx.ts b/packages/vm/examples/runTx.ts index cb76ff24f6..09bec35f7a 100644 --- a/packages/vm/examples/runTx.ts +++ b/packages/vm/examples/runTx.ts @@ -1,7 +1,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' -import { runTx, VM } from '@ethereumjs/vm' +import { VM, runTx } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) @@ -20,4 +20,4 @@ const main = async () => { console.log(res.totalGasSpent) // 21000n - gas cost for simple ETH transfer } -main() +void main() diff --git a/packages/vm/examples/vmWith4844.ts b/packages/vm/examples/vmWith4844.ts index 24e68d436e..b751850d84 100644 --- a/packages/vm/examples/vmWith4844.ts +++ b/packages/vm/examples/vmWith4844.ts @@ -1,4 +1,5 @@ -import { Common, Chain, Hardfork } from '@ethereumjs/common' +import { Chain, Common, Hardfork } from '@ethereumjs/common' + import { VM } from '../src/vm.js' const main = async () => { @@ -7,4 +8,4 @@ const main = async () => { console.log(`4844 is active in the VM - ${vm.common.isActivatedEIP(4844)}`) } -main() +void main() diff --git a/packages/vm/examples/vmWithEIPs.ts b/packages/vm/examples/vmWithEIPs.ts index 3720a66a52..6446dd37c3 100644 --- a/packages/vm/examples/vmWithEIPs.ts +++ b/packages/vm/examples/vmWithEIPs.ts @@ -6,4 +6,4 @@ const main = async () => { const vm = await VM.create({ common }) console.log(`EIP 3074 is active in the VM - ${vm.common.isActivatedEIP(3074)}`) } -main() +void main() diff --git a/packages/vm/examples/vmWithGenesisState.ts b/packages/vm/examples/vmWithGenesisState.ts index 387bd11953..c8c9e1d21b 100644 --- a/packages/vm/examples/vmWithGenesisState.ts +++ b/packages/vm/examples/vmWithGenesisState.ts @@ -10,12 +10,12 @@ const main = async () => { const blockchain = await createBlockchain({ genesisState }) const vm = await VM.create({ blockchain, genesisState }) const account = await vm.stateManager.getAccount( - Address.fromString('0x000d836201318ec6899a67540690382780743280') + Address.fromString('0x000d836201318ec6899a67540690382780743280'), ) console.log( `This balance for account 0x000d836201318ec6899a67540690382780743280 in this chain's genesis state is ${Number( - account?.balance - )}` + account?.balance, + )}`, ) } -main() +void main() diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 8c89a53ba7..4e79c1e197 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -210,7 +210,7 @@ export class BlockBuilder { */ async addTransaction( tx: TypedTransaction, - { skipHardForkValidation }: { skipHardForkValidation?: boolean } = {} + { skipHardForkValidation }: { skipHardForkValidation?: boolean } = {}, ) { this.checkStatus() diff --git a/packages/vm/src/emitEVMProfile.ts b/packages/vm/src/emitEVMProfile.ts index 819874c027..c06140ca3a 100644 --- a/packages/vm/src/emitEVMProfile.ts +++ b/packages/vm/src/emitEVMProfile.ts @@ -111,7 +111,7 @@ export function emitEVMProfile(logs: EVMPerformanceLogOutput[], profileTitle: st console.log( `+== Calls: ${calls}, Total time: ${ Math.round(totalMs * 1e3) / 1e3 - }ms, Total gas: ${totalGas}, MGas/s: ${mGasSAvg}, Blocks per Slot (BpS): ${bpSAvg} ==+` + }ms, Total gas: ${totalGas}, MGas/s: ${mGasSAvg}, Blocks per Slot (BpS): ${bpSAvg} ==+`, ) // Generate and write the header diff --git a/packages/vm/src/requests.ts b/packages/vm/src/requests.ts index 36c4214262..10100698c0 100644 --- a/packages/vm/src/requests.ts +++ b/packages/vm/src/requests.ts @@ -25,7 +25,7 @@ import type { CLRequest, CLRequestType } from '@ethereumjs/util' */ export const accumulateRequests = async ( vm: VM, - txResults: RunTxResult[] + txResults: RunTxResult[], ): Promise[]> => { const requests: CLRequest[] = [] const common = vm.common @@ -58,12 +58,12 @@ export const accumulateRequests = async ( const accumulateEIP7002Requests = async ( vm: VM, - requests: CLRequest[] + requests: CLRequest[], ): Promise => { // Partial withdrawals logic const addressBytes = setLengthLeft( bigIntToBytes(vm.common.param('withdrawalRequestPredeployAddress')), - 20 + 20, ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) @@ -71,7 +71,7 @@ const accumulateEIP7002Requests = async ( if (code.length === 0) { throw new Error( - 'Attempt to accumulate EIP-7002 requests failed: the contract does not exist. Ensure the deployment tx has been run, or that the required contract code is stored' + 'Attempt to accumulate EIP-7002 requests failed: the contract does not exist. Ensure the deployment tx has been run, or that the required contract code is stored', ) } @@ -108,12 +108,12 @@ const accumulateEIP7002Requests = async ( const accumulateEIP7251Requests = async ( vm: VM, - requests: CLRequest[] + requests: CLRequest[], ): Promise => { // Partial withdrawals logic const addressBytes = setLengthLeft( bigIntToBytes(vm.common.param('consolidationRequestPredeployAddress')), - 20 + 20, ) const consolidationsAddress = Address.fromString(bytesToHex(addressBytes)) @@ -121,7 +121,7 @@ const accumulateEIP7251Requests = async ( if (code.length === 0) { throw new Error( - 'Attempt to accumulate EIP-7251 requests failed: the contract does not exist. Ensure the deployment tx has been run, or that the required contract code is stored' + 'Attempt to accumulate EIP-7251 requests failed: the contract does not exist. Ensure the deployment tx has been run, or that the required contract code is stored', ) } @@ -145,7 +145,7 @@ const accumulateEIP7251Requests = async ( const sourcePubkey = slicedBytes.slice(20, 68) // 48 Bytes const targetPubkey = slicedBytes.slice(68, 116) // 48 bytes requests.push( - ConsolidationRequest.fromRequestData({ sourceAddress, sourcePubkey, targetPubkey }) + ConsolidationRequest.fromRequestData({ sourceAddress, sourcePubkey, targetPubkey }), ) } } @@ -161,7 +161,7 @@ const accumulateEIP7251Requests = async ( const accumulateDeposits = async ( depositContractAddress: string, txResults: RunTxResult[], - requests: CLRequest[] + requests: CLRequest[], ) => { for (const [_, tx] of txResults.entries()) { for (let i = 0; i < tx.receipt.logs.length; i++) { @@ -179,7 +179,7 @@ const accumulateDeposits = async ( const pubKeySize = bytesToInt(log[2].slice(pubKeyIdx, pubKeyIdx + 32)) const withdrawalCredsIdx = bytesToInt(log[2].slice(32, 64)) const withdrawalCredsSize = bytesToInt( - log[2].slice(withdrawalCredsIdx, withdrawalCredsIdx + 32) + log[2].slice(withdrawalCredsIdx, withdrawalCredsIdx + 32), ) const amountIdx = bytesToInt(log[2].slice(64, 96)) const amountSize = bytesToInt(log[2].slice(amountIdx, amountIdx + 32)) @@ -190,7 +190,7 @@ const accumulateDeposits = async ( const pubkey = log[2].slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize) const withdrawalCredentials = log[2].slice( withdrawalCredsIdx + 32, - withdrawalCredsIdx + 32 + withdrawalCredsSize + withdrawalCredsIdx + 32 + withdrawalCredsSize, ) const amountBytes = log[2].slice(amountIdx + 32, amountIdx + 32 + amountSize) const amountBytesBigEndian = new Uint8Array([ @@ -228,7 +228,7 @@ const accumulateDeposits = async ( amount, signature, index, - }) + }), ) } } diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 5365822f59..3715a65d78 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -51,7 +51,7 @@ import type { CLRequest, CLRequestType, PrefixedHexString } from '@ethereumjs/ut const debug = debugDefault('vm:block') const parentBeaconBlockRootAddress = Address.fromString( - '0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02' + '0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02', ) let enableProfiler = false @@ -126,7 +126,7 @@ export async function runBlock(vm: VM, opts: RunBlockOpts): Promise { function calculateOmmerReward( ommerBlockNumber: bigint, blockNumber: bigint, - minerReward: bigint + minerReward: bigint, ): bigint { const heightDiff = blockNumber - ommerBlockNumber let reward = ((BIGINT_8 - heightDiff) * minerReward) / BIGINT_8 @@ -734,7 +734,7 @@ export async function rewardAccount( evm: EVMInterface, address: Address, reward: bigint, - common?: Common + common?: Common, ): Promise { let account = await evm.stateManager.getAccount(address) if (account === undefined) { @@ -752,7 +752,7 @@ export async function rewardAccount( // use vm utility to build access but the computed gas is not charged and hence free ;(evm.stateManager as StatelessVerkleStateManager).accessWitness!.touchTxTargetAndComputeGas( address, - { sendsValue: true } + { sendsValue: true }, ) } return account diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 40c58cdc5a..128860c0fa 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -72,7 +72,7 @@ const entireTxLabel = 'Entire tx' */ function execHardfork( hardfork: Hardfork | string, - preMergeHf: Hardfork | string + preMergeHf: Hardfork | string, ): string | Hardfork { return hardfork !== Hardfork.Paris ? hardfork : preMergeHf } @@ -160,7 +160,7 @@ export async function runTx(vm: VM, opts: RunTxOpts): Promise { 'Cannot run transaction: EIP 2930 is not activated.', vm, opts.block, - opts.tx + opts.tx, ) throw new Error(msg) } @@ -170,7 +170,7 @@ export async function runTx(vm: VM, opts: RunTxOpts): Promise { 'Cannot run transaction: EIP 1559 is not activated.', vm, opts.block, - opts.tx + opts.tx, ) throw new Error(msg) } @@ -250,7 +250,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { debug( `New tx run hash=${ opts.tx.isSigned() ? bytesToHex(opts.tx.hash()) : 'unsigned' - } sender=${caller}` + } sender=${caller}`, ) } @@ -276,11 +276,11 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { if (gasLimit < intrinsicGas) { const msg = _errorMsg( `tx gas limit ${Number(gasLimit)} is lower than the minimum gas limit of ${Number( - intrinsicGas + intrinsicGas, )}`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -302,7 +302,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { } (${maxFeePerGas}) is less than the block's baseFeePerGas (${baseFeePerGas})`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -343,7 +343,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { `sender doesn't have enough funds to send tx. The upfront cost is: ${upFrontCost} and the sender's account (${caller}) only has: ${balance}`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -378,7 +378,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { `Block option must be supplied to compute blob gas price`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -388,7 +388,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { `Transaction's maxFeePerBlobGas ${castTx.maxFeePerBlobGas}) is less than block blobGasPrice (${blobGasPrice}).`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -404,7 +404,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { `sender doesn't have enough funds to send tx. The max cost is: ${maxCost} and the sender's account (${caller}) only has: ${balance}`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -416,7 +416,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { `the tx doesn't have the correct nonce. account has nonce of: ${nonce} tx has nonce of: ${tx.nonce}`, vm, block, - tx + tx, ) throw new Error(msg) } @@ -523,7 +523,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { tx.isSigned() ? bytesToHex(tx.hash()) : 'unsigned' } with caller=${caller} gasLimit=${gasLimit} to=${ to?.toString() ?? 'none' - } value=${value} data=${short(data)}` + } value=${value} data=${short(data)}`, ) } @@ -562,7 +562,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { debug( `Received tx execResult: [ executionGasUsed=${executionGasUsed} exceptionError=${ exceptionError !== undefined ? `'${exceptionError.error}'` : 'none' - } returnValue=${short(returnValue)} gasRefund=${results.gasRefund ?? 0} ]` + } returnValue=${short(returnValue)} gasRefund=${results.gasRefund ?? 0} ]`, ) } @@ -615,7 +615,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { await vm.evm.journal.putAccount(caller, fromAccount) if (vm.DEBUG) { debug( - `Refunded txCostDiff (${txCostDiff}) to fromAccount (caller) balance (-> ${fromAccount.balance})` + `Refunded txCostDiff (${txCostDiff}) to fromAccount (caller) balance (-> ${fromAccount.balance})`, ) } @@ -744,7 +744,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { results, cumulativeGasUsed, totalblobGas, - blobGasPrice + blobGasPrice, ) if (enableProfiler) { @@ -765,7 +765,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { debug( `tx run finished hash=${ opts.tx.isSigned() ? bytesToHex(opts.tx.hash()) : 'unsigned' - } sender=${caller}` + } sender=${caller}`, ) } @@ -808,7 +808,7 @@ export async function generateTxReceipt( txResult: RunTxResult, cumulativeGasUsed: bigint, blobGasUsed?: bigint, - blobGasPrice?: bigint + blobGasPrice?: bigint, ): Promise { const baseReceipt: BaseTxReceipt = { cumulativeBlockGasUsed: cumulativeGasUsed, @@ -823,7 +823,7 @@ export async function generateTxReceipt( tx.type } cumulativeBlockGasUsed=${cumulativeGasUsed} bitvector=${short(baseReceipt.bitvector)} (${ baseReceipt.bitvector.length - } bytes) logs=${baseReceipt.logs.length}` + } bytes) logs=${baseReceipt.logs.length}`, ) } diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index b41b7e8f12..4fce2f5cc3 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -96,7 +96,7 @@ export class VM { const profilerOpts = opts.profilerOpts if (profilerOpts.reportAfterBlock === true && profilerOpts.reportAfterTx === true) { throw new Error( - 'Cannot have `reportProfilerAfterBlock` and `reportProfilerAfterTx` set to `true` at the same time' + 'Cannot have `reportProfilerAfterBlock` and `reportProfilerAfterTx` set to `true` at the same time', ) } } @@ -171,7 +171,7 @@ export class VM { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = - typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false + typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false } /** diff --git a/packages/vm/test/api/EIPs/eip-1153.spec.ts b/packages/vm/test/api/EIPs/eip-1153.spec.ts index f27569126c..894cfc57b0 100644 --- a/packages/vm/test/api/EIPs/eip-1153.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1153.spec.ts @@ -32,13 +32,13 @@ describe('EIP 1153: transient storage', () => { assert.equal( step.opcode.name, test.steps[i].expectedOpcode, - `Expected Opcode: ${test.steps[i].expectedOpcode}` + `Expected Opcode: ${test.steps[i].expectedOpcode}`, ) assert.deepEqual( step.stack.map((e: bigint) => e.toString()), test.steps[i].expectedStack.map((e: bigint) => e.toString()), - `Expected stack: ${step.stack}` + `Expected stack: ${step.stack}`, ) if (i > 0) { @@ -47,7 +47,7 @@ describe('EIP 1153: transient storage', () => { gasUsed === expectedGasUsed, `Opcode: ${ test.steps[i - 1].expectedOpcode - }, Gas Used: ${gasUsed}, Expected: ${expectedGasUsed}` + }, Gas Used: ${gasUsed}, Expected: ${expectedGasUsed}`, ) } i++ diff --git a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts index 406f5fa7a3..6a4d50708e 100644 --- a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts @@ -63,7 +63,7 @@ function makeBlock(baseFee: bigint, transaction: TypedTransaction, txType: Trans }, transactions: [json], }, - { common } + { common }, ) return block } @@ -79,7 +79,7 @@ describe('EIP1559 tests', () => { }, { common, - } + }, ) const block = makeBlock(GWEI, tx, 2) const vm = await VM.create({ common }) @@ -116,7 +116,7 @@ describe('EIP1559 tests', () => { gasPrice: GWEI * BigInt(5), to: Address.zero(), }, - { common } + { common }, ) const block2 = makeBlock(GWEI, tx2, 1) await vm.stateManager.modifyAccountFields(sender, { balance }) @@ -144,7 +144,7 @@ describe('EIP1559 tests', () => { gasPrice: GWEI * BigInt(5), to: Address.zero(), }, - { common } + { common }, ) const block3 = makeBlock(GWEI, tx3, 0) await vm.stateManager.modifyAccountFields(sender, { balance }) @@ -178,7 +178,7 @@ describe('EIP1559 tests', () => { }, { common, - } + }, ) const block = makeBlock(GWEI, tx, 2) const vm = await VM.create({ common }) diff --git a/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts b/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts index 1a11905235..07a61287dd 100644 --- a/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2565-modexp-gas-cost.spec.ts @@ -26,7 +26,7 @@ describe('EIP-2565 ModExp gas cost tests', () => { if (result.execResult.executionGasUsed !== BigInt(test.Gas)) { assert.fail( - `[${testName}]: Gas usage incorrect, expected ${test.Gas}, got ${result.execResult.executionGasUsed}` + `[${testName}]: Gas usage incorrect, expected ${test.Gas}, got ${result.execResult.executionGasUsed}`, ) continue } @@ -40,7 +40,7 @@ describe('EIP-2565 ModExp gas cost tests', () => { assert.fail( `[${testName}]: Return value not the expected value (expected: ${ test.Expected - }, received: ${bytesToHex(result.execResult.returnValue)})` + }, received: ${bytesToHex(result.execResult.returnValue)})`, ) continue } diff --git a/packages/vm/test/api/EIPs/eip-2929.spec.ts b/packages/vm/test/api/EIPs/eip-2929.spec.ts index 91f3a7baca..e1c0f4967d 100644 --- a/packages/vm/test/api/EIPs/eip-2929.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2929.spec.ts @@ -26,7 +26,7 @@ describe('EIP 2929: gas cost tests', () => { assert.equal( step.opcode.name, test.steps[i].expectedOpcode, - `Expected Opcode: ${test.steps[i].expectedOpcode}` + `Expected Opcode: ${test.steps[i].expectedOpcode}`, ) // Validates the gas consumption of the (i - 1)th opcode @@ -40,7 +40,7 @@ describe('EIP 2929: gas cost tests', () => { gasUsed === expectedGasUsed, `Opcode: ${ test.steps[i - 1].expectedOpcode - }, Gas Used: ${gasUsed}, Expected: ${expectedGasUsed}` + }, Gas Used: ${gasUsed}, Expected: ${expectedGasUsed}`, ) } } @@ -66,7 +66,7 @@ describe('EIP 2929: gas cost tests', () => { const runCodeTest = async function (code: PrefixedHexString, expectedGasUsed: bigint) { // setup the accounts for this test const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) @@ -90,7 +90,7 @@ describe('EIP 2929: gas cost tests', () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - createAccount({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }), ) const result = await runTx(vm, { tx, skipHardForkValidation: true }) @@ -275,7 +275,7 @@ describe('EIP 2929: gas cost tests', () => { // call to contract, call 0xFF..FF, revert, call 0xFF..FF (should be cold) await runCodeTest( `0x341515601557${callFF}600080FD5B600080808080305AF1${callFF}00`, - BigInt(26414) + BigInt(26414), ) }) }) diff --git a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts index 379696aede..042377e11b 100644 --- a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts @@ -33,7 +33,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { gasLimit: BigInt(100000), to: contractAddress, }, - { common } + { common }, ).sign(privateKey) const txnWithoutAccessList = create2930AccessListTx( { @@ -42,7 +42,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { gasLimit: BigInt(100000), to: contractAddress, }, - { common } + { common }, ).sign(privateKey) const vm = await VM.create({ common }) @@ -56,7 +56,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - createAccount({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }), ) let trace: any = [] 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 ad658433fc..b312f056c2 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 @@ -192,7 +192,7 @@ describe('EIP 2935: historical block hashes', () => { const storage = await vm.stateManager.getContractStorage( historyAddress, - setLengthLeft(bigIntToBytes(BigInt(0)), 32) + setLengthLeft(bigIntToBytes(BigInt(0)), 32), ) assert.ok(equalsBytes(storage, genesis.hash())) }) @@ -248,7 +248,7 @@ describe('EIP 2935: historical block hashes', () => { const block = await blockchain.getBlock(i) const storage = await vm.stateManager.getContractStorage( historyAddress, - setLengthLeft(bigIntToBytes(BigInt(i) % historyServeWindow), 32) + setLengthLeft(bigIntToBytes(BigInt(i) % historyServeWindow), 32), ) // we will evaluate on lastBlock where 7709 is active and BLOCKHASH @@ -288,7 +288,7 @@ describe('EIP 2935: historical block hashes', () => { number: blocksToBuild, }, }, - { common } + { common }, ) // should be able to resolve blockhash via contract code but from the blocksActivation -1 onwards diff --git a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts index f5913e816d..e912290e6d 100644 --- a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts @@ -41,7 +41,7 @@ const block = createBlockFromBlockData( baseFeePerGas: BigInt(7), }, }, - { common } + { common }, ) const callerPrivateKey = hexToBytes(`0x${'44'.repeat(32)}`) @@ -71,7 +71,7 @@ function signMessage( commitUnpadded: Uint8Array, address: Address, privateKey: Uint8Array, - nonce: bigint = BIGINT_0 + nonce: bigint = BIGINT_0, ) { const commit = setLengthLeft(commitUnpadded, 32) const paddedInvokerAddress = setLengthLeft(address.bytes, 32) @@ -82,7 +82,7 @@ function signMessage( chainId, noncePadded, paddedInvokerAddress, - commit + commit, ) const msgHash = keccak256(message) return ecsign(msgHash, privateKey) @@ -99,7 +99,7 @@ function getAuthCode( commitUnpadded: Uint8Array, signature: ECDSASignature, address: Address, - msizeBuffer?: Uint8Array + msizeBuffer?: Uint8Array, ) { const commit = setLengthLeft(commitUnpadded, 32) let v: Uint8Array @@ -154,7 +154,7 @@ function getAuthCode( hexToBytes('0x6000'), PUSH32, addressBuffer, - AUTH + AUTH, ) } @@ -180,7 +180,7 @@ function MSTORE(position: Uint8Array, value: Uint8Array) { setLengthLeft(value, 32), hexToBytes('0x7F'), setLengthLeft(position, 32), - hexToBytes('0x52') + hexToBytes('0x52'), ) } @@ -361,7 +361,7 @@ describe('EIP-3074 AUTH', () => { const code = concatBytes( getAuthCode(message, signature, authAddress), getAuthCode(message, signature2, callerAddress), - RETURNTOP + RETURNTOP, ) await vm.stateManager.putContractCode(contractAddress, code) @@ -387,7 +387,7 @@ describe('EIP-3074 AUTH', () => { const signature = signMessage(message, contractAddress, privateKey) const code = concatBytes( getAuthCode(message, signature, authAddress, hexToBytes('0x60')), - RETURNTOP + RETURNTOP, ) await vm.stateManager.putContractCode(contractAddress, code) @@ -430,13 +430,13 @@ describe('EIP-3074 AUTH', () => { assert.deepEqual( result.execResult.returnValue.slice(31), hexToBytes('0x80'), - 'reported msize is correct' + 'reported msize is correct', ) const gas = result.execResult.executionGasUsed const code2 = concatBytes( getAuthCode(message, signature, authAddress, hexToBytes('0x90')), - RETURNMEMSIZE + RETURNMEMSIZE, ) await vm.stateManager.putContractCode(contractAddress, code2) @@ -454,7 +454,7 @@ describe('EIP-3074 AUTH', () => { assert.deepEqual( result2.execResult.returnValue.slice(31), hexToBytes('0xa0'), - 'reported msize is correct' + 'reported msize is correct', ) assert.ok(result2.execResult.executionGasUsed > gas, 'charged more gas for memory expansion') }) @@ -481,7 +481,7 @@ describe('EIP-3074 AUTHCALL', () => { getAuthCallCode({ address: contractStorageAddress, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -508,7 +508,7 @@ describe('EIP-3074 AUTHCALL', () => { getAuthCallCode({ address: contractStorageAddress, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -529,7 +529,7 @@ describe('EIP-3074 AUTHCALL', () => { const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) const gasBigInt = bytesToBigInt(gasUsed) const preGas = @@ -549,7 +549,7 @@ describe('EIP-3074 AUTHCALL', () => { getAuthCallCode({ address: contractStorageAddress, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -570,7 +570,7 @@ describe('EIP-3074 AUTHCALL', () => { const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) const gasBigInt = bytesToBigInt(gasUsed) const preGas = gas! - common.param('warmstoragereadGas')! @@ -587,7 +587,7 @@ describe('EIP-3074 AUTHCALL', () => { address: new Address(hexToBytes(`0x${'cc'.repeat(20)}`)), value: 1n, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) const account = new Account(BIGINT_0, BIGINT_1) @@ -632,7 +632,7 @@ describe('EIP-3074 AUTHCALL', () => { address: contractStorageAddress, value: 1n, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) const authAccount = new Account(BIGINT_0, BIGINT_1) @@ -659,7 +659,7 @@ describe('EIP-3074 AUTHCALL', () => { const gasUsed = await vm.stateManager.getContractStorage( contractStorageAddress, - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) const gasBigInt = bytesToBigInt(gasUsed) const preGas = @@ -691,7 +691,7 @@ describe('EIP-3074 AUTHCALL', () => { address: contractStorageAddress, value: 1n, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -715,7 +715,7 @@ describe('EIP-3074 AUTHCALL', () => { getAuthCallCode({ address: contractStorageAddress, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -729,7 +729,7 @@ describe('EIP-3074 AUTHCALL', () => { assert.equal( result.execResult.exceptionError?.error, EVMErrorMessage.AUTHCALL_UNSET, - 'threw with right error' + 'threw with right error', ) assert.equal(result.amountSpent, tx.gasPrice * tx.gasLimit, 'spent all gas') }) @@ -751,7 +751,7 @@ describe('EIP-3074 AUTHCALL', () => { getAuthCallCode({ address: contractStorageAddress, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -765,7 +765,7 @@ describe('EIP-3074 AUTHCALL', () => { assert.equal( result.execResult.exceptionError?.error, EVMErrorMessage.AUTHCALL_UNSET, - 'threw with right error' + 'threw with right error', ) assert.equal(result.amountSpent, tx.gasPrice * tx.gasLimit, 'spent all gas') }) @@ -779,7 +779,7 @@ describe('EIP-3074 AUTHCALL', () => { address: contractStorageAddress, gasLimit: 10000000n, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -794,7 +794,7 @@ describe('EIP-3074 AUTHCALL', () => { assert.equal( result.execResult.exceptionError?.error, EVMErrorMessage.OUT_OF_GAS, - 'correct error type' + 'correct error type', ) }) @@ -807,7 +807,7 @@ describe('EIP-3074 AUTHCALL', () => { address: contractStorageAddress, gasLimit: 700000n, }), - RETURNTOP + RETURNTOP, ) const vm = await setupVM(code) @@ -820,7 +820,7 @@ describe('EIP-3074 AUTHCALL', () => { await runTx(vm, { tx, block, skipHardForkValidation: true }) const gas = await vm.stateManager.getContractStorage( contractStorageAddress, - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) const gasBigInt = bytesToBigInt(gas) assert.equal(gasBigInt, BigInt(700000 - 2), 'forwarded the right amount of gas') // The 2 is subtracted due to the GAS opcode base fee @@ -840,7 +840,7 @@ describe('EIP-3074 AUTHCALL', () => { retOffset: 64n, retLength: 32n, }), - hexToBytes('0x60206040F3') // PUSH 32 PUSH 64 RETURN -> This returns the 32 bytes at memory position 64 + hexToBytes('0x60206040F3'), // PUSH 32 PUSH 64 RETURN -> This returns the 32 bytes at memory position 64 ) const vm = await setupVM(code) @@ -853,7 +853,7 @@ describe('EIP-3074 AUTHCALL', () => { const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const callInput = await vm.stateManager.getContractStorage( contractStorageAddress, - hexToBytes(`0x${'00'.repeat(31)}02`) + hexToBytes(`0x${'00'.repeat(31)}02`), ) assert.deepEqual(callInput, input, 'authcall input ok') assert.deepEqual(result.execResult.returnValue, input, 'authcall output ok') diff --git a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts index 1557b8fd7b..8c8562b133 100644 --- a/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3198-BaseFee.spec.ts @@ -53,7 +53,7 @@ function makeBlock(baseFee: bigint, transaction: TypedTransaction) { }, transactions: [json], }, - { common } + { common }, ) return block } @@ -72,7 +72,7 @@ describe('EIP3198 tests', () => { }, { common, - } + }, ) const block = makeBlock(fee, tx) const vm = await VM.create({ common }) diff --git a/packages/vm/test/api/EIPs/eip-3529.spec.ts b/packages/vm/test/api/EIPs/eip-3529.spec.ts index 0e7d90cab0..1a80cd793f 100644 --- a/packages/vm/test/api/EIPs/eip-3529.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3529.spec.ts @@ -135,7 +135,7 @@ describe('EIP-3529 tests', () => { await vm.stateManager.putContractStorage( address, key, - hexToBytes(`0x${testCase.original.toString().padStart(64, '0')}`) + hexToBytes(`0x${testCase.original.toString().padStart(64, '0')}`), ) await vm.stateManager.getContractStorage(address, key) diff --git a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts index 47583ee3b1..8a43198746 100644 --- a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts @@ -24,7 +24,7 @@ const block = createBlockFromBlockData( coinbase, }, }, - { common } + { common }, ) const code = hexToBytes('0x60008080806001415AF100') @@ -63,7 +63,7 @@ describe('EIP 3651 tests', () => { new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London, - }) + }), ) const result2 = await runTx(vm2, { block, tx, skipHardForkValidation: true }) @@ -71,7 +71,7 @@ describe('EIP 3651 tests', () => { assert.equal( result2.totalGasSpent - result.totalGasSpent, expectedDiff, - 'gas difference is correct' + 'gas difference is correct', ) }) }) diff --git a/packages/vm/test/api/EIPs/eip-3860.spec.ts b/packages/vm/test/api/EIPs/eip-3860.spec.ts index 18fac79da6..5ac7f20567 100644 --- a/packages/vm/test/api/EIPs/eip-3860.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3860.spec.ts @@ -30,18 +30,18 @@ describe('EIP 3860 tests', () => { const tx = create1559FeeMarketTx( { data: `0x7F6000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060005260206000F3${bytesToHex( - bytes + bytes, ).slice(2)}`, gasLimit: 100000000000, maxFeePerGas: 7, nonce: 0, }, - { common: txCommon } + { common: txCommon }, ).sign(pkey) const result = await runTx(vm, { tx }) assert.ok( (result.execResult.exceptionError?.error as string) === 'initcode exceeds max initcode size', - 'initcode exceeds max size' + 'initcode exceeds max size', ) }) }) diff --git a/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts b/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts index 2d1a1cb9d6..db4327f6ed 100644 --- a/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4399-supplant-difficulty-opcode-with-prevrando.spec.ts @@ -21,7 +21,7 @@ describe('EIP-4399 -> 0x44 (DIFFICULTY) should return PREVRANDAO', () => { } let block = createBlockFromBlockData( { header }, - { common, calcDifficultyFromHeader: genesis.header } + { common, calcDifficultyFromHeader: genesis.header }, ) // Track stack @@ -48,7 +48,7 @@ describe('EIP-4399 -> 0x44 (DIFFICULTY) should return PREVRANDAO', () => { mixHash: prevRandao, }, }, - { common } + { common }, ) await vm.evm.runCode!({ ...runCodeArgs, block }) assert.equal(stack[0], prevRandao, '0x44 returns PREVRANDAO (Merge)') diff --git a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts index c4479ee1b8..1e00713d3c 100644 --- a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts @@ -23,8 +23,7 @@ import { } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { VM } from '../../../src' -import { runBlock as runBlockVM } from '../../../src/index.js' +import { VM, runBlock as runBlockVM } from '../../../src/index.js' import type { Block } from '@ethereumjs/block' import type { BigIntLike, PrefixedHexString } from '@ethereumjs/util' @@ -41,7 +40,7 @@ const contractAddress = Address.fromString('0x' + 'c0de'.repeat(10)) function beaconrootBlock( blockroot: bigint, timestamp: BigIntLike, - transactions: Array + transactions: Array, ) { const newTxData = [] @@ -62,7 +61,7 @@ function beaconrootBlock( parentBeaconBlockRoot: root, timestamp, }, - { common, freeze: false } + { common, freeze: false }, ) const block = createBlockFromBlockData( { @@ -72,7 +71,7 @@ function beaconrootBlock( { common, freeze: false, - } + }, ) return block } @@ -144,7 +143,7 @@ async function runBlockTest(input: { const data = setLengthRight( setLengthLeft(bigIntToBytes(timestamp), input.extLeft ?? 32), - input.extRight ?? 32 + input.extRight ?? 32, ) const block = beaconrootBlock(blockRoot, timestampBlock, [ { diff --git a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts index efcf4aab0f..4376394f26 100644 --- a/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4844-blobs.spec.ts @@ -34,7 +34,7 @@ describe('EIP4844 tests', () => { }) const genesisBlock = createBlockFromBlockData( { header: { gasLimit: 50000, parentBeaconBlockRoot: zeros(32) } }, - { common } + { common }, ) const blockchain = await createBlockchain({ genesisBlock, @@ -76,7 +76,7 @@ describe('EIP4844 tests', () => { gasLimit: 0xffffn, to: hexToBytes('0xffb38a7a99e3e2335be83fc74b7faa19d5531243'), }, - { common } + { common }, ) const signedTx = unsignedTx.sign(pk) @@ -87,7 +87,7 @@ describe('EIP4844 tests', () => { assert.equal( bytesToHex(block.transactions[0].hash()), bytesToHex(signedTx.hash()), - 'blob transaction should be same' + 'blob transaction should be same', ) const blobGasPerBlob = common.param('blobGasPerBlob') diff --git a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts index 166b55288a..fb313c63bd 100644 --- a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts @@ -64,7 +64,7 @@ describe('EIP4895 tests', () => { */ await vm.stateManager.putContractCode( contractAddress, - hexToBytes(`0x73${addresses[0]}3160005260206000F3`) + hexToBytes(`0x73${addresses[0]}3160005260206000F3`), ) const transaction = create1559FeeMarketTx({ @@ -95,16 +95,16 @@ describe('EIP4895 tests', () => { header: { baseFeePerGas: BigInt(7), withdrawalsRoot: hexToBytes( - '0x267414525d22e2be123b619719b92c561f31e0cdd40959148230f5713aecd6b8' + '0x267414525d22e2be123b619719b92c561f31e0cdd40959148230f5713aecd6b8', ), transactionsTrie: hexToBytes( - '0x9a744e8acc2886e5809ff013e3b71bf8ec97f9941cafbd7730834fc8f76391ba' + '0x9a744e8acc2886e5809ff013e3b71bf8ec97f9941cafbd7730834fc8f76391ba', ), }, transactions: [transaction], withdrawals, }, - { common: vm.common } + { common: vm.common }, ) let result: Uint8Array @@ -135,12 +135,12 @@ describe('EIP4895 tests', () => { assert.equal( preState, '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45', - 'preState should be correct' + 'preState should be correct', ) const gethBlockBufferArray = decode(hexToBytes(gethWithdrawals8BlockRlp)) const withdrawals = (gethBlockBufferArray[3] as WithdrawalBytes[]).map((wa) => - Withdrawal.fromValuesArray(wa) + Withdrawal.fromValuesArray(wa), ) assert.equal(withdrawals[0].amount, BigInt(0), 'withdrawal 0 should have 0 amount') let block: Block @@ -157,7 +157,7 @@ describe('EIP4895 tests', () => { transactions: [], withdrawals: withdrawals.slice(0, 1), }, - { common: vm.common } + { common: vm.common }, ) postState = bytesToHex(await vm.stateManager.getStateRoot()) @@ -165,7 +165,7 @@ describe('EIP4895 tests', () => { assert.equal( postState, '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45', - 'post state should not change' + 'post state should not change', ) // construct a block with all the withdrawals @@ -179,14 +179,14 @@ describe('EIP4895 tests', () => { transactions: [], withdrawals, }, - { common: vm.common } + { common: vm.common }, ) await runBlock(vm, { block, generate: true }) postState = bytesToHex(await vm.stateManager.getStateRoot()) assert.equal( postState, '0x23eadd91fca55c0e14034e4d63b2b3ed43f2e807b6bf4d276b784ac245e7fa3f', - 'post state should match' + 'post state should match', ) }) @@ -205,7 +205,7 @@ describe('EIP4895 tests', () => { assert.equal( bytesToHex(genesisBlock.header.stateRoot), '0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45', - 'correct state root should be generated' + 'correct state root should be generated', ) const vm = await VM.create({ common, blockchain }) await vm.stateManager.generateCanonicalGenesis(parseGethGenesisState(genesisJSON)) @@ -213,7 +213,7 @@ describe('EIP4895 tests', () => { const gethBlockBufferArray = decode(hexToBytes(gethWithdrawals8BlockRlp)) const withdrawals = (gethBlockBufferArray[3] as WithdrawalBytes[]).map((wa) => - Withdrawal.fromValuesArray(wa) + Withdrawal.fromValuesArray(wa), ) const td = await blockchain.getTotalDifficulty(genesisBlock.hash()) @@ -232,7 +232,7 @@ describe('EIP4895 tests', () => { assert.equal( bytesToHex(block.header.stateRoot), '0x23eadd91fca55c0e14034e4d63b2b3ed43f2e807b6bf4d276b784ac245e7fa3f', - 'correct state root should be generated' + 'correct state root should be generated', ) // block should successfully execute with VM.runBlock and have same outputs diff --git a/packages/vm/test/api/EIPs/eip-6110.spec.ts b/packages/vm/test/api/EIPs/eip-6110.spec.ts index 2dd631d6a9..d7d1425bd0 100644 --- a/packages/vm/test/api/EIPs/eip-6110.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6110.spec.ts @@ -12,7 +12,7 @@ import type { DepositRequest } from '../../../../util/src/requests.js' import type { PrefixedHexString } from '@ethereumjs/util' const depositContractByteCode = hexToBytes( - '0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033' + '0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033', ) const common = new Common({ chain: Chain.Mainnet, @@ -53,7 +53,7 @@ describe('EIP-6110 runBlock tests', () => { { transactions: [depositTx], }, - { common } + { common }, ) const res = await runBlock(vm, { block, generate: true, skipBlockValidation: true }) assert.equal(res.requests?.length, 1) diff --git a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts index 9364c2653b..236c3cb238 100644 --- a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts @@ -63,7 +63,7 @@ describe('EIP 6780 tests', () => { (await vm.stateManager.getAccount(Address.fromString('0x' + '00'.repeat(19) + '01')))! .balance, BigInt(value), - 'balance sent to target' + 'balance sent to target', ) }) @@ -99,7 +99,7 @@ describe('EIP 6780 tests', () => { (await vm.stateManager.getAccount(Address.fromString('0x' + '00'.repeat(19) + '01')))! .balance, BigInt(value), - 'balance sent to target' + 'balance sent to target', ) }) }) diff --git a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts index d767053055..142bfb2a3f 100644 --- a/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6800-verkle.spec.ts @@ -8,8 +8,7 @@ import { loadVerkleCrypto } from 'verkle-cryptography-wasm' import { describe, it } from 'vitest' import * as verkleBlockJSON from '../../../../statemanager/test/testdata/verkleKaustinen6Block72.json' -import { VM } from '../../../src' -import { runBlock } from '../../../src/index.js' +import { VM, runBlock } from '../../../src/index.js' import type { BlockData } from '@ethereumjs/block' import type { PrefixedHexString } from '@ethereumjs/util' @@ -20,18 +19,18 @@ const common = createCustomCommon(customChainParams, { eips: [2935, 4895, 6800], }) const decodedTxs = verkleBlockJSON.transactions.map((tx) => - createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)) + createTxFromSerializedData(hexToBytes(tx as PrefixedHexString)), ) const parentStateRoot = hexToBytes( - '0x64e1a647f42e5c2e3c434531ccf529e1b3e93363a40db9fc8eec81f492123510' + '0x64e1a647f42e5c2e3c434531ccf529e1b3e93363a40db9fc8eec81f492123510', ) const block = createBlockFromBlockData( { ...verkleBlockJSON, transactions: decodedTxs } as BlockData, { common, - } + }, ) describe('EIP 6800 tests', () => { diff --git a/packages/vm/test/api/EIPs/eip-7002.spec.ts b/packages/vm/test/api/EIPs/eip-7002.spec.ts index db84982302..120a2ddea8 100644 --- a/packages/vm/test/api/EIPs/eip-7002.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7002.spec.ts @@ -33,7 +33,7 @@ const deploymentTxData = { gasLimit: BigInt('0x3d090'), gasPrice: BigInt('0xe8d4a51000'), data: hexToBytes( - '0x61049d5f5561013280600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd' + '0x61049d5f5561013280600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe146090573615156028575f545f5260205ff35b366038141561012e5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061012e57600154600101600155600354806003026004013381556001015f3581556001016020359055600101600355005b6003546002548082038060101160a4575060105b5f5b81811460dd5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160a6565b910180921460ed579060025560f8565b90505f6002555f6003555b5f548061049d141561010757505f5b60015460028282011161011c5750505f610122565b01600290035b5f555f600155604c025ff35b5f5ffd', ), v: BigInt('0x1b'), r: BigInt('0x539'), @@ -53,7 +53,7 @@ const amountBytes = setLengthLeft(bigIntToBytes(amount), 8) function generateTx(nonce: bigint) { const addressBytes = setLengthLeft( bigIntToBytes(common.param('withdrawalRequestPredeployAddress')), - 20 + 20, ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) @@ -77,7 +77,7 @@ describe('EIP-7002 tests', () => { }, transactions: [deploymentTx], }, - { common } + { common }, ) await vm.stateManager.putAccount(sender, acc) await vm.stateManager.putAccount(addr, acc) @@ -103,7 +103,7 @@ describe('EIP-7002 tests', () => { }, transactions: [tx], }, - { common } + { common }, ) let generatedBlock: Block @@ -149,7 +149,7 @@ describe('EIP-7002 tests', () => { }, transactions: [tx2, tx3], }, - { common } + { common }, ) await runBlock(vm, { @@ -172,7 +172,7 @@ describe('EIP-7002 tests', () => { number: 1, }, }, - { common } + { common }, ) try { await runBlock(vm, { diff --git a/packages/vm/test/api/EIPs/eip-7685.spec.ts b/packages/vm/test/api/EIPs/eip-7685.spec.ts index c910d73f23..887a137f54 100644 --- a/packages/vm/test/api/EIPs/eip-7685.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7685.spec.ts @@ -16,7 +16,7 @@ import { setupVM } from '../utils.js' import type { CLRequest, CLRequestType } from '@ethereumjs/util' const invalidRequestsRoot = hexToBytes( - '0xc98048d6605eb79ecc08d90b8817f44911ec474acd8d11688453d2c6ef743bc5' + '0xc98048d6605eb79ecc08d90b8817f44911ec474acd8d11688453d2c6ef743bc5', ) function getRandomDepositRequest(): CLRequest { const depositRequestData = { @@ -46,12 +46,12 @@ describe('EIP-7685 runBlock tests', () => { const emptyBlock = createBlockFromBlockData( { header: { requestsRoot: invalidRequestsRoot } }, - { common } + { common }, ) await expect(async () => runBlock(vm, { block: emptyBlock, - }) + }), ).rejects.toThrow('invalid requestsRoot') }) it('should not throw invalid requestsRoot error when valid requests are provided', async () => { @@ -63,7 +63,7 @@ describe('EIP-7685 runBlock tests', () => { requests: [request], header: { requestsRoot }, }, - { common } + { common }, ) await expect(async () => runBlock(vm, { block })).rejects.toThrow(/invalid requestsRoot/) }) @@ -75,7 +75,7 @@ describe('EIP-7685 runBlock tests', () => { requests: [request], header: { requestsRoot: invalidRequestsRoot }, }, - { common } + { common }, ) await expect(() => runBlock(vm, { block })).rejects.toThrow('invalid requestsRoot') }) @@ -90,7 +90,7 @@ describe('EIP 7685 buildBlock tests', () => { }) const genesisBlock = createBlockFromBlockData( { header: { gasLimit: 50000, baseFeePerGas: 100 } }, - { common } + { common }, ) const blockchain = await createBlockchain({ genesisBlock, common, validateConsensus: false }) const vm = await VM.create({ common, blockchain }) diff --git a/packages/vm/test/api/EIPs/eip-7702.spec.ts b/packages/vm/test/api/EIPs/eip-7702.spec.ts index 566dcdc599..bb94ba5226 100644 --- a/packages/vm/test/api/EIPs/eip-7702.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7702.spec.ts @@ -62,7 +62,7 @@ async function runTest( authorizationListOpts: GetAuthListOpts[], expect: Uint8Array, vm?: VM, - skipEmptyCode?: boolean + skipEmptyCode?: boolean, ) { vm = vm ?? (await VM.create({ common })) const authList = authorizationListOpts.map((opt) => getAuthorizationListItem(opt)) @@ -74,7 +74,7 @@ async function runTest( to: defaultAuthAddr, value: BIGINT_1, }, - { common } + { common }, ).sign(defaultSenderPkey) const code1 = hexToBytes('0x600160015500') @@ -109,7 +109,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code1Addr, }, ], - new Uint8Array([1]) + new Uint8Array([1]), ) // Try to set code to two different addresses @@ -123,7 +123,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code2Addr, }, ], - new Uint8Array([1]) + new Uint8Array([1]), ) // Chain id check: is chain id 1 also valid? @@ -138,7 +138,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code2Addr, }, ], - new Uint8Array([2]) + new Uint8Array([2]), ) // Check if chain id 2 is ignored @@ -152,7 +152,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code2Addr, }, ], - new Uint8Array([2]) + new Uint8Array([2]), ) // Check if nonce is ignored in case the nonce is incorrect @@ -166,7 +166,7 @@ describe('EIP 7702: set code to EOA accounts', () => { address: code2Addr, }, ], - new Uint8Array([2]) + new Uint8Array([2]), ) }) @@ -181,7 +181,7 @@ describe('EIP 7702: set code to EOA accounts', () => { ], new Uint8Array(), vm, - true + true, ) }) @@ -201,7 +201,7 @@ describe('EIP 7702: set code to EOA accounts', () => { // 1x warm call: 100 // Total: 115 const checkAddressWarmCode = hexToBytes( - `0x5F5F5F5F5F73${defaultAuthAddr.toString().slice(2)}5AF1` + `0x5F5F5F5F5F73${defaultAuthAddr.toString().slice(2)}5AF1`, ) const checkAddressWarm = Address.fromString(`0x${'FA'.repeat(20)}`) @@ -215,7 +215,7 @@ describe('EIP 7702: set code to EOA accounts', () => { to: checkAddressWarm, value: BIGINT_1, }, - { common } + { common }, ).sign(defaultSenderPkey) const code1 = hexToBytes('0x') @@ -248,7 +248,7 @@ describe('EIP 7702: set code to EOA accounts', () => { // value: BIGINT_1 // Note, by enabling this line, the account will not get deleted // Therefore, this test will pass }, - { common } + { common }, ).sign(defaultSenderPkey) // Store value 1 in storage slot 1 diff --git a/packages/vm/test/api/bloom.spec.ts b/packages/vm/test/api/bloom.spec.ts index a83323843e..7c52154a50 100644 --- a/packages/vm/test/api/bloom.spec.ts +++ b/packages/vm/test/api/bloom.spec.ts @@ -2,7 +2,7 @@ import * as utils from '@ethereumjs/util' import { bytesToHex, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { Bloom } from '../../src/bloom' +import { Bloom } from '../../src/bloom/index.js' const byteSize = 256 @@ -17,7 +17,7 @@ describe('bloom', () => { () => new Bloom(utils.zeros(byteSize / 2)), /bitvectors must be 2048 bits long/, undefined, - 'should fail for invalid length' + 'should fail for invalid length', ) }) @@ -69,7 +69,7 @@ describe('bloom', () => { bloom.add(hexToBytes('0x0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48')) assert.equal( bytesToHex(bloom.bitvector), - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000081100200000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000002000000000000000004000000000000000000000' + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000081100200000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000002000000000000000004000000000000000000000', ) }) }) diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index 52ca540938..c1519ba2de 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -42,7 +42,7 @@ describe('BlockBuilder', () => { // Set up tx const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) await blockBuilder.addTransaction(tx) @@ -50,7 +50,7 @@ describe('BlockBuilder', () => { assert.equal( blockBuilder.transactionReceipts.length, 1, - 'should have the correct number of tx receipts' + 'should have the correct number of tx receipts', ) const result = await runBlock(vmCopy, { block }) assert.equal(result.gasUsed, block.header.gasUsed) @@ -73,7 +73,7 @@ describe('BlockBuilder', () => { } catch (error: any) { if ( (error.message as string).includes( - 'tx has a higher gas limit than the remaining gas in the block' + 'tx has a higher gas limit than the remaining gas in the block', ) ) { assert.ok(true, 'correct error thrown') @@ -84,7 +84,7 @@ describe('BlockBuilder', () => { assert.equal( blockBuilder.transactionReceipts.length, 0, - 'should have the correct number of tx receipts' + 'should have the correct number of tx receipts', ) }) @@ -112,7 +112,7 @@ describe('BlockBuilder', () => { // Set up tx const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) await blockBuilder.addTransaction(tx) @@ -133,7 +133,7 @@ describe('BlockBuilder', () => { address: new Address(hexToBytes('0x0b90087d864e82a284dca15923f3776de6bb016f')), privateKey: hexToBytes('0x64bf9cc30328b0e42387b3c82c614e6386259136235e20c1357bd11cdee86993'), publicKey: hexToBytes( - '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195' + '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195', ), } @@ -194,7 +194,7 @@ describe('BlockBuilder', () => { const cliqueSigner = signer.privateKey const genesisBlock = createBlockFromBlockData( { header: { gasLimit: 50000, extraData } }, - { common, cliqueSigner } + { common, cliqueSigner }, ) const blockchain = await createBlockchain({ genesisBlock, common }) const vm = await VM.create({ common, blockchain }) @@ -211,7 +211,7 @@ describe('BlockBuilder', () => { // Set up tx const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(signer.privateKey) await blockBuilder.addTransaction(tx) @@ -222,7 +222,7 @@ describe('BlockBuilder', () => { assert.deepEqual( block.header.cliqueSigner(), signer.address, - 'should recover the correct signer address' + 'should recover the correct signer address', ) }) @@ -241,7 +241,7 @@ describe('BlockBuilder', () => { const tx = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) await blockBuilder.addTransaction(tx) @@ -252,7 +252,7 @@ describe('BlockBuilder', () => { assert.equal( blockBuilder.getStatus().status, 'reverted', - 'block should be in reverted status' + 'block should be in reverted status', ) } catch (error: any) { assert.fail('shoud not throw') @@ -262,7 +262,7 @@ describe('BlockBuilder', () => { const tx2 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1, nonce: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) await blockBuilder.addTransaction(tx2) @@ -273,7 +273,7 @@ describe('BlockBuilder', () => { assert.equal( blockBuilder.getStatus().status, 'reverted', - 'block should be in reverted status' + 'block should be in reverted status', ) } catch (error: any) { assert.fail('shoud not throw') @@ -306,7 +306,7 @@ describe('BlockBuilder', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London, eips: [1559] }) const genesisBlock = createBlockFromBlockData( { header: { gasLimit: 50000, baseFeePerGas: 100 } }, - { common } + { common }, ) const blockchain = await createBlockchain({ genesisBlock, common, validateConsensus: false }) const vm = await VM.create({ common, blockchain }) @@ -324,12 +324,12 @@ describe('BlockBuilder', () => { // Set up underpriced txs to test error response const tx1 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) const tx2 = create1559FeeMarketTx( { to: Address.zero(), value: 1000, gasLimit: 21000, maxFeePerGas: 10 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) for (const tx of [tx1, tx2]) { @@ -339,7 +339,7 @@ describe('BlockBuilder', () => { } catch (error: any) { assert.ok( (error.message as string).includes("is less than the block's baseFeePerGas"), - 'should fail with appropriate error' + 'should fail with appropriate error', ) } } @@ -347,12 +347,12 @@ describe('BlockBuilder', () => { // Set up correctly priced txs const tx3 = createLegacyTx( { to: Address.zero(), value: 1000, gasLimit: 21000, gasPrice: 101 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) const tx4 = create1559FeeMarketTx( { to: Address.zero(), value: 1000, gasLimit: 21000, maxFeePerGas: 101, nonce: 1 }, - { common, freeze: false } + { common, freeze: false }, ).sign(privateKey) for (const tx of [tx3, tx4]) { @@ -364,12 +364,12 @@ describe('BlockBuilder', () => { assert.equal( blockBuilder.transactionReceipts.length, 2, - 'should have the correct number of tx receipts' + 'should have the correct number of tx receipts', ) assert.ok( block.header.baseFeePerGas! === genesisBlock.header.calcNextBaseFee(), - "baseFeePerGas should equal parentHeader's calcNextBaseFee" + "baseFeePerGas should equal parentHeader's calcNextBaseFee", ) const result = await runBlock(vmCopy, { block }) diff --git a/packages/vm/test/api/copy.spec.ts b/packages/vm/test/api/copy.spec.ts index 3250cda902..49f74969d5 100644 --- a/packages/vm/test/api/copy.spec.ts +++ b/packages/vm/test/api/copy.spec.ts @@ -1,7 +1,7 @@ import { Address, createAccount } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { setupVM } from './utils' +import { setupVM } from './utils.js' describe('VM Copy Test', () => { it('should pass copy of state manager', async () => { @@ -15,13 +15,13 @@ describe('VM Copy Test', () => { assert.ok( (await vm.stateManager.getAccount(address)) !== undefined, - 'account exists before copy' + 'account exists before copy', ) const vmCopy = await vm.shallowCopy() assert.isUndefined( await vmCopy.stateManager.getAccount(address), - 'non-committed checkpoints will not be copied' + 'non-committed checkpoints will not be copied', ) await vm.stateManager.checkpoint() @@ -31,7 +31,7 @@ describe('VM Copy Test', () => { assert.ok( (await vmCopy2.stateManager.getAccount(address)) !== undefined, - 'committed checkpoints will be copied' + 'committed checkpoints will be copied', ) }) }) diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index f70127f53e..be4387d97a 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -58,7 +58,7 @@ const block = createBlockFromBlockData( }, { common, - } + }, ) const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109') @@ -77,7 +77,7 @@ describe('VM initialized with custom state', () => { }, { common, - } + }, ).sign(privateKey) const result = await runTx(vm, { tx, @@ -95,7 +95,7 @@ describe('VM initialized with custom state', () => { common.setHardfork(Hardfork.London) const vm = await VM.create({ blockchain, common, genesisState }) const sigHash = new Interface(['function retrieve()']).getSighash( - 'retrieve' + 'retrieve', ) as PrefixedHexString const callResult = await vm.evm.runCall({ diff --git a/packages/vm/test/api/events.spec.ts b/packages/vm/test/api/events.spec.ts index 580f3c97c0..9feecc0b46 100644 --- a/packages/vm/test/api/events.spec.ts +++ b/packages/vm/test/api/events.spec.ts @@ -174,7 +174,7 @@ describe('VM events', () => { assert.equal( bytesToHex(emitted.code), - '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3' + '0x7f410000000000000000000000000000000000000000000000000000000000000060005260016000f3', ) }) }) diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index d4b9d7e6a5..074141908f 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -4,14 +4,14 @@ import { Account, Address, KECCAK256_RLP, hexToBytes } from '@ethereumjs/util' import * as util from 'util' // eslint-disable-line @typescript-eslint/no-unused-vars import { assert, describe, it } from 'vitest' -import { VM } from '../../src/vm' +import { VM } from '../../src/vm.js' import * as testnet from './testdata/testnet.json' import * as testnet2 from './testdata/testnet2.json' import * as testnetMerge from './testdata/testnetMerge.json' -import { setupVM } from './utils' +import { setupVM } from './utils.js' -import type { VMOpts } from '../../src' +import type { VMOpts } from '../../src/index.js' import type { ChainConfig } from '@ethereumjs/common' import type { DefaultStateManager } from '@ethereumjs/statemanager' @@ -37,7 +37,7 @@ describe('VM -> basic instantiation / boolean switches', () => { assert.deepEqual( (vm.stateManager as DefaultStateManager)['_trie'].root(), KECCAK256_RLP, - 'it has default trie' + 'it has default trie', ) assert.equal(vm.common.hardfork(), Hardfork.Shanghai, 'it has correct default HF') }) @@ -47,7 +47,7 @@ describe('VM -> basic instantiation / boolean switches', () => { assert.notDeepEqual( (vm.stateManager as DefaultStateManager)['_trie'].root(), KECCAK256_RLP, - 'it has different root' + 'it has different root', ) }) }) @@ -73,7 +73,7 @@ describe('VM -> Default EVM / Custom EVM Opts', () => { const copiedVM = await vm.shallowCopy() assert.isTrue( (copiedVM.evm as EVM).allowUnlimitedContractSize, - 'allowUnlimitedContractSize=true (for shallowCopied VM)' + 'allowUnlimitedContractSize=true (for shallowCopied VM)', ) }) @@ -86,7 +86,7 @@ describe('VM -> Default EVM / Custom EVM Opts', () => { assert.equal( (copiedVM.evm as EVM).common.hardfork(), 'byzantium', - 'use modfied HF from VM common (for shallowCopied VM)' + 'use modfied HF from VM common (for shallowCopied VM)', ) }) @@ -99,7 +99,7 @@ describe('VM -> Default EVM / Custom EVM Opts', () => { assert.equal( (copiedVM.evm as EVM).common.hardfork(), 'byzantium', - 'use modfied HF from evmOpts (for shallowCopied VM)' + 'use modfied HF from evmOpts (for shallowCopied VM)', ) }) }) @@ -218,7 +218,7 @@ describe('VM -> setHardfork, state (deprecated), blockchain', () => { assert.deepEqual( (vm.stateManager as DefaultStateManager)['_trie'].root(), KECCAK256_RLP, - 'it has default trie' + 'it has default trie', ) }) @@ -245,12 +245,12 @@ describe('VM -> setHardfork, state (deprecated), blockchain', () => { assert.deepEqual( (vmCopy as any)._setHardfork, true, - 'copy() correctly passes setHardfork option' + 'copy() correctly passes setHardfork option', ) assert.deepEqual( (vm as any)._setHardfork, (vmCopy as any)._setHardfork, - 'setHardfork options match' + 'setHardfork options match', ) // @@ -263,12 +263,12 @@ describe('VM -> setHardfork, state (deprecated), blockchain', () => { assert.deepEqual( (vmCopy as any)._setHardfork, BigInt(5001), - 'copy() correctly passes setHardfork option' + 'copy() correctly passes setHardfork option', ) assert.deepEqual( (vm as any)._setHardfork, (vmCopy as any)._setHardfork, - 'setHardfork options match' + 'setHardfork options match', ) }) describe('Ensure that precompile activation creates non-empty accounts', () => { diff --git a/packages/vm/test/api/istanbul/eip-1108.spec.ts b/packages/vm/test/api/istanbul/eip-1108.spec.ts index ce7a429b1d..8facba9487 100644 --- a/packages/vm/test/api/istanbul/eip-1108.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1108.spec.ts @@ -45,7 +45,7 @@ describe('Istanbul: EIP-1108 tests', () => { const result = await ECPAIRING({ data: hexToBytes( - '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa' + '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa', ), gasLimit: BigInt(0xffffff), common, @@ -55,7 +55,7 @@ describe('Istanbul: EIP-1108 tests', () => { assert.deepEqual( result.executionGasUsed, BigInt(113000), - 'should use petersburg gas costs (k ^= 2 pairings)' + 'should use petersburg gas costs (k ^= 2 pairings)', ) }) }) diff --git a/packages/vm/test/api/istanbul/eip-2200.spec.ts b/packages/vm/test/api/istanbul/eip-2200.spec.ts index 66a12856c2..dd3b2948c5 100644 --- a/packages/vm/test/api/istanbul/eip-2200.spec.ts +++ b/packages/vm/test/api/istanbul/eip-2200.spec.ts @@ -59,7 +59,7 @@ describe('Istanbul: EIP-2200', () => { await vm.stateManager.putContractStorage( addr, key, - hexToBytes(`0x${testCase.original.toString(16)}`) + hexToBytes(`0x${testCase.original.toString(16)}`), ) } diff --git a/packages/vm/test/api/level.ts b/packages/vm/test/api/level.ts index 88e77b7671..39ba1e1a96 100644 --- a/packages/vm/test/api/level.ts +++ b/packages/vm/test/api/level.ts @@ -18,7 +18,7 @@ export class LevelDB implements DB { * @param leveldb - An abstract-leveldown compliant store */ constructor( - leveldb?: AbstractLevel + leveldb?: AbstractLevel, ) { this._leveldb = leveldb ?? new MemoryLevel(ENCODING_OPTS) } diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 56d7d43f36..0d554e61f5 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -33,8 +33,8 @@ import { keccak256 } from 'ethereum-cryptography/keccak' import { assert, describe, it } from 'vitest' import { runBlock } from '../../src/index.js' -import { VM } from '../../src/vm' -import { getDAOCommon, setupPreConditions } from '../util' +import { VM } from '../../src/vm.js' +import { getDAOCommon, setupPreConditions } from '../util.js' import * as testData from './testdata/blockchain.json' import * as testnet from './testdata/testnet.json' @@ -67,7 +67,7 @@ describe('runBlock() -> successful API parameter usage', async () => { assert.deepEqual( (vm.stateManager as DefaultStateManager)['_trie'].root(), genesis.header.stateRoot, - 'genesis state root should match calculated state root' + 'genesis state root should match calculated state root', ) const res = await runBlock(vm, { @@ -80,7 +80,7 @@ describe('runBlock() -> successful API parameter usage', async () => { assert.equal( res.results[0].totalGasSpent.toString(16), '5208', - 'actual gas used should equal blockHeader gasUsed' + 'actual gas used should equal blockHeader gasUsed', ) } @@ -120,13 +120,13 @@ describe('runBlock() -> successful API parameter usage', async () => { }) const uncleReward = (await vm.stateManager.getAccount( - Address.fromString('0xb94f5374fce5ed0000000097c15331677e6ebf0b') + Address.fromString('0xb94f5374fce5ed0000000097c15331677e6ebf0b'), ))!.balance.toString(16) assert.equal( `0x${uncleReward}`, testData.postState['0xb94f5374fce5ed0000000097c15331677e6ebf0b'].balance, - 'calculated balance should equal postState balance' + 'calculated balance should equal postState balance', ) } @@ -170,7 +170,7 @@ describe('runBlock() -> successful API parameter usage', async () => { }) const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) function getBlock(common: Common): Block { @@ -185,11 +185,11 @@ describe('runBlock() -> successful API parameter usage', async () => { data: '0x600154', // PUSH 01 SLOAD gasLimit: BigInt(100000), }, - { common } + { common }, ).sign(privateKey), ], }, - { common } + { common }, ) } @@ -209,12 +209,12 @@ describe('runBlock() -> successful API parameter usage', async () => { assert.equal( txResultChainstart.results[0].totalGasSpent, BigInt(21000) + BigInt(68) * BigInt(3) + BigInt(3) + BigInt(50), - 'tx charged right gas on chainstart hard fork' + 'tx charged right gas on chainstart hard fork', ) assert.equal( txResultMuirGlacier.results[0].totalGasSpent, BigInt(21000) + BigInt(32000) + BigInt(16) * BigInt(3) + BigInt(3) + BigInt(800), - 'tx charged right gas on muir glacier hard fork' + 'tx charged right gas on muir glacier hard fork', ) }) }) @@ -258,7 +258,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { .catch((e) => { assert.ok( e.message.includes('not found in DB'), - 'block failed validation due to no parent header' + 'block failed validation due to no parent header', ) }) }) @@ -274,7 +274,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { assert.equal( err.message, 'cannot validate header: blockchain has no `validateHeader` method', - 'should error' + 'should error', ) } }) @@ -291,7 +291,7 @@ describe('runBlock() -> API parameter usage/data errors', async () => { const opts = { common: block.common } block.transactions[0] = new LegacyTransaction( { nonce, gasPrice, gasLimit, to, value, data, v, r, s }, - opts + opts, ) await runBlock(vm, { block, skipBlockValidation: true }) @@ -317,14 +317,14 @@ describe('runBlock() -> runtime behavior', async () => { const fundBalance1 = BigInt('0x1111') const accountFunded1 = createAccountWithDefaults(BigInt(0), fundBalance1) const DAOFundedContractAddress1 = new Address( - hexToBytes('0xd4fe7bc31cedb7bfb8a345f31e668033056b2728') + hexToBytes('0xd4fe7bc31cedb7bfb8a345f31e668033056b2728'), ) await vm.stateManager.putAccount(DAOFundedContractAddress1, accountFunded1) const fundBalance2 = BigInt('0x2222') const accountFunded2 = createAccountWithDefaults(BigInt(0), fundBalance2) const DAOFundedContractAddress2 = new Address( - hexToBytes('0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425') + hexToBytes('0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425'), ) await vm.stateManager.putAccount(DAOFundedContractAddress2, accountFunded2) @@ -361,7 +361,7 @@ describe('runBlock() -> runtime behavior', async () => { address: new Address(hexToBytes('0x0b90087d864e82a284dca15923f3776de6bb016f')), privateKey: hexToBytes('0x64bf9cc30328b0e42387b3c82c614e6386259136235e20c1357bd11cdee86993'), publicKey: hexToBytes( - '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195' + '0x40b2ebdf4b53206d2d3d3d59e7e2f13b1ea68305aec71d5d24cefe7f24ecae886d241f9267f04702d7f693655eb7b4aa23f30dcd0c3c5f2b970aad7c8a828195', ), } @@ -369,7 +369,7 @@ describe('runBlock() -> runtime behavior', async () => { address: new Address(hexToBytes('0x6f62d8382bf2587361db73ceca28be91b2acb6df')), privateKey: hexToBytes('0x2a6e9ad5a6a8e4f17149b8bc7128bf090566a11dbd63c30e5a0ee9f161309cd6'), publicKey: hexToBytes( - '0xca0a55f6e81cb897aee6a1c390aa83435c41048faa0564b226cfc9f3df48b73e846377fb0fd606df073addc7bd851f22547afbbdd5c3b028c91399df802083a2' + '0xca0a55f6e81cb897aee6a1c390aa83435c41048faa0564b226cfc9f3df48b73e846377fb0fd606df073addc7bd851f22547afbbdd5c3b028c91399df802083a2', ), } @@ -377,13 +377,13 @@ describe('runBlock() -> runtime behavior', async () => { await vm.stateManager.putAccount(otherUser.address, new Account(BigInt(0), BigInt(42000))) const tx = createLegacyTx( { to: Address.zero(), gasLimit: 21000, gasPrice: 1 }, - { common } + { common }, ).sign(otherUser.privateKey) // create block with the signer and txs const block = createBlockFromBlockData( { header: { extraData: new Uint8Array(97) }, transactions: [tx, tx] }, - { common, cliqueSigner: signer.privateKey } + { common, cliqueSigner: signer.privateKey }, ) await runBlock(vm, { block, skipNonce: true, skipBlockValidation: true, generate: true }) @@ -391,14 +391,14 @@ describe('runBlock() -> runtime behavior', async () => { assert.equal( account!.balance, BigInt(42000), - 'beneficiary balance should equal the cost of the txs' + 'beneficiary balance should equal the cost of the txs', ) }) }) async function runBlockAndGetAfterBlockEvent( vm: VM, - runBlockOpts: RunBlockOpts + runBlockOpts: RunBlockOpts, ): Promise { let results: AfterBlockEvent function handler(event: AfterBlockEvent) { @@ -464,14 +464,14 @@ describe('runBlock() -> API return values', () => { assert.equal( (res.receipts[0] as PostByzantiumTxReceipt).status, 1, - 'should return correct post-Byzantium receipt format' + 'should return correct post-Byzantium receipt format', ) res = await runWithHf('spuriousDragon') assert.deepEqual( (res.receipts[0] as PreByzantiumTxReceipt).stateRoot, hexToBytes('0x4477e2cfaf9fd2eed4f74426798b55d140f6a9612da33413c4745f57d7a97fcc'), - 'should return correct pre-Byzantium receipt format' + 'should return correct pre-Byzantium receipt format', ) }) }) @@ -504,7 +504,7 @@ describe('runBlock() -> tx types', async () => { res.receipts .map((r) => r.cumulativeBlockGasUsed) .reduce((prevValue: bigint, currValue: bigint) => prevValue + currValue, BigInt(0)), - "gas used should equal transaction's total gasUsed" + "gas used should equal transaction's total gasUsed", ) } @@ -533,7 +533,7 @@ describe('runBlock() -> tx types', async () => { const tx = create2930AccessListTx( { gasLimit: 53000, value: 1, v: 1, r: 1, s: 1 }, - { common, freeze: false } + { common, freeze: false }, ) tx.getSenderAddress = () => { @@ -552,7 +552,7 @@ describe('runBlock() -> tx types', async () => { const tx = create1559FeeMarketTx( { maxFeePerGas: 10, maxPriorityFeePerGas: 4, gasLimit: 100000, value: 6 }, - { common, freeze: false } + { common, freeze: false }, ) tx.getSenderAddress = () => { @@ -645,7 +645,7 @@ describe('runBlock() -> tx types', async () => { to: defaultAuthAddr, value: BIGINT_1, }, - { common } + { common }, ).sign(defaultSenderPkey) const tx2 = create7702EOACodeTx( { @@ -657,13 +657,13 @@ describe('runBlock() -> tx types', async () => { value: BIGINT_1, nonce: 1, }, - { common } + { common }, ).sign(defaultSenderPkey) const block = createBlockFromBlockData( { transactions: [tx1, tx2], }, - { common, setHardfork: false, skipConsensusFormatValidation: true } + { common, setHardfork: false, skipConsensusFormatValidation: true }, ) await runBlock(vm, { block, skipBlockValidation: true, generate: true }) diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index dd716efc46..f3b6920f11 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -60,7 +60,7 @@ describe('runTx() -> successful API parameter usage', async () => { // Setup block with correct extraData for POA block = createBlockFromBlockData( { header: { extraData: new Uint8Array(97) } }, - { common: vm.common } + { common: vm.common }, ) } @@ -117,7 +117,7 @@ describe('runTx() -> successful API parameter usage', async () => { assert.equal( (e as Error).message.includes('block has a different hardfork than the vm'), true, - 'block has a different hardfork than the vm' + 'block has a different hardfork than the vm', ) assert.ok(true, 'vm/tx mismatched hardfork correctly failed') } @@ -131,7 +131,7 @@ describe('runTx() -> successful API parameter usage', async () => { assert.equal( (e as Error).message.includes('block has a different hardfork than the vm'), true, - 'block has a different hardfork than the vm' + 'block has a different hardfork than the vm', ) assert.ok(true, 'vm/tx mismatched hardfork correctly failed') } @@ -177,7 +177,7 @@ describe('runTx() -> successful API parameter usage', async () => { assert.equal( res.receipt.cumulativeBlockGasUsed, blockGasUsed + res.totalGasSpent, - 'receipt.gasUsed should equal block gas used + tx gas used' + 'receipt.gasUsed should equal block gas used + tx gas used', ) }) @@ -194,7 +194,7 @@ describe('runTx() -> successful API parameter usage', async () => { const res = await runTx(vm, { tx }) assert.isTrue( res.totalGasSpent > BigInt(0), - `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})` + `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})`, ) }) @@ -203,7 +203,7 @@ describe('runTx() -> successful API parameter usage', async () => { const vm = await VM.create({ common }) const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) const address = Address.fromPrivateKey(privateKey) const initialBalance = BigInt(10) ** BigInt(18) @@ -211,7 +211,7 @@ describe('runTx() -> successful API parameter usage', async () => { const account = await vm.stateManager.getAccount(address) await vm.stateManager.putAccount( address, - createAccount({ ...account, balance: initialBalance }) + createAccount({ ...account, balance: initialBalance }), ) const transferCost = 21000 @@ -225,7 +225,7 @@ describe('runTx() -> successful API parameter usage', async () => { maxPriorityFeePerGas: 50, maxFeePerGas: 50, } as TypedTxData, - { common } + { common }, ) const tx = unsignedTx.sign(privateKey) @@ -238,7 +238,7 @@ describe('runTx() -> successful API parameter usage', async () => { baseFeePerGas: 7, }, }, - { common } + { common }, ) const result = await runTx(vm, { @@ -264,13 +264,13 @@ describe('runTx() -> successful API parameter usage', async () => { assert.equal( coinbaseAccount!.balance, expectedCoinbaseBalance, - `should use custom block (${txType.name})` + `should use custom block (${txType.name})`, ) assert.equal( result.execResult.exceptionError, undefined, - `should run ${txType.name} without errors` + `should run ${txType.name} without errors`, ) } }) @@ -284,7 +284,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const tx = getTransaction( new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }), 1, - true + true, ) const caller = tx.getSenderAddress() @@ -298,7 +298,7 @@ describe('runTx() -> API parameter usage/data errors', () => { } catch (e: any) { assert.ok( e.message.includes('(EIP-2718) not activated'), - `should fail for ${TRANSACTION_TYPES[1].name}` + `should fail for ${TRANSACTION_TYPES[1].name}`, ) } }) @@ -315,7 +315,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const res = await runTx(vm, { tx, reportAccessList: true }) assert.isTrue( res.totalGasSpent > BigInt(0), - `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})` + `mainnet (PoW), istanbul HF, default SM - should run without errors (${TRANSACTION_TYPES[0].name})`, ) assert.deepEqual(res.accessList, []) }) @@ -349,7 +349,7 @@ describe('runTx() -> API parameter usage/data errors', () => { assert.ok( e.message.includes('not signed') === true || e.message.includes('Invalid Signature') === true, - `should fail for ${txType.name}` + `should fail for ${txType.name}`, ) } } @@ -364,7 +364,7 @@ describe('runTx() -> API parameter usage/data errors', () => { } catch (e: any) { assert.ok( e.message.toLowerCase().includes('enough funds'), - `should fail for ${txType.name}` + `should fail for ${txType.name}`, ) } } @@ -378,7 +378,7 @@ describe('runTx() -> API parameter usage/data errors', () => { const maxCost: bigint = tx.gasLimit * tx.maxFeePerGas await vm.stateManager.putAccount( address, - createAccountWithDefaults(BigInt(0), maxCost - BigInt(1)) + createAccountWithDefaults(BigInt(0), maxCost - BigInt(1)), ) try { await runTx(vm, { tx }) @@ -386,7 +386,7 @@ describe('runTx() -> API parameter usage/data errors', () => { } catch (e: any) { assert.ok( e.message.toLowerCase().includes('max cost'), - `should fail if max cost exceeds balance` + `should fail if max cost exceeds balance`, ) } // set sufficient balance @@ -445,7 +445,7 @@ describe('runTx() -> API parameter usage/data errors', () => { } catch (e: any) { assert.ok( e.message.includes("is less than the block's baseFeePerGas"), - 'should fail with appropriate error' + 'should fail with appropriate error', ) } } @@ -458,7 +458,7 @@ describe('runTx() -> runtime behavior', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin }) const vm = await VM.create({ common }) const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) /* Code which is deployed here: PUSH1 01 @@ -472,7 +472,7 @@ describe('runTx() -> runtime behavior', () => { await vm.stateManager.putContractStorage( address, hexToBytes(`0x${'00'.repeat(32)}`), - hexToBytes(`0x${'00'.repeat(31)}01`) + hexToBytes(`0x${'00'.repeat(31)}01`), ) const txParams: any = { nonce: '0x00', @@ -494,7 +494,7 @@ describe('runTx() -> runtime behavior', () => { assert.equal( (vm.stateManager).originalStorageCache.map.size, 0, - `should clear storage cache after every ${txType.name}` + `should clear storage cache after every ${txType.name}`, ) } }) @@ -518,12 +518,12 @@ describe('runTx() -> runtime errors', () => { assert.equal( res.execResult!.exceptionError!.error, 'value overflow', - `result should have 'value overflow' error set (${txType.name})` + `result should have 'value overflow' error set (${txType.name})`, ) assert.equal( (vm.stateManager)._checkpointCount, 0, - `checkpoint count should be 0 (${txType.name})` + `checkpoint count should be 0 (${txType.name})`, ) } }) @@ -546,12 +546,12 @@ describe('runTx() -> runtime errors', () => { assert.equal( res.execResult!.exceptionError!.error, 'value overflow', - `result should have 'value overflow' error set (${txType.name})` + `result should have 'value overflow' error set (${txType.name})`, ) assert.equal( (vm.stateManager)._checkpointCount, 0, - `checkpoint count should be 0 (${txType.name})` + `checkpoint count should be 0 (${txType.name})`, ) } }) @@ -572,17 +572,17 @@ describe('runTx() -> API return values', () => { assert.equal( res.execResult.executionGasUsed, BigInt(0), - `execution result -> gasUsed -> 0 (${txType.name})` + `execution result -> gasUsed -> 0 (${txType.name})`, ) assert.equal( res.execResult.exceptionError, undefined, - `execution result -> exception error -> undefined (${txType.name})` + `execution result -> exception error -> undefined (${txType.name})`, ) assert.deepEqual( res.execResult.returnValue, Uint8Array.from([]), - `execution result -> return value -> empty Uint8Array (${txType.name})` + `execution result -> return value -> empty Uint8Array (${txType.name})`, ) assert.equal(res.gasRefund, BigInt(0), `gasRefund -> 0 (${txType.name})`) } @@ -602,7 +602,7 @@ describe('runTx() -> API return values', () => { assert.equal( res.totalGasSpent, tx.getIntrinsicGas(), - `runTx result -> gasUsed -> tx.getIntrinsicGas() (${txType.name})` + `runTx result -> gasUsed -> tx.getIntrinsicGas() (${txType.name})`, ) if (tx instanceof FeeMarketEIP1559Transaction) { const baseFee = BigInt(7) @@ -614,35 +614,35 @@ describe('runTx() -> API return values', () => { assert.equal( res.amountSpent, res.totalGasSpent * gasPrice, - `runTx result -> amountSpent -> gasUsed * gasPrice (${txType.name})` + `runTx result -> amountSpent -> gasUsed * gasPrice (${txType.name})`, ) } else { assert.equal( res.amountSpent, res.totalGasSpent * (tx).gasPrice, - `runTx result -> amountSpent -> gasUsed * gasPrice (${txType.name})` + `runTx result -> amountSpent -> gasUsed * gasPrice (${txType.name})`, ) } assert.deepEqual( res.bloom.bitvector, hexToBytes(`0x${'00'.repeat(256)}`), - `runTx result -> bloom.bitvector -> should be empty (${txType.name})` + `runTx result -> bloom.bitvector -> should be empty (${txType.name})`, ) assert.equal( res.receipt.cumulativeBlockGasUsed, res.totalGasSpent, - `runTx result -> receipt.gasUsed -> result.gasUsed (${txType.name})` + `runTx result -> receipt.gasUsed -> result.gasUsed (${txType.name})`, ) assert.deepEqual( res.receipt.bitvector, res.bloom.bitvector, - `runTx result -> receipt.bitvector -> result.bloom.bitvector (${txType.name})` + `runTx result -> receipt.bitvector -> result.bloom.bitvector (${txType.name})`, ) assert.deepEqual( res.receipt.logs, [], - `runTx result -> receipt.logs -> empty array (${txType.name})` + `runTx result -> receipt.logs -> empty array (${txType.name})`, ) } }) @@ -726,7 +726,7 @@ describe('runTx() -> consensus bugs', () => { assert.equal( result.totalGasSpent, BigInt(66382), - 'should use the right amount of gas and not consume all' + 'should use the right amount of gas and not consume all', ) }) }) @@ -751,7 +751,7 @@ describe('runTx() -> RunTxOptions', () => { } catch (err: any) { assert.ok( err.message.includes('value field cannot be negative'), - 'throws on negative call value' + 'throws on negative call value', ) } } @@ -781,7 +781,7 @@ it('runTx() -> skipBalance behavior', async () => { assert.equal( afterTxBalance, balance !== undefined ? balance - 1n : BigInt(0), - `sender balance should be >= 0 after transaction with skipBalance` + `sender balance should be >= 0 after transaction with skipBalance`, ) assert.equal(res.execResult.exceptionError, undefined, 'no exceptionError with skipBalance') } @@ -847,7 +847,7 @@ it('Validate CALL does not charge new account gas when calling CALLER and caller assert.equal( (await runTx(vm, { tx, skipHardForkValidation: true })).totalGasSpent, BigInt(27818), - 'did not charge callNewAccount' + 'did not charge callNewAccount', ) }) @@ -878,7 +878,7 @@ it('Validate SELFDESTRUCT does not charge new account gas when calling CALLER an assert.equal( (await runTx(vm, { tx, skipHardForkValidation: true })).totalGasSpent, BigInt(13001), - 'did not charge callNewAccount' + 'did not charge callNewAccount', ) }) @@ -909,13 +909,13 @@ describe('EIP 4844 transaction tests', () => { { common, skipConsensusFormatValidation: true, - } + }, ), }, { common, skipConsensusFormatValidation: true, - } + }, ) } const blockchain = await createBlockchain({ @@ -937,10 +937,10 @@ describe('EIP 4844 transaction tests', () => { { common, skipConsensusFormatValidation: true, - } + }, ), }, - { common, skipConsensusFormatValidation: true } + { common, skipConsensusFormatValidation: true }, ) const res = await runTx(vm, { tx, block, skipBalance: true }) assert.ok(res.execResult.exceptionError === undefined, 'simple blob tx run succeeds') diff --git a/packages/vm/test/api/state/accountExists.spec.ts b/packages/vm/test/api/state/accountExists.spec.ts index 8e3da9c557..71ddc7c518 100644 --- a/packages/vm/test/api/state/accountExists.spec.ts +++ b/packages/vm/test/api/state/accountExists.spec.ts @@ -30,14 +30,14 @@ describe('correctly apply new account gas fee on pre-Spurious Dragon hardforks', await vm.stateManager.putContractStorage( contractAddress, hexToBytes('0xd08f588b94e47566eea77acec87441cecca23f61aea9ed8eb086c062d3837605'), - hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001') + hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001'), ) // setup the call arguments const runCallArgs = { caller, // call address gasLimit: BigInt(174146 - 22872), // tx gas limit minus the tx fee (21000) and data fee (1872) to represent correct gas costs data: hexToBytes( - '0xa9059cbb000000000000000000000000f48a1bdc65d9ccb4b569ffd4bffff415b90783d60000000000000000000000000000000000000000000000000000000000000001' + '0xa9059cbb000000000000000000000000f48a1bdc65d9ccb4b569ffd4bffff415b90783d60000000000000000000000000000000000000000000000000000000000000001', ), to: contractAddress, // call to the contract address value: BigInt(0), @@ -47,7 +47,7 @@ describe('correctly apply new account gas fee on pre-Spurious Dragon hardforks', assert.equal( result.execResult.executionGasUsed, BigInt(53552), - 'vm correctly applies new account gas price' + 'vm correctly applies new account gas price', ) }) }) @@ -73,20 +73,20 @@ describe('do not apply new account gas fee for empty account in DB on pre-Spurio const emptyAccount = (await vm.stateManager.getAccount(emptyAddress)) as Account await (vm.stateManager as DefaultStateManager)['_trie'].put( toBytes(emptyAddress), - emptyAccount.serialize() + emptyAccount.serialize(), ) await vm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code await vm.stateManager.putContractStorage( contractAddress, hexToBytes('0xd08f588b94e47566eea77acec87441cecca23f61aea9ed8eb086c062d3837605'), - hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001') + hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001'), ) // setup the call arguments const runCallArgs = { caller, // call address gasLimit: BigInt(174146 - 22872), // tx gas limit minus the tx fee (21000) and data fee (1872) to represent correct gas costs data: hexToBytes( - '0xa9059cbb000000000000000000000000f48a1bdc65d9ccb4b569ffd4bffff415b90783d60000000000000000000000000000000000000000000000000000000000000001' + '0xa9059cbb000000000000000000000000f48a1bdc65d9ccb4b569ffd4bffff415b90783d60000000000000000000000000000000000000000000000000000000000000001', ), to: contractAddress, // call to the contract address value: BigInt(0), @@ -96,7 +96,7 @@ describe('do not apply new account gas fee for empty account in DB on pre-Spurio assert.equal( result.execResult.executionGasUsed, BigInt(28552), - 'new account price not applied as empty account exists' + 'new account price not applied as empty account exists', ) }) }) diff --git a/packages/vm/test/api/tester/tester.config.spec.ts b/packages/vm/test/api/tester/tester.config.spec.ts index fe478b233e..1513b3c7c5 100644 --- a/packages/vm/test/api/tester/tester.config.spec.ts +++ b/packages/vm/test/api/tester/tester.config.spec.ts @@ -1,7 +1,7 @@ import { Hardfork } from '@ethereumjs/common' import { assert, describe, it } from 'vitest' -import { getCommon } from '../../tester/config' +import { getCommon } from '../../tester/config.js' describe('bloom', () => { it('should initialize common with the right hardfork', () => { diff --git a/packages/vm/test/api/utils.ts b/packages/vm/test/api/utils.ts index 3e88786b3c..ebcea00bb4 100644 --- a/packages/vm/test/api/utils.ts +++ b/packages/vm/test/api/utils.ts @@ -9,11 +9,11 @@ import { } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' -import { VM } from '../../src/vm' +import { VM } from '../../src/vm.js' -import { LevelDB } from './level' +import { LevelDB } from './level.js' -import type { VMOpts } from '../../src/types' +import type { VMOpts } from '../../src/types.js' import type { Block } from '@ethereumjs/block' import type { Common } from '@ethereumjs/common' import type { Address } from '@ethereumjs/util' @@ -53,7 +53,7 @@ export function getTransaction( sign = false, value = '0x00', createContract = false, - nonce = 0 + nonce = 0, ) { let to: string | undefined = '0x0000000000000000000000000000000000000000' let data = '0x7f7465737432000000000000000000000000000000000000000000000000000000600057' @@ -105,11 +105,11 @@ export function getTransaction( txParams['kzgProofs'] = txParams['blobs'].map((blob: Uint8Array, ctx: number) => common.customCrypto!.kzg!.computeBlobKzgProof( blob, - txParams['kzgCommitments'][ctx] as Uint8Array - ) + txParams['kzgCommitments'][ctx] as Uint8Array, + ), ) txParams['blobVersionedHashes'] = txParams['kzgCommitments'].map((commitment: Uint8Array) => - computeVersionedHash(commitment, 0x1) + computeVersionedHash(commitment, 0x1), ) } @@ -117,7 +117,7 @@ export function getTransaction( if (sign) { const privateKey = hexToBytes( - '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109' + '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) return tx.sign(privateKey) } diff --git a/packages/vm/test/tester/config.ts b/packages/vm/test/tester/config.ts index 3aa1f00701..42eff75264 100644 --- a/packages/vm/test/tester/config.ts +++ b/packages/vm/test/tester/config.ts @@ -224,7 +224,7 @@ function setupCommonWithNetworks(network: string, ttd?: number, timestamp?: numb // normal hard fork, return the common with this hard fork // find the right upper/lowercased version const hfName = normalHardforks.reduce((previousValue, currentValue) => - currentValue.toLowerCase() === networkLowercase ? currentValue : previousValue + currentValue.toLowerCase() === networkLowercase ? currentValue : previousValue, ) const mainnetCommon = new Common({ chain: Chain.Mainnet, hardfork: hfName }) const hardforks = mainnetCommon.hardforks() @@ -270,7 +270,7 @@ function setupCommonWithNetworks(network: string, ttd?: number, timestamp?: numb hardforks: testHardforks, defaultHardfork: hfName, }, - { eips: [3607], customCrypto: { kzg } } + { eips: [3607], customCrypto: { kzg } }, ) // Activate EIPs const eips = network.match(/(?<=\+)(.\d+)/g) @@ -358,7 +358,7 @@ export function getCommon(network: string, kzg?: Kzg): Common { hardfork: transitionForks.startFork, eips: [3607], customCrypto: { kzg }, - } + }, ) return common } @@ -422,7 +422,7 @@ const expectedTestsFull: { */ export function getExpectedTests( fork: string, - name: 'BlockchainTests' | 'GeneralStateTests' + name: 'BlockchainTests' | 'GeneralStateTests', ): number | undefined { if (expectedTestsFull[name] === undefined) { return diff --git a/packages/vm/test/tester/index.ts b/packages/vm/test/tester/index.ts index 060f37f3e6..864c22eaac 100755 --- a/packages/vm/test/tester/index.ts +++ b/packages/vm/test/tester/index.ts @@ -15,10 +15,10 @@ import { getRequiredForkConfigAlias, getSkipTests, getTestDirs, -} from './config' -import { runBlockchainTest } from './runners/BlockchainTestsRunner' -import { runStateTest } from './runners/GeneralStateTestsRunner' -import { getTestFromSource, getTestsFromArgs } from './testLoader' +} from './config.js' +import { runBlockchainTest } from './runners/BlockchainTestsRunner.js' +import { runStateTest } from './runners/GeneralStateTestsRunner.js' +import { getTestFromSource, getTestsFromArgs } from './testLoader.js' import type { Common } from '@ethereumjs/common' import type { EVMBLSInterface } from '@ethereumjs/evm/dist/cjs/types' @@ -169,8 +169,8 @@ async function runTests() { argv['verify-test-amount-alltests'] > 0 ? getExpectedTests(FORK_CONFIG_VM, name) : argv['expected-test-amount'] !== undefined && argv['expected-test-amount'] > 0 - ? argv['expected-test-amount'] - : undefined + ? argv['expected-test-amount'] + : undefined /** * Initialization output to console @@ -186,7 +186,7 @@ async function runTests() { .filter(([_k, v]) => typeof v === 'string' || (Array.isArray(v) && v.length !== 0)) .map(([k, v]) => ({ [k]: Array.isArray(v) && v.length > 0 ? v.length : v, - })) + })), ) } const formattedGetterArgs = formatArgs(testGetterArgs) @@ -268,7 +268,7 @@ async function runTests() { await runner(runnerArgs, test, t) } }, - testGetterArgs + testGetterArgs, ) .then(() => { resolve() diff --git a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts index 10af87c5cb..15d2a4c1b0 100644 --- a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts +++ b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts @@ -110,7 +110,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes t.deepEquals( await vm.stateManager.getStateRoot(), genesisBlock.header.stateRoot, - 'correct pre stateRoot' + 'correct pre stateRoot', ) async function handleError(error: string | undefined, expectException: string | boolean) { @@ -245,7 +245,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes t.equal( bytesToHex((blockchain as any)._headHeaderHash), '0x' + testData.lastblockhash, - 'correct last header block' + 'correct last header block', ) const end = Date.now() diff --git a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts index 94f70a2007..1c592cd73f 100644 --- a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts +++ b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts @@ -15,7 +15,7 @@ function parseTestCases( testData: any, data: string | undefined, gasLimit: string | undefined, - value: string | undefined + value: string | undefined, ) { let testCases = [] @@ -183,7 +183,7 @@ export async function runStateTest(options: any, testData: any, t: tape.Test) { testData, options.data, options.gasLimit, - options.value + options.value, ) if (testCases.length === 0) { t.comment(`No ${options.forkConfigTestSuite} post state defined, skip test`) diff --git a/packages/vm/test/tester/testLoader.ts b/packages/vm/test/tester/testLoader.ts index 35d96be47f..a7ad7fb22d 100644 --- a/packages/vm/test/tester/testLoader.ts +++ b/packages/vm/test/tester/testLoader.ts @@ -2,7 +2,7 @@ import * as fs from 'fs' import * as dir from 'node-dir' import * as path from 'path' -import { DEFAULT_TESTS_PATH } from './config' +import { DEFAULT_TESTS_PATH } from './config.js' const falsePredicate = () => false @@ -20,7 +20,7 @@ export async function getTests( fileFilter: RegExp | string[] = /.json$/, skipPredicate: (...args: any[]) => boolean = falsePredicate, directory: string, - excludeDir: RegExp | string[] = [] + excludeDir: RegExp | string[] = [], ): Promise { const options = { match: fileFilter, @@ -38,7 +38,7 @@ export async function getTests( err: Error | undefined, content: string | Uint8Array, fileName: string, - next: Function + next: Function, ) => { if (err) { reject(err) diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 626019ac52..96ed73a1ba 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -125,7 +125,7 @@ export function format(a: any, toZero: boolean = false, isHex: boolean = false): */ export function makeTx( txData: any, - opts?: TxOptions + opts?: TxOptions, ): | EOACodeEIP7702Transaction | BlobEIP4844Transaction @@ -215,7 +215,7 @@ export function verifyAccountPostConditions( address: string, account: Account, acctData: any, - t: tape.Test + t: tape.Test, ) { return new Promise((resolve) => { t.comment('Account: ' + address) @@ -223,12 +223,12 @@ export function verifyAccountPostConditions( t.comment( `Expected balance of ${bytesToBigInt(format(acctData.balance, true))}, but got ${ account.balance - }` + }`, ) } if (!equalsBytes(format(account.nonce, true), format(acctData.nonce, true))) { t.comment( - `Expected nonce of ${bytesToBigInt(format(acctData.nonce, true))}, but got ${account.nonce}` + `Expected nonce of ${bytesToBigInt(format(acctData.nonce, true))}, but got ${account.nonce}`, ) } @@ -258,7 +258,7 @@ export function verifyAccountPostConditions( t.comment( `Expected storage key ${bytesToHex(data.key)} at address ${address} to have value ${ hashedStorage[key] ?? '0x' - }, but got ${val}}` + }, but got ${val}}`, ) } delete hashedStorage[key] @@ -332,7 +332,7 @@ export function makeBlockHeader(data: any, opts?: BlockOptions) { gasUsed: parentGasUsed, baseFeePerGas: parentBaseFee, }, - { common: opts.common } + { common: opts.common }, ) headerData['baseFeePerGas'] = parentBlockHeader.calcNextBaseFee() } @@ -429,7 +429,7 @@ export function getDAOCommon(activationBlock: number) { { baseChain: 'mainnet', hardfork: Hardfork.Dao, - } + }, ) return DAOCommon } diff --git a/packages/vm/tsconfig.lint.json b/packages/vm/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/vm/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} diff --git a/packages/wallet/.eslintrc.cjs b/packages/wallet/.eslintrc.cjs index 015c06f88c..38a6d05f92 100644 --- a/packages/wallet/.eslintrc.cjs +++ b/packages/wallet/.eslintrc.cjs @@ -1,14 +1,15 @@ module.exports = { extends: '../../config/eslint.cjs', parserOptions: { - project: ['./tsconfig.json'], + project: ['./tsconfig.lint.json'], }, overrides: [ { - files: ['test/index.spec.ts'], + files: ['test/index.spec.ts', "examples/**/*"], rules: { 'github/array-foreach': 'warn', 'no-prototype-builtins': 'warn', + 'no-console': 'off', }, }, ], diff --git a/packages/wallet/examples/hdKey.js b/packages/wallet/examples/hdKey.cjs similarity index 100% rename from packages/wallet/examples/hdKey.js rename to packages/wallet/examples/hdKey.cjs diff --git a/packages/wallet/examples/hdKey.ts b/packages/wallet/examples/hdKey.ts index a4d99922ec..f33ae1dd20 100644 --- a/packages/wallet/examples/hdKey.ts +++ b/packages/wallet/examples/hdKey.ts @@ -1,6 +1,6 @@ import { hdkey } from '@ethereumjs/wallet' const wallet = hdkey.EthereumHDKey.fromMnemonic( - 'clown galaxy face oxygen birth round modify fame correct stumble kind excess' + 'clown galaxy face oxygen birth round modify fame correct stumble kind excess', ) console.log(wallet.getWallet().getAddressString()) // Should print an Ethereum address diff --git a/packages/wallet/examples/thirdparty.js b/packages/wallet/examples/thirdparty.cjs similarity index 100% rename from packages/wallet/examples/thirdparty.js rename to packages/wallet/examples/thirdparty.cjs diff --git a/packages/wallet/examples/wallet.js b/packages/wallet/examples/wallet.cjs similarity index 100% rename from packages/wallet/examples/wallet.js rename to packages/wallet/examples/wallet.cjs diff --git a/packages/wallet/src/thirdparty.ts b/packages/wallet/src/thirdparty.ts index a47dfbb738..756e3aae15 100644 --- a/packages/wallet/src/thirdparty.ts +++ b/packages/wallet/src/thirdparty.ts @@ -117,7 +117,7 @@ export interface EtherWalletOptions { */ export async function fromEtherWallet( input: string | EtherWalletOptions, - password: string + password: string, ): Promise { const json: EtherWalletOptions = typeof input === 'object' ? input : JSON.parse(input) diff --git a/packages/wallet/src/wallet.ts b/packages/wallet/src/wallet.ts index c778a48a2d..b49cb56c98 100644 --- a/packages/wallet/src/wallet.ts +++ b/packages/wallet/src/wallet.ts @@ -99,7 +99,7 @@ function validateBytes(paramName: string, bytes: Uint8Array, length?: number) { typeof length === 'number' ? `${length * 2}` : 'empty or a non-zero even number of' const howManyBytes = typeof length === 'number' ? ` (${length} bytes)` : '' throw new Error( - `Invalid ${paramName}, must be a string (${howManyHex} hex characters) or Uint8Array${howManyBytes}` + `Invalid ${paramName}, must be a string (${howManyHex} hex characters) or Uint8Array${howManyBytes}`, ) } if (typeof length === 'number' && bytes.length !== length) { @@ -265,7 +265,7 @@ interface EthSaleKeystore { export class Wallet { constructor( private readonly privateKey?: Uint8Array | undefined, - private publicKey: Uint8Array | undefined = undefined + private publicKey: Uint8Array | undefined = undefined, ) { if (privateKey && publicKey) { throw new Error('Cannot supply both a private and a public key to the constructor') @@ -393,7 +393,7 @@ export class Wallet { ciphertext, keccak256(derivedKey.subarray(0, 16)).subarray(0, 16), unprefixedHexToBytes(json.Crypto.IV), - 'aes-128-cbc' + 'aes-128-cbc', ) return new Wallet(seed) } @@ -407,7 +407,7 @@ export class Wallet { public static async fromV3( input: string | V3Keystore, password: string, - nonStrict = false + nonStrict = false, ): Promise { const json: V3Keystore = typeof input === 'object' ? input : JSON.parse(nonStrict ? input.toLowerCase() : input) @@ -433,7 +433,7 @@ export class Wallet { unprefixedHexToBytes(kdfparams.salt), kdfparams.c, kdfparams.dklen, - 'sha256' + 'sha256', ) } else { throw new Error('Unsupported key derivation scheme') @@ -449,7 +449,7 @@ export class Wallet { ciphertext, derivedKey.subarray(0, 16), unprefixedHexToBytes(json.crypto.cipherparams.iv), - json.crypto.cipher + json.crypto.cipher, ) return new Wallet(seed) } @@ -464,7 +464,7 @@ export class Wallet { */ public static async fromEthSale( input: string | EthSaleKeystore, - password: string + password: string, ): Promise { const json: EthSaleKeystore = typeof input === 'object' ? input : JSON.parse(input) @@ -482,7 +482,7 @@ export class Wallet { derivedKey, encseed.subarray(0, 16), 'aes-128-cbc', - true + true, ) const wallet = new Wallet(keccak256(seed)) @@ -587,7 +587,7 @@ export class Wallet { kdfParams.salt, kdfParams.c, kdfParams.dklen, - 'sha256' + 'sha256', ) break case KDFFunctions.Scrypt: @@ -604,7 +604,7 @@ export class Wallet { derivedKey.subarray(0, 16), v3Params.iv, v3Params.cipher, - false + false, ) const mac = keccak256(concatBytes(derivedKey.subarray(16, 32), ciphertext)) diff --git a/packages/wallet/test/hdkey.spec.ts b/packages/wallet/test/hdkey.spec.ts index 5b8a99c40f..7b70f6aa25 100644 --- a/packages/wallet/test/hdkey.spec.ts +++ b/packages/wallet/test/hdkey.spec.ts @@ -5,7 +5,7 @@ import { EthereumHDKey } from '../src/hdkey.js' // from BIP39 mnemonic: awake book subject inch gentle blur grant damage process float month clown const fixtureseed = hexToBytes( - '0x747f302d9c916698912d5f70be53a6cf53bc495803a5523d3a7c3afa2afba94ec3803f838b3e1929ab5481f9da35441372283690fdcf27372c38f40ba134fe03' + '0x747f302d9c916698912d5f70be53a6cf53bc495803a5523d3a7c3afa2afba94ec3803f838b3e1929ab5481f9da35441372283690fdcf27372c38f40ba134fe03', ) const fixturehd = EthereumHDKey.fromMasterSeed(fixtureseed) const fixtureMnemonic = 'awake book subject inch gentle blur grant damage process float month clown' @@ -30,44 +30,44 @@ describe('HD Key tests', () => { it('.privateExtendedKey()', () => { assert.deepEqual( fixturehd.privateExtendedKey(), - 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY' + 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY', ) }, 30000) it('.publicExtendedKey()', () => { assert.deepEqual( fixturehd.publicExtendedKey(), - 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ' + 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ', ) }, 30000) it('.fromExtendedKey()', () => { const onlyPublicExtendedKey = EthereumHDKey.fromExtendedKey( - 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ' + 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ', ) assert.deepEqual( onlyPublicExtendedKey.publicExtendedKey(), - 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ' + 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ', ) assert.throws( function () { onlyPublicExtendedKey.privateExtendedKey() }, /^No private key$/, - 'throws when trying to access private extended key with no private key provided' + 'throws when trying to access private extended key with no private key provided', ) const fullExtendedKey = EthereumHDKey.fromExtendedKey( - 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY' + 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY', ) assert.deepEqual( fullExtendedKey.publicExtendedKey(), 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ', - 'successfully generated key from extended private key' + 'successfully generated key from extended private key', ) assert.deepEqual( fullExtendedKey.privateExtendedKey(), 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY', - 'successfully generated key from extended private key' + 'successfully generated key from extended private key', ) }, 30000) @@ -75,7 +75,7 @@ describe('HD Key tests', () => { const hdnode = fixturehd.deriveChild(1) assert.deepEqual( hdnode.privateExtendedKey(), - 'xprv9vYSvrg3eR5FaKbQE4Ao2vHdyvfFL27aWMyH6X818mKWMsqqQZAN6HmRqYDGDPLArzaqbLExRsxFwtx2B2X2QKkC9uoKsiBNi22tLPKZHNS' + 'xprv9vYSvrg3eR5FaKbQE4Ao2vHdyvfFL27aWMyH6X818mKWMsqqQZAN6HmRqYDGDPLArzaqbLExRsxFwtx2B2X2QKkC9uoKsiBNi22tLPKZHNS', ) }, 30000) @@ -84,27 +84,27 @@ describe('HD Key tests', () => { assert.deepEqual( hdnode1.privateExtendedKey(), 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY', - 'should work with m' + 'should work with m', ) const hdnode2 = fixturehd.derivePath("m/44'/0'/0/1") assert.deepEqual( hdnode2.privateExtendedKey(), 'xprvA1ErCzsuXhpB8iDTsbmgpkA2P8ggu97hMZbAXTZCdGYeaUrDhyR8fEw47BNEgLExsWCVzFYuGyeDZJLiFJ9kwBzGojQ6NB718tjVJrVBSrG', - "should work with m/44'/0'/0/1" + "should work with m/44'/0'/0/1", ) }, 30000) it('.getWallet()', () => { assert.deepEqual( fixturehd.getWallet().getPrivateKeyString(), - '0x26cc9417b89cd77c4acdbe2e3cd286070a015d8e380f9cd1244ae103b7d89d81' + '0x26cc9417b89cd77c4acdbe2e3cd286070a015d8e380f9cd1244ae103b7d89d81', ) assert.deepEqual( fixturehd.getWallet().getPublicKeyString(), - '0x0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1' + '0x0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1', ) const hdnode = EthereumHDKey.fromExtendedKey( - 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ' + 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ', ) assert.throws(function () { hdnode.getWallet().getPrivateKeyString() @@ -112,7 +112,7 @@ describe('HD Key tests', () => { assert.deepEqual( hdnode.getWallet().getPublicKeyString(), '0x0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1', - 'should work with public nodes' + 'should work with public nodes', ) }, 30000) }) diff --git a/packages/wallet/test/index.spec.ts b/packages/wallet/test/index.spec.ts index 96bb85a648..49c386e32c 100644 --- a/packages/wallet/test/index.spec.ts +++ b/packages/wallet/test/index.spec.ts @@ -49,7 +49,7 @@ describe('Wallet tests', () => { it('.getAddress()', () => { assert.deepEqual( bytesToUnprefixedHex(fixtureWallet.getAddress()), - 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c' + 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c', ) }, 30000) @@ -60,7 +60,7 @@ describe('Wallet tests', () => { it('.getChecksumAddressString()', () => { assert.deepEqual( fixtureWallet.getChecksumAddressString(), - '0xB14Ab53E38DA1C172f877DBC6d65e4a1B0474C3c' + '0xB14Ab53E38DA1C172f877DBC6d65e4a1B0474C3c', ) }, 30000) @@ -71,7 +71,7 @@ describe('Wallet tests', () => { assert.deepEqual( fixtureWallet.verifyPublicKey(new Uint8Array(64)), false, - 'should return false if publicKey, privateKey pair is invalid' + 'should return false if publicKey, privateKey pair is invalid', ) }, 30000) @@ -80,32 +80,34 @@ describe('Wallet tests', () => { assert.deepEqual( bytesToUnprefixedHex(Wallet.fromPublicKey(pubKey).getPublicKey()), fixturePublicKey, - '.fromPublicKey() should work' + '.fromPublicKey() should work', ) assert.throws( function () { Wallet.fromPublicKey( - unprefixedHexToBytes('030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d') + unprefixedHexToBytes( + '030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d', + ), ) }, 'Invalid public key', - '.fromPublicKey() should not accept compressed keys in strict mode' + '.fromPublicKey() should not accept compressed keys in strict mode', ) const tmp = unprefixedHexToBytes( - '030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d' + '030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d', ) assert.deepEqual( bytesToUnprefixedHex(Wallet.fromPublicKey(tmp, true).getPublicKey()), '0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1', - '.fromPublicKey() should accept compressed keys in non-strict mode' + '.fromPublicKey() should accept compressed keys in non-strict mode', ) assert.deepEqual( bytesToUnprefixedHex(Wallet.fromPublicKey(pubKey).getAddress()), 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c', - '.getAddress() should work' + '.getAddress() should work', ) assert.throws( @@ -113,7 +115,7 @@ describe('Wallet tests', () => { Wallet.fromPublicKey(pubKey).getPrivateKey() }, 'This is a public key only wallet', - '.getPrivateKey() should fail' + '.getPrivateKey() should fail', ) }, 30000) @@ -123,7 +125,7 @@ describe('Wallet tests', () => { } catch (err: any) { assert.ok( err.message.includes('This is a public key only wallet'), - 'fails to generate V3 when no private key present' + 'fails to generate V3 when no private key present', ) } }, 30000) @@ -133,7 +135,7 @@ describe('Wallet tests', () => { 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY' assert.deepEqual( Wallet.fromExtendedPrivateKey(xprv).getAddressString(), - '0xb800bf5435f67c7ee7d83c3a863269969a57c57c' + '0xb800bf5435f67c7ee7d83c3a863269969a57c57c', ) }, 30000) @@ -142,7 +144,7 @@ describe('Wallet tests', () => { 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ' assert.deepEqual( Wallet.fromExtendedPublicKey(xpub).getAddressString(), - '0xb800bf5435f67c7ee7d83c3a863269969a57c57c' + '0xb800bf5435f67c7ee7d83c3a863269969a57c57c', ) }, 30000) @@ -155,7 +157,7 @@ describe('Wallet tests', () => { assert.equal( BigInt('0x' + addr) <= max, true, - 'should generate an account compatible with ICAP Direct' + 'should generate an account compatible with ICAP Direct', ) }, 30000) @@ -166,7 +168,7 @@ describe('Wallet tests', () => { assert.deepEqual( wallet.getAddress()[1] >>> 4, 0, - 'should generate an account with 000 prefix (object)' + 'should generate an account with 000 prefix (object)', ) wallet = Wallet.generateVanityAddress('^000') @@ -175,14 +177,14 @@ describe('Wallet tests', () => { assert.deepEqual( wallet.getAddress()[1] >>> 4, 0, - 'should generate an account with 000 prefix (string)' + 'should generate an account with 000 prefix (string)', ) }, 30000) it('.getV3Filename()', () => { assert.deepEqual( fixtureWallet.getV3Filename(1457917509265), - 'UTC--2016-03-14T01-05-09.265Z--b14ab53e38da1c172f877dbc6d65e4a1b0474c3c' + 'UTC--2016-03-14T01-05-09.265Z--b14ab53e38da1c172f877dbc6d65e4a1b0474c3c', ) }, 30000) @@ -218,7 +220,7 @@ describe('Wallet tests', () => { acc.add(key) }) return acc - }, new Set()) + }, new Set()), ) const radix = objs.length const numPermus = radix ** keys.length @@ -369,8 +371,8 @@ describe('Wallet tests', () => { } catch (err: any) { assert.ok( err.message.includes( - 'Invalid salt, must be a string (empty or a non-zero even number of hex characters) or Uint8Array' - ) + 'Invalid salt, must be a string (empty or a non-zero even number of hex characters) or Uint8Array', + ), ) } }, 30000) @@ -383,7 +385,7 @@ describe('Wallet tests', () => { assert.equal(salt, w.crypto.kdfparams.salt) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w, pw)).getPrivateKeyString() + (await Wallet.fromV3(w, pw)).getPrivateKeyString(), ) salt = '0x' @@ -392,7 +394,7 @@ describe('Wallet tests', () => { assert.equal('', w.crypto.kdfparams.salt) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w, pw)).getPrivateKeyString() + (await Wallet.fromV3(w, pw)).getPrivateKeyString(), ) salt = unprefixedHexToBytes('') @@ -401,7 +403,7 @@ describe('Wallet tests', () => { assert.equal('', w.crypto.kdfparams.salt) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w, pw)).getPrivateKeyString() + (await Wallet.fromV3(w, pw)).getPrivateKeyString(), ) salt = '' @@ -424,18 +426,18 @@ describe('Wallet tests', () => { salt: '0x' + salt, iv: '0x' + iv, uuid: '0x' + uuid, - } + }, ) assert.deepEqual(salt, JSON.parse(wStr).crypto.kdfparams.salt) assert.deepEqual(JSON.parse(wStr), JSON.parse(wEthersStr.toLowerCase())) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString() + (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString(), ) assert.equal( fixtureWallet.getPrivateKeyString(), - (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey + (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey, ) salt = '0x' @@ -458,18 +460,18 @@ describe('Wallet tests', () => { salt, iv, uuid, - } + }, ) assert.equal('', JSON.parse(wStr).crypto.kdfparams.salt) assert.deepEqual(JSON.parse(wStr), JSON.parse(wEthersStr.toLowerCase())) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString() + (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString(), ) assert.equal( fixtureWallet.getPrivateKeyString(), - (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey + (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey, ) salt = unprefixedHexToBytes('') @@ -490,18 +492,18 @@ describe('Wallet tests', () => { salt, iv, uuid, - } + }, ) assert.equal('', JSON.parse(wStr).crypto.kdfparams.salt) assert.deepEqual(JSON.parse(wStr), JSON.parse(wEthersStr.toLowerCase())) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString() + (await Wallet.fromV3(JSON.parse(wStr), pw)).getPrivateKeyString(), ) assert.equal( fixtureWallet.getPrivateKeyString(), - (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey + (await ethersWallet.fromEncryptedJson(wEthersStr, pw)).privateKey, ) }, 120000) @@ -563,8 +565,8 @@ describe('Wallet tests', () => { } catch (err: any) { assert.ok( err.message.includes( - 'Invalid iv, must be a string (32 hex characters) or Uint8Array (16 bytes)' - ) + 'Invalid iv, must be a string (32 hex characters) or Uint8Array (16 bytes)', + ), ) } }, 30000) @@ -625,8 +627,8 @@ describe('Wallet tests', () => { } catch (err: any) { assert.ok( err.message.includes( - 'Invalid uuid, must be a string (32 hex characters) or Uint8Array (16 bytes)' - ) + 'Invalid uuid, must be a string (32 hex characters) or Uint8Array (16 bytes)', + ), ) } }, 30000) @@ -654,11 +656,11 @@ describe('Wallet tests', () => { assert.equal(w.id, w2.id) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w, pw)).getPrivateKeyString() + (await Wallet.fromV3(w, pw)).getPrivateKeyString(), ) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w2, pw)).getPrivateKeyString() + (await Wallet.fromV3(w2, pw)).getPrivateKeyString(), ) w = await fixtureWallet.toV3(pw, { @@ -679,11 +681,11 @@ describe('Wallet tests', () => { assert.equal(w.id, w2.id) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w, pw)).getPrivateKeyString() + (await Wallet.fromV3(w, pw)).getPrivateKeyString(), ) assert.equal( fixtureWallet.getPrivateKeyString(), - (await Wallet.fromV3(w2, pw)).getPrivateKeyString() + (await Wallet.fromV3(w2, pw)).getPrivateKeyString(), ) }, 60000) @@ -703,11 +705,11 @@ describe('Wallet tests', () => { assert.deepEqual(wallet.getAddressString(), '0x008aeeda4d805471df9b2a5b0f38a0c3bcba786b') assert.deepEqual( wallet.getAddressString(), - (await ethersWallet.fromEncryptedJson(wEthersCompat, pw)).address.toLowerCase() + (await ethersWallet.fromEncryptedJson(wEthersCompat, pw)).address.toLowerCase(), ) assert.deepEqual( walletRandom.getAddressString(), - (await ethersWallet.fromEncryptedJson(wRandom, pw)).address.toLowerCase() + (await ethersWallet.fromEncryptedJson(wRandom, pw)).address.toLowerCase(), ) }, 30000) @@ -722,11 +724,11 @@ describe('Wallet tests', () => { assert.deepEqual(wallet.getAddressString(), '0x2f91eb73a6cd5620d7abb50889f24eea7a6a4feb') assert.deepEqual( wallet.getAddressString(), - (await ethersWallet.fromEncryptedJson(sample, pw)).address.toLowerCase() + (await ethersWallet.fromEncryptedJson(sample, pw)).address.toLowerCase(), ) assert.deepEqual( walletRandom.getAddressString(), - (await ethersWallet.fromEncryptedJson(sampleRandom, pw)).address.toLowerCase() + (await ethersWallet.fromEncryptedJson(sampleRandom, pw)).address.toLowerCase(), ) }) it.skip("should work with 'unencrypted' wallets", async () => { @@ -830,7 +832,7 @@ describe('Wallet tests', () => { assert.equal( wallet.getAddressString(), '0x182b6ca390224c455f11b6337d74119305014ed4', - 'should work with seed text' + 'should work with seed text', ) }, 30000) @@ -845,7 +847,7 @@ describe('Wallet tests', () => { new Wallet(fixturePrivateKeyBuffer, fixturePublicKeyBuffer) }, 'Cannot supply both a private and a public key to the constructor', - 'should fail when both priv and pub key provided' + 'should fail when both priv and pub key provided', ) }, 30000) }) diff --git a/packages/wallet/tsconfig.lint.json b/packages/wallet/tsconfig.lint.json new file mode 100644 index 0000000000..3698f4f0be --- /dev/null +++ b/packages/wallet/tsconfig.lint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../config/tsconfig.lint.json" +} From bf588e25a14f4f9f5b8976dc5abfb58467f2699c Mon Sep 17 00:00:00 2001 From: Scotty <66335769+ScottyPoi@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:11:53 -0600 Subject: [PATCH 21/58] client: change MAX_TXS_EXECUTE default to 200 (#3540) --- packages/client/src/config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/client/src/config.ts b/packages/client/src/config.ts index c20cb6809f..74fa734339 100644 --- a/packages/client/src/config.ts +++ b/packages/client/src/config.ts @@ -388,8 +388,7 @@ export class Config { // engine new payload calls can come in batch of 64, keeping 128 as the lookup factor public static readonly ENGINE_PARENTLOOKUP_MAX_DEPTH = 128 public static readonly ENGINE_NEWPAYLOAD_MAX_EXECUTE = 2 - // currently ethereumjs can execute 200 txs in 12 second window so keeping 1/2 target for blocking response - public static readonly ENGINE_NEWPAYLOAD_MAX_TXS_EXECUTE = 100 + public static readonly ENGINE_NEWPAYLOAD_MAX_TXS_EXECUTE = 200 public static readonly SNAP_AVAILABILITY_DEPTH = BigInt(128) // distance from head at which we can safely transition from a synced snapstate to vmexecution // randomly kept it at 5 for fast testing purposes but ideally should be >=32 slots From 1b881bcb8e888b4fcd14d7699feab58c506458b6 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Fri, 26 Jul 2024 09:29:36 +0200 Subject: [PATCH 22/58] Common: Remove Parameters (#3537) * Separate params from EIP configs * Make requiredEIPs optional * Add internal params dict using params option, add updateParams() and resetParams() methods, add tests * Minor * Move EVM param to EVM parms dict * Fix local Common tests, add params test config * Fix tests and example * Add dedicated params config for Block * Add dedicated params dict for Tx * Add dedicated VM params config * Minor * Remove last params from Common, test fixes * Fully remove params dict from Common * Fixes * Add a consistent params option for tx, block, evm and vm to allow to override the default parameter set * Disallow BigInt in parameter files (simply use string) to avoid deep cloning/serialization problems * Add additional deep copy notes on params option code docs, use deep copy in tests * Lint fixes * Address review comments --- packages/block/src/header.ts | 3 + packages/block/src/index.ts | 1 + packages/block/src/params.ts | 88 ++++ packages/block/src/types.ts | 19 +- packages/block/test/block.spec.ts | 13 +- packages/block/test/eip1559block.spec.ts | 4 +- packages/block/test/eip4844block.spec.ts | 3 + packages/client/src/miner/miner.ts | 2 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 2 + packages/common/examples/common.ts | 5 - packages/common/src/common.ts | 97 ++-- packages/common/src/constructors.ts | 11 +- packages/common/src/eips.ts | 443 ------------------ packages/common/src/types.ts | 36 +- packages/common/test/data/paramsTest.ts | 50 ++ packages/common/test/params.spec.ts | 52 +- packages/evm/examples/decode-opcodes.ts | 5 +- packages/evm/src/evm.ts | 3 + packages/evm/src/index.ts | 1 + packages/evm/src/params.ts | 431 +++++++++++++++++ packages/evm/src/types.ts | 26 +- packages/evm/test/evm.spec.ts | 24 + packages/evm/vite.config.bundler.ts | 2 +- packages/tx/src/1559/tx.ts | 2 + packages/tx/src/2930/tx.ts | 2 + packages/tx/src/4844/tx.ts | 2 + packages/tx/src/7702/tx.ts | 2 + packages/tx/src/baseTransaction.ts | 2 + packages/tx/src/index.ts | 2 + packages/tx/src/legacy/tx.ts | 2 + packages/tx/src/params.ts | 46 ++ packages/tx/src/types.ts | 18 + packages/tx/test/base.spec.ts | 6 + packages/tx/test/eip3860.spec.ts | 3 +- packages/tx/test/typedTxsAndEIP2930.spec.ts | 2 + packages/vm/src/index.ts | 1 + packages/vm/src/params.ts | 92 ++++ packages/vm/src/runTx.ts | 2 +- packages/vm/src/types.ts | 19 +- packages/vm/src/vm.ts | 3 + .../eip-2935-historical-block-hashes.spec.ts | 3 +- packages/vm/test/api/index.spec.ts | 36 +- 42 files changed, 1047 insertions(+), 519 deletions(-) create mode 100644 packages/block/src/params.ts create mode 100644 packages/common/test/data/paramsTest.ts create mode 100644 packages/evm/src/params.ts create mode 100644 packages/evm/test/evm.spec.ts create mode 100644 packages/tx/src/params.ts create mode 100644 packages/vm/src/params.ts diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index 9a8939c001..f8f417362d 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -28,6 +28,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { CLIQUE_EXTRA_SEAL, CLIQUE_EXTRA_VANITY } from './clique.js' import { fakeExponential, valuesArrayToHeaderData } from './helpers.js' +import { paramsBlock } from './params.js' import type { BlockHeaderBytes, BlockOptions, HeaderData, JsonHeader } from './types.js' import type { CliqueConfig } from '@ethereumjs/common' @@ -167,6 +168,8 @@ export class BlockHeader { chain: Chain.Mainnet, // default }) } + this.common.updateParams(opts.params ?? paramsBlock) + this.keccakFunction = this.common.customCrypto.keccak256 ?? keccak256 const skipValidateConsensusFormat = opts.skipConsensusFormatValidation ?? false diff --git a/packages/block/src/index.ts b/packages/block/src/index.ts index a4e2bacd4d..c1a94abb64 100644 --- a/packages/block/src/index.ts +++ b/packages/block/src/index.ts @@ -9,4 +9,5 @@ export { getDifficulty, valuesArrayToHeaderData, } from './helpers.js' +export * from './params.js' export * from './types.js' diff --git a/packages/block/src/params.ts b/packages/block/src/params.ts new file mode 100644 index 0000000000..94472f0eba --- /dev/null +++ b/packages/block/src/params.ts @@ -0,0 +1,88 @@ +import type { ParamsDict } from '@ethereumjs/common' + +export const paramsBlock: ParamsDict = { + /** + * Frontier/Chainstart + */ + 1: { + // gasConfig + minGasLimit: 5000, // Minimum the gas limit may ever be + gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations + targetBlobGasPerBlock: 0, // Base value needed here since called pre-4844 in BlockHeader.calcNextExcessBlobGas() + blobGasPerBlob: 0, + maxblobGasPerBlock: 0, + // format + maxExtraDataSize: 32, // Maximum size extra data may be after Genesis + // pow + minimumDifficulty: 131072, // The minimum that the difficulty may ever be + difficultyBoundDivisor: 2048, // The bound divisor of the difficulty, used in the update calculations + durationLimit: 13, // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not + epochDuration: 30000, // Duration between proof-of-work epochs + timebombPeriod: 100000, // Exponential difficulty timebomb period + difficultyBombDelay: 0, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * Byzantium HF Meta EIP +. */ + 609: { + // pow + difficultyBombDelay: 3000000, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * Constantinope HF Meta EIP +. */ + 1013: { + // pow + difficultyBombDelay: 5000000, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * MuirGlacier HF Meta EIP +. */ + 2384: { + // pow + difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * Fee market change for ETH 1.0 chain +. */ + 1559: { + // gasConfig + baseFeeMaxChangeDenominator: 8, // Maximum base fee change denominator + elasticityMultiplier: 2, // Maximum block gas target elasticity + initialBaseFee: 1000000000, // Initial base fee on first EIP1559 block + }, + /** +. * Difficulty Bomb Delay to December 1st 2021 +. */ + 3554: { + // pow + difficultyBombDelay: 9500000, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * Difficulty Bomb Delay to June 2022 +. */ + 4345: { + // pow + difficultyBombDelay: 10700000, // the amount of blocks to delay the difficulty bomb with + }, + /** +. * Shard Blob Transactions +. */ + 4844: { + // gasConfig + targetBlobGasPerBlock: 393216, // The target blob gas consumed per block + blobGasPerBlob: 131072, // The base fee for blob gas per blob + maxblobGasPerBlock: 786432, // The max blob gas allowable per block + blobGasPriceUpdateFraction: 3338477, // The denominator used in the exponential when calculating a blob gas price + // gasPrices + simplePerBlobGas: 12000, // The basic gas fee for each blob + minBlobGas: 1, // The minimum fee per blob gas + }, + /** + * Delaying Difficulty Bomb to mid-September 2022 + */ + 5133: { + // pow + difficultyBombDelay: 11400000, // the amount of blocks to delay the difficulty bomb with + }, +} diff --git a/packages/block/src/types.ts b/packages/block/src/types.ts index 5935fc6c97..470faed400 100644 --- a/packages/block/src/types.ts +++ b/packages/block/src/types.ts @@ -1,5 +1,5 @@ import type { BlockHeader } from './header.js' -import type { Common } from '@ethereumjs/common' +import type { Common, ParamsDict } from '@ethereumjs/common' import type { JsonRpcTx, JsonTx, TransactionType, TxData } from '@ethereumjs/tx' import type { AddressLike, @@ -46,6 +46,23 @@ export interface BlockOptions { * Default: `false` (HF is set to whatever default HF is set by the {@link Common} instance) */ setHardfork?: boolean | BigIntLike + /** + * Block parameters sorted by EIP can be found in the exported `paramsBlock` dictionary, + * which is internally passed to the associated `@ethereumjs/common` instance which + * manages parameter selection based on the hardfork and EIP settings. + * + * This option allows providing a custom set of parameters. Note that parameters + * get fully overwritten, so you need to extend the default parameter dict + * to provide the full parameter set. + * + * It is recommended to deep-clone the params object for this to avoid side effects: + * + * ```ts + * const params = JSON.parse(JSON.stringify(paramsBlock)) + * params['1']['minGasLimit'] = 3000 // 5000 + * ``` + */ + params?: ParamsDict /** * If a preceding {@link BlockHeader} (usually the parent header) is given the preceding * header will be used to calculate the difficulty for this block and the calculated diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index f58ee611c4..99e821125c 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -18,6 +18,7 @@ import { } from '../src/constructors.js' import { createBlockFromRpc } from '../src/from-rpc.js' import { genTransactionsTrieRoot } from '../src/helpers.js' +import { type Block, type BlockBytes, type JsonRpcBlock, paramsBlock } from '../src/index.js' import * as testDataGenesis from './testdata/genesishashestest.json' import * as testDataFromRpcGoerli from './testdata/testdata-from-rpc-goerli.json' @@ -25,7 +26,6 @@ import * as testDataPreLondon2 from './testdata/testdata_pre-london-2.json' import * as testDataPreLondon from './testdata/testdata_pre-london.json' import * as testnetMerge from './testdata/testnetMerge.json' -import type { Block, BlockBytes, JsonRpcBlock } from '../src/index.js' import type { ChainConfig } from '@ethereumjs/common' import type { NestedUint8Array, PrefixedHexString } from '@ethereumjs/util' @@ -35,9 +35,18 @@ describe('[Block]: block functions', () => { const genesis = createBlockFromBlockData({}, { common }) assert.ok(bytesToHex(genesis.hash()), 'block should initialize') + const params = JSON.parse(JSON.stringify(paramsBlock)) + params['1']['minGasLimit'] = 3000 // 5000 + let block = createBlockFromBlockData({}, { params }) + assert.equal( + block.common.param('minGasLimit'), + BigInt(3000), + 'should use custom parameters provided', + ) + // test default freeze values // also test if the options are carried over to the constructor - let block = createBlockFromBlockData({}) + block = createBlockFromBlockData({}) assert.ok(Object.isFrozen(block), 'block should be frozen by default') block = createBlockFromBlockData({}, { freeze: false }) diff --git a/packages/block/test/eip1559block.spec.ts b/packages/block/test/eip1559block.spec.ts index 0bf4b8bed5..43cbc2e90c 100644 --- a/packages/block/test/eip1559block.spec.ts +++ b/packages/block/test/eip1559block.spec.ts @@ -5,15 +5,17 @@ import { assert, describe, it } from 'vitest' import { createBlockFromBlockData } from '../src/constructors.js' import { BlockHeader } from '../src/header.js' - // Test data from Besu (retrieved via Discord) // Older version at https://github.com/abdelhamidbakhta/besu/blob/bf54b6c0b40d3015fc85ff9b078fbc26592d80c0/ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/core/fees/basefee-test.json +import { paramsBlock } from '../src/params.js' + import * as eip1559BaseFee from './testdata/eip1559baseFee.json' const common = new Common({ eips: [1559], chain: Chain.Mainnet, hardfork: Hardfork.London, + params: paramsBlock, }) const genesis = createBlockFromBlockData({}) diff --git a/packages/block/test/eip4844block.spec.ts b/packages/block/test/eip4844block.spec.ts index de2a01234a..6f05554d43 100644 --- a/packages/block/test/eip4844block.spec.ts +++ b/packages/block/test/eip4844block.spec.ts @@ -12,6 +12,7 @@ import { assert, beforeAll, describe, it } from 'vitest' import { createBlockFromBlockData } from '../src/constructors.js' import { BlockHeader } from '../src/header.js' import { fakeExponential, getNumBlobs } from '../src/helpers.js' +import { paramsBlock } from '../src/params.js' import gethGenesis from './testdata/4844-hardfork.json' @@ -105,6 +106,7 @@ describe('blob gas tests', () => { common = createCommonFromGethGenesis(gethGenesis, { chain: 'customChain', hardfork: Hardfork.Cancun, + params: paramsBlock, customCrypto: { kzg }, }) blobGasPerBlob = common.param('blobGasPerBlob') @@ -162,6 +164,7 @@ describe('transaction validation tests', () => { common = createCommonFromGethGenesis(gethGenesis, { chain: 'customChain', hardfork: Hardfork.Cancun, + params: paramsBlock, customCrypto: { kzg }, }) blobGasPerBlob = common.param('blobGasPerBlob') diff --git a/packages/client/src/miner/miner.ts b/packages/client/src/miner/miner.ts index a5ff3f719a..5f898b2f8e 100644 --- a/packages/client/src/miner/miner.ts +++ b/packages/client/src/miner/miner.ts @@ -260,7 +260,7 @@ export class Miner { number === londonHardforkBlock ) { // Get baseFeePerGas from `paramByEIP` since 1559 not currently active on common - baseFeePerGas = this.config.chainCommon.paramByEIP('initialBaseFee', 1559) ?? BIGINT_0 + baseFeePerGas = vmCopy.common.paramByEIP('initialBaseFee', 1559) ?? BIGINT_0 // Set initial EIP1559 block gas limit to 2x parent gas limit per logic in `block.validateGasLimit` gasLimit = gasLimit * BIGINT_2 } else if (this.config.chainCommon.isActivatedEIP(1559)) { diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index 3ead5e1ff6..e49108903f 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -1,3 +1,4 @@ +import { paramsBlock } from '@ethereumjs/block' import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' import { createTxFromTxData } from '@ethereumjs/tx' import { @@ -250,6 +251,7 @@ describe(method, () => { eips: [1559], chain: CommonChain.Mainnet, hardfork: Hardfork.London, + params: paramsBlock, }) const initialBaseFee = common.param('initialBaseFee') diff --git a/packages/common/examples/common.ts b/packages/common/examples/common.ts index 272f3005a0..cfc933c0c9 100644 --- a/packages/common/examples/common.ts +++ b/packages/common/examples/common.ts @@ -8,11 +8,6 @@ const commonWithStrings = new Common({ chain: 'mainnet', hardfork: 'london' }) // Instantiate with the chain (and the default hardfork) let c = new Common({ chain: Chain.Mainnet }) -console.log(`The gas price for ecAdd is ${c.param('ecAddGas')}`) // 500 - -// Chain and hardfork provided -c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) -console.log(`The miner reward under PoW on Byzantium us ${c.param('minerReward')}`) // 3000000000000000000 // Get bootstrap nodes for chain/network console.log('Below are the known bootstrap nodes') diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 1d25c0db9b..e10f833827 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -24,19 +24,16 @@ import type { CliqueConfig, CommonOpts, CustomCrypto, - EIPConfig, EthashConfig, GenesisBlockConfig, HardforkByOpts, HardforkConfig, HardforkTransitionConfig, + ParamsConfig, + ParamsDict, } from './types.js' import type { BigIntLike, PrefixedHexString } from '@ethereumjs/util' -type ParamsCacheConfig = { - [key: string]: number | bigint | null -} - /** * Common class to access chain and hardfork parameters and to provide * a unified and shared view on the network and hardfork state. @@ -51,11 +48,12 @@ export class Common { protected _chainParams: ChainConfig protected _hardfork: string | Hardfork protected _eips: number[] = [] + protected _params: ParamsDict protected _customChains: ChainConfig[] public readonly customCrypto: CustomCrypto - protected _paramsCache: ParamsCacheConfig = {} + protected _paramsCache: ParamsConfig = {} protected _activatedEIPsCache: number[] = [] protected HARDFORK_CHANGES: [string, HardforkConfig][] @@ -75,6 +73,8 @@ export class Common { (this._chainParams.customHardforks && this._chainParams.customHardforks[hf.name]), ]) this._hardfork = this.DEFAULT_HARDFORK + this._params = { ...(opts.params ?? {}) } // copy + if (opts.hardfork !== undefined) { this.setHardfork(opts.hardfork) } @@ -89,6 +89,55 @@ export class Common { } } + /** + * Update the internal Common EIP params set. Existing values + * will get preserved unless there is a new value for a paramter + * provided with params. + * + * Example Format: + * + * ```ts + * { + * 1559: { + * initialBaseFee: 1000000000, + * } + * } + * ``` + * + * @param params + */ + updateParams(params: ParamsDict) { + for (const [eip, paramsConfig] of Object.entries(params)) { + if (!(eip in this._params)) { + this._params[eip] = { ...paramsConfig } // copy + } else { + this._params[eip] = { ...this._params[eip], ...params[eip] } + } + } + + this._buildParamsCache() + } + + /** + * Fully resets the internal Common EIP params set with the values provided. + * + * Example Format: + * + * ```ts + * { + * 1559: { + * initialBaseFee: 1000000000, + * } + * } + * ``` + * + * @param params + */ + resetParams(params: ParamsDict) { + this._params = { ...params } // copy + this._buildParamsCache() + } + /** * Sets the chain * @param chain String ('mainnet') or Number (1) chain representation. @@ -314,7 +363,7 @@ export class Common { for (const eip of eips) { if (eipsDict[eip].requiredEIPs !== undefined) { - for (const elem of eipsDict[eip].requiredEIPs) { + for (const elem of eipsDict[eip].requiredEIPs!) { if (!(eips.includes(elem) || this.isActivatedEIP(elem))) { throw new Error(`${eip} requires EIP ${elem}, but is not included in the EIP list`) } @@ -326,10 +375,10 @@ export class Common { /** * Internal helper for _buildParamsCache() */ - protected _mergeWithParamsCache(params: HardforkConfig | EIPConfig) { + protected _mergeWithParamsCache(params: ParamsConfig) { this._paramsCache = { ...this._paramsCache, - ...params['params'], + ...params, } } @@ -345,28 +394,16 @@ export class Common { if ('eips' in hfChanges[1]) { const hfEIPs = hfChanges[1]['eips'] for (const eip of hfEIPs!) { - if (!(eip in eipsDict)) { - throw new Error(`${eip} not supported`) - } - - this._mergeWithParamsCache(eipsDict[eip]) + this._mergeWithParamsCache(this._params[eip] ?? {}) } - // Parameter-inlining HF config (e.g. for istanbul) - } else { - this._mergeWithParamsCache(hfChanges[1]) - } - if (hfChanges[1].params !== undefined) { - this._mergeWithParamsCache(hfChanges[1]) } + // Parameter-inlining HF config (e.g. for istanbul) + this._mergeWithParamsCache(hfChanges[1].params ?? {}) if (hfChanges[0] === hardfork) break } // Iterate through all additionally activated EIPs for (const eip of this._eips) { - if (!(eip in eipsDict)) { - throw new Error(`${eip} not supported`) - } - - this._mergeWithParamsCache(eipsDict[eip]) + this._mergeWithParamsCache(this._params[eip] ?? {}) } } @@ -414,8 +451,8 @@ export class Common { if ('eips' in hfChanges[1]) { const hfEIPs = hfChanges[1]['eips'] for (const eip of hfEIPs!) { - const eipParams = eipsDict[eip] - const eipValue = eipParams.params?.[name] + const eipParams = this._params[eip] + const eipValue = eipParams?.[name] if (eipValue !== undefined) { value = eipValue } @@ -446,11 +483,11 @@ export class Common { throw new Error(`${eip} not supported`) } - const eipParams = eipsDict[eip] - if (eipParams.params?.[name] === undefined) { + const eipParams = this._params[eip] + if (eipParams?.[name] === undefined) { throw new Error(`Missing parameter value for ${name}`) } - const value = eipParams.params![name] + const value = eipParams![name] return BigInt(value ?? 0) } diff --git a/packages/common/src/constructors.ts b/packages/common/src/constructors.ts index 080d268bbc..6c510d4a25 100644 --- a/packages/common/src/constructors.ts +++ b/packages/common/src/constructors.ts @@ -112,13 +112,22 @@ export function createCustomCommon( */ export function createCommonFromGethGenesis( genesisJson: any, - { chain, eips, genesisHash, hardfork, mergeForkIdPostMerge, customCrypto }: GethConfigOpts, + { + chain, + eips, + genesisHash, + hardfork, + params, + mergeForkIdPostMerge, + customCrypto, + }: GethConfigOpts, ): Common { const genesisParams = parseGethGenesis(genesisJson, chain, mergeForkIdPostMerge) const common = new Common({ chain: genesisParams.name ?? 'custom', customChains: [genesisParams], eips, + params, hardfork: hardfork ?? genesisParams.hardfork, customCrypto, }) diff --git a/packages/common/src/eips.ts b/packages/common/src/eips.ts index 31fed75fea..04401ccbdd 100644 --- a/packages/common/src/eips.ts +++ b/packages/common/src/eips.ts @@ -9,272 +9,54 @@ export const eipsDict: EIPsDict = { */ 1: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasConfig - minGasLimit: 5000, // Minimum the gas limit may ever be - gasLimitBoundDivisor: 1024, // The bound divisor of the gas limit, used in update calculations - maxRefundQuotient: 2, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) - targetBlobGasPerBlock: 0, // Base value needed here since called pre-4844 in BlockHeader.calcNextExcessBlobGas() - blobGasPerBlob: 0, - maxblobGasPerBlock: 0, - // gasPrices - basefeeGas: 2, // Gas base cost, used e.g. for ChainID opcode (Istanbul) - expGas: 10, // Base fee of the EXP opcode - expByteGas: 10, // Times ceil(log256(exponent)) for the EXP instruction - keccak256Gas: 30, // Base fee of the SHA3 opcode - keccak256WordGas: 6, // Once per word of the SHA3 operation's data - sloadGas: 50, // Base fee of the SLOAD opcode - sstoreSetGas: 20000, // Once per SSTORE operation if the zeroness changes from zero - sstoreResetGas: 5000, // Once per SSTORE operation if the zeroness does not change from zero - sstoreRefundGas: 15000, // Once per SSTORE operation if the zeroness changes to zero - jumpdestGas: 1, // Base fee of the JUMPDEST opcode - logGas: 375, // Base fee of the LOG opcode - logDataGas: 8, // Per byte in a LOG* operation's data - logTopicGas: 375, // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas - createGas: 32000, // Base fee of the CREATE opcode - callGas: 40, // Base fee of the CALL opcode - callStipendGas: 2300, // Free gas given at beginning of call - callValueTransferGas: 9000, // Paid for CALL when the value transfor is non-zero - callNewAccountGas: 25000, // Paid for CALL when the destination address didn't exist prior - selfdestructRefundGas: 24000, // Refunded following a selfdestruct operation - memoryGas: 3, // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL - quadCoeffDivGas: 512, // Divisor for the quadratic particle of the memory cost equation - createDataGas: 200, // - txGas: 21000, // Per transaction. NOTE: Not payable on data of calls between transactions - txCreationGas: 32000, // The cost of creating a contract via tx - txDataZeroGas: 4, // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions - txDataNonZeroGas: 68, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions - copyGas: 3, // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added - ecRecoverGas: 3000, - sha256Gas: 60, - sha256WordGas: 12, - ripemd160Gas: 600, - ripemd160WordGas: 120, - identityGas: 15, - identityWordGas: 3, - stopGas: 0, // Base fee of the STOP opcode - addGas: 3, // Base fee of the ADD opcode - mulGas: 5, // Base fee of the MUL opcode - subGas: 3, // Base fee of the SUB opcode - divGas: 5, // Base fee of the DIV opcode - sdivGas: 5, // Base fee of the SDIV opcode - modGas: 5, // Base fee of the MOD opcode - smodGas: 5, // Base fee of the SMOD opcode - addmodGas: 8, // Base fee of the ADDMOD opcode - mulmodGas: 8, // Base fee of the MULMOD opcode - signextendGas: 5, // Base fee of the SIGNEXTEND opcode - ltGas: 3, // Base fee of the LT opcode - gtGas: 3, // Base fee of the GT opcode - sltGas: 3, // Base fee of the SLT opcode - sgtGas: 3, // Base fee of the SGT opcode - eqGas: 3, // Base fee of the EQ opcode - iszeroGas: 3, // Base fee of the ISZERO opcode - andGas: 3, // Base fee of the AND opcode - orGas: 3, // Base fee of the OR opcode - xorGas: 3, // Base fee of the XOR opcode - notGas: 3, // Base fee of the NOT opcode - byteGas: 3, // Base fee of the BYTE opcode - addressGas: 2, // Base fee of the ADDRESS opcode - balanceGas: 20, // Base fee of the BALANCE opcode - originGas: 2, // Base fee of the ORIGIN opcode - callerGas: 2, // Base fee of the CALLER opcode - callvalueGas: 2, // Base fee of the CALLVALUE opcode - calldataloadGas: 3, // Base fee of the CALLDATALOAD opcode - calldatasizeGas: 2, // Base fee of the CALLDATASIZE opcode - calldatacopyGas: 3, // Base fee of the CALLDATACOPY opcode - codesizeGas: 2, // Base fee of the CODESIZE opcode - codecopyGas: 3, // Base fee of the CODECOPY opcode - gaspriceGas: 2, // Base fee of the GASPRICE opcode - extcodesizeGas: 20, // Base fee of the EXTCODESIZE opcode - extcodecopyGas: 20, // Base fee of the EXTCODECOPY opcode - blockhashGas: 20, // Base fee of the BLOCKHASH opcode - coinbaseGas: 2, // Base fee of the COINBASE opcode - timestampGas: 2, // Base fee of the TIMESTAMP opcode - numberGas: 2, // Base fee of the NUMBER opcode - difficultyGas: 2, // Base fee of the DIFFICULTY opcode - gaslimitGas: 2, // Base fee of the GASLIMIT opcode - popGas: 2, // Base fee of the POP opcode - mloadGas: 3, // Base fee of the MLOAD opcode - mstoreGas: 3, // Base fee of the MSTORE opcode - mstore8Gas: 3, // Base fee of the MSTORE8 opcode - sstoreGas: 0, // Base fee of the SSTORE opcode - jumpGas: 8, // Base fee of the JUMP opcode - jumpiGas: 10, // Base fee of the JUMPI opcode - pcGas: 2, // Base fee of the PC opcode - msizeGas: 2, // Base fee of the MSIZE opcode - gasGas: 2, // Base fee of the GAS opcode - pushGas: 3, // Base fee of the PUSH opcode - dupGas: 3, // Base fee of the DUP opcode - swapGas: 3, // Base fee of the SWAP opcode - callcodeGas: 40, // Base fee of the CALLCODE opcode - returnGas: 0, // Base fee of the RETURN opcode - invalidGas: 0, // Base fee of the INVALID opcode - selfdestructGas: 0, // Base fee of the SELFDESTRUCT opcode - prevrandaoGas: 0, // TODO: these below 0-gas additons might also point to non-clean implementations in the code base - authGas: 0, // ...allowing access to non-existing gas parameters. Might be worth to fix at some point. - authcallGas: 0, - accessListStorageKeyGas: 0, - accessListAddressGas: 0, - // vm - stackLimit: 1024, // Maximum size of VM stack allowed - callCreateDepth: 1024, // Maximum depth of call/create stack - maxExtraDataSize: 32, // Maximum size extra data may be after Genesis - // pow - minimumDifficulty: 131072, // The minimum that the difficulty may ever be - difficultyBoundDivisor: 2048, // The bound divisor of the difficulty, used in the update calculations - durationLimit: 13, // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not - epochDuration: 30000, // Duration between proof-of-work epochs - timebombPeriod: 100000, // Exponential difficulty timebomb period - minerReward: BigInt('5000000000000000000'), // the amount a miner get rewarded for mining a block - difficultyBombDelay: 0, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Homestead HF Meta EIP */ 606: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasPrices - delegatecallGas: 40, // Base fee of the DELEGATECALL opcode - }, }, /** * TangerineWhistle HF Meta EIP */ 608: { minimumHardfork: Hardfork.Homestead, - requiredEIPs: [], - params: { - // gasPrices - sloadGas: 200, // Once per SLOAD operation - callGas: 700, // Once per CALL operation & message call transaction - extcodesizeGas: 700, // Base fee of the EXTCODESIZE opcode - extcodecopyGas: 700, // Base fee of the EXTCODECOPY opcode - balanceGas: 400, // Base fee of the BALANCE opcode - delegatecallGas: 700, // Base fee of the DELEGATECALL opcode - callcodeGas: 700, // Base fee of the CALLCODE opcode - selfdestructGas: 5000, // Base fee of the SELFDESTRUCT opcode - }, }, /** * Spurious Dragon HF Meta EIP */ 607: { minimumHardfork: Hardfork.TangerineWhistle, - requiredEIPs: [], - params: { - // gasPrices - expByteGas: 50, // Times ceil(log256(exponent)) for the EXP instruction - // vm - maxCodeSize: 24576, // Maximum length of contract code - }, }, /** * Byzantium HF Meta EIP */ 609: { minimumHardfork: Hardfork.SpuriousDragon, - requiredEIPs: [], - params: { - // gasPrices - modexpGquaddivisorGas: 20, // Gquaddivisor from modexp precompile for gas calculation - ecAddGas: 500, // Gas costs for curve addition precompile - ecMulGas: 40000, // Gas costs for curve multiplication precompile - ecPairingGas: 100000, // Base gas costs for curve pairing precompile - ecPairingWordGas: 80000, // Gas costs regarding curve pairing precompile input length - revertGas: 0, // Base fee of the REVERT opcode - staticcallGas: 700, // Base fee of the STATICCALL opcode - returndatasizeGas: 2, // Base fee of the RETURNDATASIZE opcode - returndatacopyGas: 3, // Base fee of the RETURNDATACOPY opcode - // pow - minerReward: BigInt('3000000000000000000'), // the amount a miner get rewarded for mining a block - difficultyBombDelay: 3000000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Constantinope HF Meta EIP */ 1013: { minimumHardfork: Hardfork.Constantinople, - requiredEIPs: [], - params: { - // gasPrices - netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change - netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero - netSstoreCleanGas: 5000, // Once per SSTORE operation from clean non-zero - netSstoreDirtyGas: 200, // Once per SSTORE operation from dirty - netSstoreClearRefundGas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot - netSstoreResetRefundGas: 4800, // Once per SSTORE operation for resetting to the original non-zero value - netSstoreResetClearRefundGas: 19800, // Once per SSTORE operation for resetting to the original zero value - shlGas: 3, // Base fee of the SHL opcode - shrGas: 3, // Base fee of the SHR opcode - sarGas: 3, // Base fee of the SAR opcode - extcodehashGas: 400, // Base fee of the EXTCODEHASH opcode - create2Gas: 32000, // Base fee of the CREATE2 opcode - // pow - minerReward: BigInt('2000000000000000000'), // The amount a miner gets rewarded for mining a block - difficultyBombDelay: 5000000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Petersburg HF Meta EIP */ 1716: { minimumHardfork: Hardfork.Constantinople, - requiredEIPs: [], - params: { - // gasPrices - netSstoreNoopGas: null, // Removed along EIP-1283 - netSstoreInitGas: null, // Removed along EIP-1283 - netSstoreCleanGas: null, // Removed along EIP-1283 - netSstoreDirtyGas: null, // Removed along EIP-1283 - netSstoreClearRefundGas: null, // Removed along EIP-1283 - netSstoreResetRefundGas: null, // Removed along EIP-1283 - netSstoreResetClearRefundGas: null, // Removed along EIP-1283 - }, }, /** * Istanbul HF Meta EIP */ 1679: { minimumHardfork: Hardfork.Constantinople, - requiredEIPs: [], - params: { - // gasPrices - blake2RoundGas: 1, // Gas cost per round for the Blake2 F precompile - ecAddGas: 150, // Gas costs for curve addition precompile - ecMulGas: 6000, // Gas costs for curve multiplication precompile - ecPairingGas: 45000, // Base gas costs for curve pairing precompile - ecPairingWordGas: 34000, // Gas costs regarding curve pairing precompile input length - txDataNonZeroGas: 16, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions - sstoreSentryEIP2200Gas: 2300, // Minimum gas required to be present for an SSTORE call, not consumed - sstoreNoopEIP2200Gas: 800, // Once per SSTORE operation if the value doesn't change - sstoreDirtyEIP2200Gas: 800, // Once per SSTORE operation if a dirty value is changed - sstoreInitEIP2200Gas: 20000, // Once per SSTORE operation from clean zero to non-zero - sstoreInitRefundEIP2200Gas: 19200, // Once per SSTORE operation for resetting to the original zero value - sstoreCleanEIP2200Gas: 5000, // Once per SSTORE operation from clean non-zero to something else - sstoreCleanRefundEIP2200Gas: 4200, // Once per SSTORE operation for resetting to the original non-zero value - sstoreClearRefundEIP2200Gas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot - balanceGas: 700, // Base fee of the BALANCE opcode - extcodehashGas: 700, // Base fee of the EXTCODEHASH opcode - chainidGas: 2, // Base fee of the CHAINID opcode - selfbalanceGas: 5, // Base fee of the SELFBALANCE opcode - sloadGas: 800, // Base fee of the SLOAD opcode - }, }, /** * MuirGlacier HF Meta EIP */ 2384: { minimumHardfork: Hardfork.Istanbul, - requiredEIPs: [], - params: { - // pow - difficultyBombDelay: 9000000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Description : SWAPN, DUPN and EXCHANGE instructions @@ -284,12 +66,6 @@ export const eipsDict: EIPsDict = { 663: { minimumHardfork: Hardfork.Chainstart, requiredEIPs: [3540, 5450], - params: { - // gasPrices - dupnGas: 3, // Base fee of the DUPN opcode - swapnGas: 3, // Base fee of the SWAPN opcode - exchangeGas: 3, // Base fee of the EXCHANGE opcode - }, }, /** * Description : Transient storage opcodes @@ -298,12 +74,6 @@ export const eipsDict: EIPsDict = { */ 1153: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasPrices - tstoreGas: 100, // Base fee of the TSTORE opcode - tloadGas: 100, // Base fee of the TLOAD opcode - }, }, /** * Description : Fee market change for ETH 1.0 chain @@ -313,12 +83,6 @@ export const eipsDict: EIPsDict = { 1559: { minimumHardfork: Hardfork.Berlin, requiredEIPs: [2930], - params: { - // gasConfig - baseFeeMaxChangeDenominator: 8, // Maximum base fee change denominator - elasticityMultiplier: 2, // Maximum block gas target elasticity - initialBaseFee: 1000000000, // Initial base fee on first EIP1559 block - }, }, /** * Description : ModExp gas cost @@ -327,11 +91,6 @@ export const eipsDict: EIPsDict = { */ 2565: { minimumHardfork: Hardfork.Byzantium, - requiredEIPs: [], - params: { - // gasPrices - modexpGquaddivisorGas: 3, // Gquaddivisor from modexp precompile for gas calculation - }, }, /** * Description : BLS12-381 precompiles @@ -340,18 +99,6 @@ export const eipsDict: EIPsDict = { */ 2537: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasPrices - Bls12381G1AddGas: 500, // Gas cost of a single BLS12-381 G1 addition precompile-call - Bls12381G1MulGas: 12000, // Gas cost of a single BLS12-381 G1 multiplication precompile-call - Bls12381G2AddGas: 800, // Gas cost of a single BLS12-381 G2 addition precompile-call - Bls12381G2MulGas: 45000, // Gas cost of a single BLS12-381 G2 multiplication precompile-call - Bls12381PairingBaseGas: 65000, // Base gas cost of BLS12-381 pairing check - Bls12381PairingPerPairGas: 43000, // Per-pair gas cost of BLS12-381 pairing check - Bls12381MapG1Gas: 5500, // Gas cost of BLS12-381 map field element to G1 - Bls12381MapG2Gas: 75000, // Gas cost of BLS12-381 map field element to G2 - }, }, /** * Description : Typed Transaction Envelope @@ -360,7 +107,6 @@ export const eipsDict: EIPsDict = { */ 2718: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], }, /** * Description : Gas cost increases for state access opcodes @@ -369,28 +115,6 @@ export const eipsDict: EIPsDict = { */ 2929: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasPrices - coldsloadGas: 2100, // Gas cost of the first read of storage from a given location (per transaction) - coldaccountaccessGas: 2600, // Gas cost of the first read of a given address (per transaction) - warmstoragereadGas: 100, // Gas cost of reading storage locations which have already loaded 'cold' - sstoreCleanEIP2200Gas: 2900, // Once per SSTORE operation from clean non-zero to something else - sstoreNoopEIP2200Gas: 100, // Once per SSTORE operation if the value doesn't change - sstoreDirtyEIP2200Gas: 100, // Once per SSTORE operation if a dirty value is changed - sstoreInitRefundEIP2200Gas: 19900, // Once per SSTORE operation for resetting to the original zero value - sstoreCleanRefundEIP2200Gas: 4900, // Once per SSTORE operation for resetting to the original non-zero value - callGas: 0, // Base fee of the CALL opcode - callcodeGas: 0, // Base fee of the CALLCODE opcode - delegatecallGas: 0, // Base fee of the DELEGATECALL opcode - staticcallGas: 0, // Base fee of the STATICCALL opcode - balanceGas: 0, // Base fee of the BALANCE opcode - extcodesizeGas: 0, // Base fee of the EXTCODESIZE opcode - extcodecopyGas: 0, // Base fee of the EXTCODECOPY opcode - extcodehashGas: 0, // Base fee of the EXTCODEHASH opcode - sloadGas: 0, // Base fee of the SLOAD opcode - sstoreGas: 0, // Base fee of the SSTORE opcode - }, }, /** * Description : Optional access lists @@ -400,11 +124,6 @@ export const eipsDict: EIPsDict = { 2930: { minimumHardfork: Hardfork.Istanbul, requiredEIPs: [2718, 2929], - params: { - // gasPrices - accessListStorageKeyGas: 1900, // Gas cost per storage key in an Access List transaction - accessListAddressGas: 2400, // Gas cost per storage key in an Access List transaction - }, }, /** * Description : Save historical block hashes in state (Verkle related usage, UNSTABLE) @@ -413,12 +132,6 @@ export const eipsDict: EIPsDict = { */ 2935: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // vm - historyStorageAddress: BigInt('0x0aae40965e6800cd9b1f4b05ff21581047e3f91e'), // The address where the historical blockhashes are stored - historyServeWindow: BigInt(8192), // The amount of blocks to be served by the historical blockhash contract - }, }, /** * Description : AUTH and AUTHCALL opcodes @@ -427,13 +140,6 @@ export const eipsDict: EIPsDict = { */ 3074: { minimumHardfork: Hardfork.London, - requiredEIPs: [], - params: { - // gasPrices - authGas: 3100, // Gas cost of the AUTH opcode - authcallGas: 0, // Gas cost of the AUTHCALL opcode - authcallValueTransferGas: 6700, // Paid for CALL when the value transfer is non-zero - }, }, /** * Description : BASEFEE opcode @@ -442,11 +148,6 @@ export const eipsDict: EIPsDict = { */ 3198: { minimumHardfork: Hardfork.London, - requiredEIPs: [], - params: { - // gasPrices - basefeeGas: 2, // Gas cost of the BASEFEE opcode - }, }, /** * Description : Reduction in refunds @@ -456,13 +157,6 @@ export const eipsDict: EIPsDict = { 3529: { minimumHardfork: Hardfork.Berlin, requiredEIPs: [2929], - params: { - // gasConfig - maxRefundQuotient: 5, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) - // gasPrices - selfdestructRefundGas: 0, // Refunded following a selfdestruct operation - sstoreClearRefundEIP2200Gas: 4800, // Once per SSTORE operation for clearing an originally existing storage slot - }, }, /** * Description : EVM Object Format (EOF) v1 @@ -480,7 +174,6 @@ export const eipsDict: EIPsDict = { */ 3541: { minimumHardfork: Hardfork.Berlin, - requiredEIPs: [], }, /** * Description : Difficulty Bomb Delay to December 1st 2021 @@ -489,11 +182,6 @@ export const eipsDict: EIPsDict = { */ 3554: { minimumHardfork: Hardfork.MuirGlacier, - requiredEIPs: [], - params: { - // pow - difficultyBombDelay: 9500000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Description : Reject transactions from senders with deployed code @@ -502,7 +190,6 @@ export const eipsDict: EIPsDict = { */ 3607: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], }, /** * Description : Warm COINBASE @@ -529,7 +216,6 @@ export const eipsDict: EIPsDict = { */ 3675: { minimumHardfork: Hardfork.London, - requiredEIPs: [], }, /** * Description : PUSH0 instruction @@ -538,11 +224,6 @@ export const eipsDict: EIPsDict = { */ 3855: { minimumHardfork: Hardfork.Chainstart, - requiredEIPs: [], - params: { - // gasPrices - push0Gas: 2, // Base fee of the PUSH0 opcode - }, }, /** * Description : Limit and meter initcode @@ -551,13 +232,6 @@ export const eipsDict: EIPsDict = { */ 3860: { minimumHardfork: Hardfork.SpuriousDragon, - requiredEIPs: [], - params: { - // gasPrices - initCodeWordGas: 2, // Gas to pay for each word (32 bytes) of initcode when creating a contract - // vm - maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract - }, }, /** * Description : EOF - Static relative jumps @@ -567,12 +241,6 @@ export const eipsDict: EIPsDict = { 4200: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670], - params: { - // gasPrices - rjumpGas: 2, // Base fee of the RJUMP opcode - rjumpiGas: 4, // Base fee of the RJUMPI opcode - rjumpvGas: 4, // Base fee of the RJUMPV opcode - }, }, /** * Description : Difficulty Bomb Delay to June 2022 @@ -581,11 +249,6 @@ export const eipsDict: EIPsDict = { */ 4345: { minimumHardfork: Hardfork.London, - requiredEIPs: [], - params: { - // pow - difficultyBombDelay: 10700000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Description : Supplant DIFFICULTY opcode with PREVRANDAO @@ -594,11 +257,6 @@ export const eipsDict: EIPsDict = { */ 4399: { minimumHardfork: Hardfork.London, - requiredEIPs: [], - params: { - // gasPrices - prevrandaoGas: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) - }, }, /** * Description : EOF - Functions @@ -608,11 +266,6 @@ export const eipsDict: EIPsDict = { 4750: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670, 5450], - params: { - // gasPrices - callfGas: 5, // Base fee of the CALLF opcode - retfGas: 3, // Base fee of the RETF opcode - }, }, /** * Description : Beacon block root in the EVM @@ -621,11 +274,6 @@ export const eipsDict: EIPsDict = { */ 4788: { minimumHardfork: Hardfork.Cancun, - requiredEIPs: [], - params: { - // vm - historicalRootsLength: 8191, // The modulo parameter of the beaconroot ring buffer in the beaconroot statefull precompile - }, }, /** * Description : Shard Blob Transactions @@ -635,21 +283,6 @@ export const eipsDict: EIPsDict = { 4844: { minimumHardfork: Hardfork.Paris, requiredEIPs: [1559, 2718, 2930, 4895], - params: { - // gasConfig - blobGasPerBlob: 131072, // The base fee for blob gas per blob - targetBlobGasPerBlock: 393216, // The target blob gas consumed per block - maxblobGasPerBlock: 786432, // The max blob gas allowable per block - blobGasPriceUpdateFraction: 3338477, // The denominator used in the exponential when calculating a blob gas price - // gasPrices - simplePerBlobGas: 12000, // The basic gas fee for each blob - minBlobGas: 1, // The minimum fee per blob gas - kzgPointEvaluationPrecompileGas: 50000, // The fee associated with the point evaluation precompile - blobhashGas: 3, // Base fee of the BLOBHASH opcode - // sharding - blobCommitmentVersionKzg: 1, // The number indicated a versioned hash is a KZG commitment - fieldElementsPerBlob: 4096, // The number of field elements allowed per blob - }, }, /** * Description : Beacon chain push withdrawals as operations @@ -658,7 +291,6 @@ export const eipsDict: EIPsDict = { */ 4895: { minimumHardfork: Hardfork.Paris, - requiredEIPs: [], }, /** * Description : Delaying Difficulty Bomb to mid-September 2022 @@ -667,11 +299,6 @@ export const eipsDict: EIPsDict = { */ 5133: { minimumHardfork: Hardfork.GrayGlacier, - requiredEIPs: [], - params: { - // pow - difficultyBombDelay: 11400000, // the amount of blocks to delay the difficulty bomb with - }, }, /** * Description : EOF - Stack Validation @@ -689,11 +316,6 @@ export const eipsDict: EIPsDict = { */ 5656: { minimumHardfork: Hardfork.Shanghai, - requiredEIPs: [], - params: { - // gasPrices - mcopyGas: 3, // Base fee of the MCOPY opcode - }, }, /** * Description : Supply validator deposits on chain @@ -712,10 +334,6 @@ export const eipsDict: EIPsDict = { 6206: { minimumHardfork: Hardfork.London, requiredEIPs: [4750, 5450], - params: { - // gasPrices - jumpfGas: 5, // Base fee of the JUMPF opcode - }, }, /** * Description : SELFDESTRUCT only in same transaction @@ -724,7 +342,6 @@ export const eipsDict: EIPsDict = { */ 6780: { minimumHardfork: Hardfork.London, - requiredEIPs: [], }, /** * Description : Ethereum state using a unified verkle tree (experimental) @@ -733,16 +350,6 @@ export const eipsDict: EIPsDict = { */ 6800: { minimumHardfork: Hardfork.London, - requiredEIPs: [], - params: { - // gasPrices - createGas: 1000, // Base fee of the CREATE opcode - coldsloadGas: 0, // Gas cost of the first read of storage from a given location (per transaction) - // vm - // kaustinen 6 current uses this address, however this will be updated to correct address - // in next iteration - historyStorageAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The address where the historical blockhashes are stored - }, }, /** * Description : Execution layer triggerable withdrawals (experimental) @@ -752,21 +359,6 @@ export const eipsDict: EIPsDict = { 7002: { minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], - params: { - // vm - withdrawalRequestType: BigInt(0x01), // The withdrawal request type for EIP-7685 - excessWithdrawalsRequestStorageSlot: BigInt(0), // The storage slot of the excess withdrawals - withdrawalsRequestCountStorage: BigInt(1), // The storage slot of the withdrawal request count - withdrawalsRequestQueueHeadStorageSlot: BigInt(2), // The storage slot of the withdrawal request head of the queue - withdrawalsRequestTailHeadStorageSlot: BigInt(3), // The storage slot of the withdrawal request tail of the queue - withdrawalsRequestQueueStorageOffset: BigInt(4), // The storage slot of the withdrawal request queue offset - maxWithdrawalRequestsPerBlock: BigInt(16), // The max withdrawal requests per block - targetWithdrawalRequestsPerBlock: BigInt(2), // The target withdrawal requests per block - minWithdrawalRequestFee: BigInt(1), // The minimum withdrawal request fee (in wei) - withdrawalRequestFeeUpdateFraction: BigInt(17), // The withdrawal request fee update fraction (used in the fake exponential) - systemAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The system address to perform operations on the withdrawal requests predeploy address - withdrawalRequestPredeployAddress: BigInt('0x00A3ca265EBcb825B45F985A16CEFB49958cE017'), // Address of the validator excess address - }, }, /** * Description : Revamped CALL instructions @@ -781,15 +373,6 @@ export const eipsDict: EIPsDict = { EIP 214 - (STATICCALL) - Included in Byzantium */ requiredEIPs: [2929], - params: { - // gasPrices - extcallGas: 0, // Base fee of the EXTCALL opcode - extdelegatecallGas: 0, // Base fee of the EXTDELEGATECALL opcode - extstaticcallGas: 0, // Base fee of the EXTSTATICCALL opcode - returndataloadGas: 3, // Base fee of the RETURNDATALOAD opcode - minRetainedGas: 5000, // Minimum gas retained prior to executing an EXT*CALL opcode (this is the minimum gas available after performing the EXT*CALL) - minCalleeGas: 2300, //Minimum gas available to the the address called by an EXT*CALL opcode - }, }, /** * Description : Increase the MAX_EFFECTIVE_BALANCE -> Execution layer triggered consolidations (experimental) @@ -799,12 +382,6 @@ export const eipsDict: EIPsDict = { 7251: { minimumHardfork: Hardfork.Paris, requiredEIPs: [7685], - params: { - // vm - consolidationRequestType: BigInt(0x02), // The withdrawal request type for EIP-7685 - systemAddress: BigInt('0xfffffffffffffffffffffffffffffffffffffffe'), // The system address to perform operations on the consolidation requests predeploy address - consolidationRequestPredeployAddress: BigInt('0x00b42dbF2194e931E80326D950320f7d9Dbeac02'), // Address of the consolidations contract - }, }, /** * Description : EOF - Data section access instructions @@ -814,13 +391,6 @@ export const eipsDict: EIPsDict = { 7480: { minimumHardfork: Hardfork.London, requiredEIPs: [3540, 3670], - params: { - // gasPrices - dataloadGas: 4, // Base fee of the DATALOAD opcode - dataloadnGas: 3, // Base fee of the DATALOADN opcode - datasizeGas: 2, // Base fee of the DATASIZE opcode - datacopyGas: 3, // Base fee of the DATACOPY opcode - }, }, /** * Description : BLOBBASEFEE opcode @@ -830,10 +400,6 @@ export const eipsDict: EIPsDict = { 7516: { minimumHardfork: Hardfork.Paris, requiredEIPs: [4844], - params: { - // gasPrices - blobbasefeeGas: 2, // Gas cost of the BLOBBASEFEE opcode - }, }, /** * Description : EOF Contract Creation @@ -846,11 +412,6 @@ export const eipsDict: EIPsDict = { EIP 170 - (Max contract size) - Included in Spurious Dragon */ requiredEIPs: [3540, 3541, 3670], - params: { - // gasPrices - eofcreateGas: 32000, // Base fee of the EOFCREATE opcode (Same as CREATE/CREATE2) - returncontractGas: 0, // Base fee of the RETURNCONTRACT opcode - }, }, /** * Description : General purpose execution layer requests @@ -889,10 +450,6 @@ export const eipsDict: EIPsDict = { // TODO: Set correct minimum hardfork minimumHardfork: Hardfork.Cancun, requiredEIPs: [2718, 2929, 2930], - params: { - // gasPrices - perAuthBaseGas: 2500, // Gas cost of each authority item - }, }, /** * Description : Use historical block hashes saved in state for BLOCKHASH diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 746400f364..1c395643d7 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -103,6 +103,24 @@ interface BaseOpts { * - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS12-381 precompiles */ eips?: number[] + /** + * Optionally pass in an EIP params dictionary, see one of the + * EthereumJS library `params.ts` files for an example (e.g. tx, evm). + * By default parameters are set by the respective library, so this + * is only relevant if you want to use EthereumJS libraries with a + * custom parameter set. + * + * Example Format: + * + * ```ts + * { + * 1559: { + * initialBaseFee: 1000000000, + * } + * } + * ``` + */ + params?: ParamsDict /** * This option can be used to replace the most common crypto primitives * (keccak256 hashing e.g.) within the EthereumJS ecosystem libraries @@ -126,6 +144,7 @@ export interface CommonOpts extends BaseOpts { * passed in via {@link CommonOpts.customChains}. */ chain: string | number | Chain | bigint | object + /** * Initialize (in addition to the supported chains) with the selected * custom chains. Custom genesis state should be passed to the Blockchain class if used. @@ -165,24 +184,27 @@ export interface HardforkByOpts { export type EIPConfig = { minimumHardfork: Hardfork - requiredEIPs: number[] - params?: { - [key: string]: number | bigint | null - } + requiredEIPs?: number[] +} + +export type ParamsConfig = { + [key: string]: number | string | null } export type HardforkConfig = { eips?: number[] consensus?: ConsensusConfig - params?: { - [key: string]: number | bigint | null - } + params?: ParamsConfig } export type EIPsDict = { [key: string]: EIPConfig } +export type ParamsDict = { + [key: string]: ParamsConfig +} + export type HardforksDict = { [key: string]: HardforkConfig } diff --git a/packages/common/test/data/paramsTest.ts b/packages/common/test/data/paramsTest.ts new file mode 100644 index 0000000000..b6121c1b65 --- /dev/null +++ b/packages/common/test/data/paramsTest.ts @@ -0,0 +1,50 @@ +import type { ParamsDict } from '@ethereumjs/common' + +export const paramsTest: ParamsDict = { + /** + * Frontier/Chainstart + */ + 1: { + // pow + minerReward: '5000000000000000000', // the amount a miner get rewarded for mining a block + }, + /** + * Byzantium HF Meta EIP + */ + 609: { + // gasPrices + ecAddGas: 500, // Gas costs for curve addition precompile + // pow + minerReward: '3000000000000000000', // the amount a miner get rewarded for mining a block + }, + /** +. * Constantinope HF Meta EIP +. */ + 1013: { + // gasPrices + netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change + // pow + minerReward: '2000000000000000000', // The amount a miner gets rewarded for mining a block + }, + /** +. * Petersburg HF Meta EIP +. */ + 1716: { + // gasPrices + netSstoreNoopGas: null, // Removed along EIP-1283 + }, + /** + * Istanbul HF Meta EIP + */ + 1679: { + // gasPrices + ecAddGas: 150, // Gas costs for curve addition precompile + }, + /** + * BLS12-381 precompiles + */ + 2537: { + // gasPrices + Bls12381G1AddGas: 500, // Gas cost of a single BLS12-381 G1 addition precompile-call + }, +} diff --git a/packages/common/test/params.spec.ts b/packages/common/test/params.spec.ts index a71702fbc4..900ab3dffd 100644 --- a/packages/common/test/params.spec.ts +++ b/packages/common/test/params.spec.ts @@ -2,9 +2,38 @@ import { assert, describe, it } from 'vitest' import { Chain, Common, Hardfork } from '../src/index.js' +import { paramsTest } from './data/paramsTest.js' + +describe('[Common]: Parameter instantion / params option / Updates', () => { + it('Param option', () => { + const c = new Common({ chain: Chain.Mainnet, params: paramsTest }) + let msg = 'Should also work with parameters passed with params option' + assert.equal(c.param('ecAddGas'), BigInt(150), msg) + + const params = { + 1679: { + ecAddGas: 250, + }, + } + c.updateParams(params) + msg = 'Should update parameter on updateParams() and properly rebuild cache' + assert.equal(c.param('ecAddGas'), BigInt(250), msg) + + c.resetParams(params) + msg = 'Should reset all parameters on resetParams() and properly rebuild cache' + assert.equal(c.param('ecAddGas'), BigInt(250), msg) + assert.throws(() => { + c.param('ecMulGas'), BigInt(250) + }) + + msg = 'Should not side-manipulate the original params file during updating internally' + assert.equal(paramsTest['1679']['ecAddGas'], 150) + }) +}) + describe('[Common]: Parameter access for param(), paramByHardfork()', () => { it('Basic usage', () => { - const c = new Common({ chain: Chain.Mainnet, eips: [2537] }) + const c = new Common({ chain: Chain.Mainnet, params: paramsTest, eips: [2537] }) let msg = 'Should return correct value when HF directly provided' assert.equal(c.paramByHardfork('ecAddGas', 'byzantium'), BigInt(500), msg) @@ -31,7 +60,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { }) it('Error cases for param(), paramByHardfork()', () => { - const c = new Common({ chain: Chain.Mainnet }) + const c = new Common({ chain: Chain.Mainnet, params: paramsTest }) c.setHardfork(Hardfork.Byzantium) assert.equal( @@ -42,7 +71,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { }) it('Parameter updates', () => { - const c = new Common({ chain: Chain.Mainnet }) + const c = new Common({ chain: Chain.Mainnet, params: paramsTest }) let msg = 'Should return correct value for chain start' assert.equal(c.paramByHardfork('minerReward', 'chainstart'), BigInt(5000000000000000000), msg) @@ -58,7 +87,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { }) it('Access by block number, paramByBlock()', () => { - const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium }) + const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium, params: paramsTest }) let msg = 'Should correctly translate block numbers into HF states (updated value)' assert.equal(c.paramByBlock('minerReward', 4370000), BigInt(3000000000000000000), msg) @@ -71,7 +100,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { }) it('Access on copied Common instances', () => { - const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) + const c = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai, params: paramsTest }) let msg = 'Should correctly access param with param() on original Common' assert.equal(c.param('minerReward'), BigInt(2000000000000000000), msg) @@ -87,7 +116,7 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { }) it('EIP param access, paramByEIP()', () => { - const c = new Common({ chain: Chain.Mainnet }) + const c = new Common({ chain: Chain.Mainnet, params: paramsTest }) assert.throws(() => { c.paramByEIP('notexistingvalue', 1559) @@ -106,15 +135,4 @@ describe('[Common]: Parameter access for param(), paramByHardfork()', () => { msg = 'Should return Bls12381G1AddGas gas price for EIP2537' assert.equal(c.paramByEIP('Bls12381G1AddGas', 2537), BigInt(500), msg) }) - - it('returns the right block delay for EIP3554', () => { - for (const fork of [Hardfork.MuirGlacier, Hardfork.Berlin]) { - const c = new Common({ chain: Chain.Mainnet, hardfork: fork }) - let delay = c.param('difficultyBombDelay') - assert.equal(delay, BigInt(9000000)) - c.setEIPs([3554]) - delay = c.param('difficultyBombDelay') - assert.equal(delay, BigInt(9500000)) - } - }) }) diff --git a/packages/evm/examples/decode-opcodes.ts b/packages/evm/examples/decode-opcodes.ts index b138bd529d..cfcbd42613 100644 --- a/packages/evm/examples/decode-opcodes.ts +++ b/packages/evm/examples/decode-opcodes.ts @@ -3,11 +3,10 @@ // 1. Takes binary EVM code and decodes it into opcodes import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { getOpcodesForHF, paramsEVM } from '@ethereumjs/evm' import { bytesToHex, hexToBytes } from '@ethereumjs/util' -import { getOpcodesForHF } from '../dist/cjs/opcodes/index.js' - -const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) +const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul, params: paramsEVM }) const opcodes = getOpcodesForHF(common).opcodes const data = diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index ff85812b00..1aed094c00 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -26,6 +26,7 @@ import { Journal } from './journal.js' import { EVMPerformanceLogger } from './logger.js' import { Message } from './message.js' import { getOpcodesForHF } from './opcodes/index.js' +import { paramsEVM } from './params.js' import { NobleBLS, getActivePrecompiles, getPrecompileName } from './precompiles/index.js' import { TransientStorage } from './transientStorage.js' @@ -183,6 +184,8 @@ export class EVM implements EVMInterface { ) } + this.common.updateParams(opts.params ?? paramsEVM) + this.allowUnlimitedContractSize = opts.allowUnlimitedContractSize ?? false this.allowUnlimitedInitCodeSize = opts.allowUnlimitedInitCodeSize ?? false this._customOpcodes = opts.customOpcodes diff --git a/packages/evm/src/index.ts b/packages/evm/src/index.ts index 6fcfc55462..dc79d5c626 100644 --- a/packages/evm/src/index.ts +++ b/packages/evm/src/index.ts @@ -47,3 +47,4 @@ export { } export * from './constructors.js' +export * from './params.js' diff --git a/packages/evm/src/params.ts b/packages/evm/src/params.ts new file mode 100644 index 0000000000..f4483d1201 --- /dev/null +++ b/packages/evm/src/params.ts @@ -0,0 +1,431 @@ +import type { ParamsDict } from '@ethereumjs/common' + +export const paramsEVM: ParamsDict = { + /** + * Frontier/Chainstart + */ + 1: { + // gasConfig + maxRefundQuotient: 2, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) + // gasPrices + basefeeGas: 2, // Gas base cost, used e.g. for ChainID opcode (Istanbul) + expGas: 10, // Base fee of the EXP opcode + expByteGas: 10, // Times ceil(log256(exponent)) for the EXP instruction + keccak256Gas: 30, // Base fee of the SHA3 opcode + keccak256WordGas: 6, // Once per word of the SHA3 operation's data + sloadGas: 50, // Base fee of the SLOAD opcode + sstoreSetGas: 20000, // Once per SSTORE operation if the zeroness changes from zero + sstoreResetGas: 5000, // Once per SSTORE operation if the zeroness does not change from zero + sstoreRefundGas: 15000, // Once per SSTORE operation if the zeroness changes to zero + jumpdestGas: 1, // Base fee of the JUMPDEST opcode + logGas: 375, // Base fee of the LOG opcode + logDataGas: 8, // Per byte in a LOG* operation's data + logTopicGas: 375, // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas + createGas: 32000, // Base fee of the CREATE opcode + callGas: 40, // Base fee of the CALL opcode + callStipendGas: 2300, // Free gas given at beginning of call + callValueTransferGas: 9000, // Paid for CALL when the value transfor is non-zero + callNewAccountGas: 25000, // Paid for CALL when the destination address didn't exist prior + selfdestructRefundGas: 24000, // Refunded following a selfdestruct operation + memoryGas: 3, // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL + quadCoeffDivGas: 512, // Divisor for the quadratic particle of the memory cost equation + createDataGas: 200, // + copyGas: 3, // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added + ecRecoverGas: 3000, + sha256Gas: 60, + sha256WordGas: 12, + ripemd160Gas: 600, + ripemd160WordGas: 120, + identityGas: 15, + identityWordGas: 3, + stopGas: 0, // Base fee of the STOP opcode + addGas: 3, // Base fee of the ADD opcode + mulGas: 5, // Base fee of the MUL opcode + subGas: 3, // Base fee of the SUB opcode + divGas: 5, // Base fee of the DIV opcode + sdivGas: 5, // Base fee of the SDIV opcode + modGas: 5, // Base fee of the MOD opcode + smodGas: 5, // Base fee of the SMOD opcode + addmodGas: 8, // Base fee of the ADDMOD opcode + mulmodGas: 8, // Base fee of the MULMOD opcode + signextendGas: 5, // Base fee of the SIGNEXTEND opcode + ltGas: 3, // Base fee of the LT opcode + gtGas: 3, // Base fee of the GT opcode + sltGas: 3, // Base fee of the SLT opcode + sgtGas: 3, // Base fee of the SGT opcode + eqGas: 3, // Base fee of the EQ opcode + iszeroGas: 3, // Base fee of the ISZERO opcode + andGas: 3, // Base fee of the AND opcode + orGas: 3, // Base fee of the OR opcode + xorGas: 3, // Base fee of the XOR opcode + notGas: 3, // Base fee of the NOT opcode + byteGas: 3, // Base fee of the BYTE opcode + addressGas: 2, // Base fee of the ADDRESS opcode + balanceGas: 20, // Base fee of the BALANCE opcode + originGas: 2, // Base fee of the ORIGIN opcode + callerGas: 2, // Base fee of the CALLER opcode + callvalueGas: 2, // Base fee of the CALLVALUE opcode + calldataloadGas: 3, // Base fee of the CALLDATALOAD opcode + calldatasizeGas: 2, // Base fee of the CALLDATASIZE opcode + calldatacopyGas: 3, // Base fee of the CALLDATACOPY opcode + codesizeGas: 2, // Base fee of the CODESIZE opcode + codecopyGas: 3, // Base fee of the CODECOPY opcode + gaspriceGas: 2, // Base fee of the GASPRICE opcode + extcodesizeGas: 20, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 20, // Base fee of the EXTCODECOPY opcode + blockhashGas: 20, // Base fee of the BLOCKHASH opcode + coinbaseGas: 2, // Base fee of the COINBASE opcode + timestampGas: 2, // Base fee of the TIMESTAMP opcode + numberGas: 2, // Base fee of the NUMBER opcode + difficultyGas: 2, // Base fee of the DIFFICULTY opcode + gaslimitGas: 2, // Base fee of the GASLIMIT opcode + popGas: 2, // Base fee of the POP opcode + mloadGas: 3, // Base fee of the MLOAD opcode + mstoreGas: 3, // Base fee of the MSTORE opcode + mstore8Gas: 3, // Base fee of the MSTORE8 opcode + sstoreGas: 0, // Base fee of the SSTORE opcode + jumpGas: 8, // Base fee of the JUMP opcode + jumpiGas: 10, // Base fee of the JUMPI opcode + pcGas: 2, // Base fee of the PC opcode + msizeGas: 2, // Base fee of the MSIZE opcode + gasGas: 2, // Base fee of the GAS opcode + pushGas: 3, // Base fee of the PUSH opcode + dupGas: 3, // Base fee of the DUP opcode + swapGas: 3, // Base fee of the SWAP opcode + callcodeGas: 40, // Base fee of the CALLCODE opcode + returnGas: 0, // Base fee of the RETURN opcode + invalidGas: 0, // Base fee of the INVALID opcode + selfdestructGas: 0, // Base fee of the SELFDESTRUCT opcode + prevrandaoGas: 0, // TODO: these below 0-gas additons might also point to non-clean implementations in the code base + authGas: 0, // ...allowing access to non-existing gas parameters. Might be worth to fix at some point. + authcallGas: 0, + // evm + stackLimit: 1024, // Maximum size of VM stack allowed + callCreateDepth: 1024, // Maximum depth of call/create stack + }, + /** +. * Homestead HF Meta EIP +. */ + 606: { + // gasPrices + delegatecallGas: 40, // Base fee of the DELEGATECALL opcode + }, + /** +. * TangerineWhistle HF Meta EIP +. */ + 608: { + // gasPrices + sloadGas: 200, // Once per SLOAD operation + callGas: 700, // Once per CALL operation & message call transaction + extcodesizeGas: 700, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 700, // Base fee of the EXTCODECOPY opcode + balanceGas: 400, // Base fee of the BALANCE opcode + delegatecallGas: 700, // Base fee of the DELEGATECALL opcode + callcodeGas: 700, // Base fee of the CALLCODE opcode + selfdestructGas: 5000, // Base fee of the SELFDESTRUCT opcode + }, + /** +. * Spurious Dragon HF Meta EIP +. */ + 607: { + // gasPrices + expByteGas: 50, // Times ceil(log256(exponent)) for the EXP instruction + // evm + maxCodeSize: 24576, // Maximum length of contract code + }, + /** +. * Byzantium HF Meta EIP +. */ + 609: { + // gasPrices + modexpGquaddivisorGas: 20, // Gquaddivisor from modexp precompile for gas calculation + ecAddGas: 500, // Gas costs for curve addition precompile + ecMulGas: 40000, // Gas costs for curve multiplication precompile + ecPairingGas: 100000, // Base gas costs for curve pairing precompile + ecPairingWordGas: 80000, // Gas costs regarding curve pairing precompile input length + revertGas: 0, // Base fee of the REVERT opcode + staticcallGas: 700, // Base fee of the STATICCALL opcode + returndatasizeGas: 2, // Base fee of the RETURNDATASIZE opcode + returndatacopyGas: 3, // Base fee of the RETURNDATACOPY opcode + }, + /** +. * Constantinope HF Meta EIP +. */ + 1013: { + // gasPrices + netSstoreNoopGas: 200, // Once per SSTORE operation if the value doesn't change + netSstoreInitGas: 20000, // Once per SSTORE operation from clean zero + netSstoreCleanGas: 5000, // Once per SSTORE operation from clean non-zero + netSstoreDirtyGas: 200, // Once per SSTORE operation from dirty + netSstoreClearRefundGas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot + netSstoreResetRefundGas: 4800, // Once per SSTORE operation for resetting to the original non-zero value + netSstoreResetClearRefundGas: 19800, // Once per SSTORE operation for resetting to the original zero value + shlGas: 3, // Base fee of the SHL opcode + shrGas: 3, // Base fee of the SHR opcode + sarGas: 3, // Base fee of the SAR opcode + extcodehashGas: 400, // Base fee of the EXTCODEHASH opcode + create2Gas: 32000, // Base fee of the CREATE2 opcode + }, + /** +. * Petersburg HF Meta EIP +. */ + 1716: { + // gasPrices + netSstoreNoopGas: null, // Removed along EIP-1283 + netSstoreInitGas: null, // Removed along EIP-1283 + netSstoreCleanGas: null, // Removed along EIP-1283 + netSstoreDirtyGas: null, // Removed along EIP-1283 + netSstoreClearRefundGas: null, // Removed along EIP-1283 + netSstoreResetRefundGas: null, // Removed along EIP-1283 + netSstoreResetClearRefundGas: null, // Removed along EIP-1283 + }, + /** +. * Istanbul HF Meta EIP +. */ + 1679: { + // gasPrices + blake2RoundGas: 1, // Gas cost per round for the Blake2 F precompile + ecAddGas: 150, // Gas costs for curve addition precompile + ecMulGas: 6000, // Gas costs for curve multiplication precompile + ecPairingGas: 45000, // Base gas costs for curve pairing precompile + ecPairingWordGas: 34000, // Gas costs regarding curve pairing precompile input length + sstoreSentryEIP2200Gas: 2300, // Minimum gas required to be present for an SSTORE call, not consumed + sstoreNoopEIP2200Gas: 800, // Once per SSTORE operation if the value doesn't change + sstoreDirtyEIP2200Gas: 800, // Once per SSTORE operation if a dirty value is changed + sstoreInitEIP2200Gas: 20000, // Once per SSTORE operation from clean zero to non-zero + sstoreInitRefundEIP2200Gas: 19200, // Once per SSTORE operation for resetting to the original zero value + sstoreCleanEIP2200Gas: 5000, // Once per SSTORE operation from clean non-zero to something else + sstoreCleanRefundEIP2200Gas: 4200, // Once per SSTORE operation for resetting to the original non-zero value + sstoreClearRefundEIP2200Gas: 15000, // Once per SSTORE operation for clearing an originally existing storage slot + balanceGas: 700, // Base fee of the BALANCE opcode + extcodehashGas: 700, // Base fee of the EXTCODEHASH opcode + chainidGas: 2, // Base fee of the CHAINID opcode + selfbalanceGas: 5, // Base fee of the SELFBALANCE opcode + sloadGas: 800, // Base fee of the SLOAD opcode + }, + + /** +. * SWAPN, DUPN and EXCHANGE instructions +. */ + 663: { + // gasPrices + dupnGas: 3, // Base fee of the DUPN opcode + swapnGas: 3, // Base fee of the SWAPN opcode + exchangeGas: 3, // Base fee of the EXCHANGE opcode + }, + /** +. * Transient storage opcodes +. */ + 1153: { + // gasPrices + tstoreGas: 100, // Base fee of the TSTORE opcode + tloadGas: 100, // Base fee of the TLOAD opcode + }, + 1559: { + elasticityMultiplier: 2, // Maximum block gas target elasticity + }, + /** +. * ModExp gas cost +. */ + 2565: { + // gasPrices + modexpGquaddivisorGas: 3, // Gquaddivisor from modexp precompile for gas calculation + }, + /** + * BLS12-381 precompiles + */ + 2537: { + // gasPrices + Bls12381G1AddGas: 500, // Gas cost of a single BLS12-381 G1 addition precompile-call + Bls12381G1MulGas: 12000, // Gas cost of a single BLS12-381 G1 multiplication precompile-call + Bls12381G2AddGas: 800, // Gas cost of a single BLS12-381 G2 addition precompile-call + Bls12381G2MulGas: 45000, // Gas cost of a single BLS12-381 G2 multiplication precompile-call + Bls12381PairingBaseGas: 65000, // Base gas cost of BLS12-381 pairing check + Bls12381PairingPerPairGas: 43000, // Per-pair gas cost of BLS12-381 pairing check + Bls12381MapG1Gas: 5500, // Gas cost of BLS12-381 map field element to G1 + Bls12381MapG2Gas: 75000, // Gas cost of BLS12-381 map field element to G2 + }, + /** +. * Gas cost increases for state access opcodes +. */ + 2929: { + // gasPrices + coldsloadGas: 2100, // Gas cost of the first read of storage from a given location (per transaction) + coldaccountaccessGas: 2600, // Gas cost of the first read of a given address (per transaction) + warmstoragereadGas: 100, // Gas cost of reading storage locations which have already loaded 'cold' + sstoreCleanEIP2200Gas: 2900, // Once per SSTORE operation from clean non-zero to something else + sstoreNoopEIP2200Gas: 100, // Once per SSTORE operation if the value doesn't change + sstoreDirtyEIP2200Gas: 100, // Once per SSTORE operation if a dirty value is changed + sstoreInitRefundEIP2200Gas: 19900, // Once per SSTORE operation for resetting to the original zero value + sstoreCleanRefundEIP2200Gas: 4900, // Once per SSTORE operation for resetting to the original non-zero value + callGas: 0, // Base fee of the CALL opcode + callcodeGas: 0, // Base fee of the CALLCODE opcode + delegatecallGas: 0, // Base fee of the DELEGATECALL opcode + staticcallGas: 0, // Base fee of the STATICCALL opcode + balanceGas: 0, // Base fee of the BALANCE opcode + extcodesizeGas: 0, // Base fee of the EXTCODESIZE opcode + extcodecopyGas: 0, // Base fee of the EXTCODECOPY opcode + extcodehashGas: 0, // Base fee of the EXTCODEHASH opcode + sloadGas: 0, // Base fee of the SLOAD opcode + sstoreGas: 0, // Base fee of the SSTORE opcode + }, + /** + * Save historical block hashes in state (Verkle related usage, UNSTABLE) + */ + 2935: { + // evm + historyStorageAddress: '0x0aae40965e6800cd9b1f4b05ff21581047e3f91e', // The address where the historical blockhashes are stored + historyServeWindow: 8192, // The amount of blocks to be served by the historical blockhash contract + }, + /** +. * AUTH and AUTHCALL opcodes +. */ + 3074: { + // gasPrices + authGas: 3100, // Gas cost of the AUTH opcode + authcallGas: 0, // Gas cost of the AUTHCALL opcode + authcallValueTransferGas: 6700, // Paid for CALL when the value transfer is non-zero + }, + /** +. * BASEFEE opcode +. */ + 3198: { + // gasPrices + basefeeGas: 2, // Gas cost of the BASEFEE opcode + }, + /** +. * Reduction in refunds +. */ + 3529: { + // gasConfig + maxRefundQuotient: 5, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) + // gasPrices + selfdestructRefundGas: 0, // Refunded following a selfdestruct operation + sstoreClearRefundEIP2200Gas: 4800, // Once per SSTORE operation for clearing an originally existing storage slot + }, + /** +. * PUSH0 instruction +. */ + 3855: { + // gasPrices + push0Gas: 2, // Base fee of the PUSH0 opcode + }, + /** +. * Limit and meter initcode +. */ + 3860: { + // gasPrices + initCodeWordGas: 2, // Gas to pay for each word (32 bytes) of initcode when creating a contract + // vm + maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract + }, + /** + * EOF - Static relative jumps + */ + 4200: { + // gasPrices + rjumpGas: 2, // Base fee of the RJUMP opcode + rjumpiGas: 4, // Base fee of the RJUMPI opcode + rjumpvGas: 4, // Base fee of the RJUMPV opcode + }, + /** +. * Supplant DIFFICULTY opcode with PREVRANDAO +. */ + 4399: { + // gasPrices + prevrandaoGas: 2, // Base fee of the PREVRANDAO opcode (previously DIFFICULTY) + }, + /** + * EOF - Functions + */ + 4750: { + // gasPrices + callfGas: 5, // Base fee of the CALLF opcode + retfGas: 3, // Base fee of the RETF opcode + }, + /** +. * Shard Blob Transactions +. */ + 4844: { + kzgPointEvaluationPrecompileGas: 50000, // The fee associated with the point evaluation precompile + blobhashGas: 3, // Base fee of the BLOBHASH opcode + // sharding + blobCommitmentVersionKzg: 1, // The number indicated a versioned hash is a KZG commitment + fieldElementsPerBlob: 4096, // The number of field elements allowed per blob + }, + /** + * MCOPY - Memory copying instruction + */ + 5656: { + // gasPrices + mcopyGas: 3, // Base fee of the MCOPY opcode + }, + /** + * EOF - JUMPF and non-returning functions + */ + 6206: { + // gasPrices + jumpfGas: 5, // Base fee of the JUMPF opcode + }, + /** + * Ethereum state using a unified verkle tree (experimental) + */ + 6800: { + // gasPrices + createGas: 1000, // Base fee of the CREATE opcode + coldsloadGas: 0, // Gas cost of the first read of storage from a given location (per transaction) + }, + /** +. * Revamped CALL instructions +. */ + 7069: { + /* Note: per EIP these are the additionally required EIPs: + EIP 150 - This is the entire Tangerine Whistle hardfork + EIP 211 - (RETURNDATASIZE / RETURNDATACOPY) - Included in Byzantium + EIP 214 - (STATICCALL) - Included in Byzantium + */ + // gasPrices + extcallGas: 0, // Base fee of the EXTCALL opcode + extdelegatecallGas: 0, // Base fee of the EXTDELEGATECALL opcode + extstaticcallGas: 0, // Base fee of the EXTSTATICCALL opcode + returndataloadGas: 3, // Base fee of the RETURNDATALOAD opcode + minRetainedGas: 5000, // Minimum gas retained prior to executing an EXT*CALL opcode (this is the minimum gas available after performing the EXT*CALL) + minCalleeGas: 2300, //Minimum gas available to the the address called by an EXT*CALL opcode + }, + /** + * EOF - Data section access instructions + */ + 7480: { + // gasPrices + dataloadGas: 4, // Base fee of the DATALOAD opcode + dataloadnGas: 3, // Base fee of the DATALOADN opcode + datasizeGas: 2, // Base fee of the DATASIZE opcode + datacopyGas: 3, // Base fee of the DATACOPY opcode + }, + /** +. * BLOBBASEFEE opcode +. */ + 7516: { + // gasPrices + blobbasefeeGas: 2, // Gas cost of the BLOBBASEFEE opcode + }, + /** +. * EOF Contract Creation +. */ + 7620: { + /* Note: per EIP these are the additionally required EIPs: + EIP 170 - (Max contract size) - Included in Spurious Dragon + */ + // gasPrices + eofcreateGas: 32000, // Base fee of the EOFCREATE opcode (Same as CREATE/CREATE2) + returncontractGas: 0, // Base fee of the RETURNCONTRACT opcode + }, + /** +. * Set EOA account code for one transaction +. */ + 7702: { + // TODO: Set correct minimum hardfork + // gasPrices + perAuthBaseGas: 2500, // Gas cost of each authority item + }, +} diff --git a/packages/evm/src/types.ts b/packages/evm/src/types.ts index b8798befc4..4f001da07d 100644 --- a/packages/evm/src/types.ts +++ b/packages/evm/src/types.ts @@ -8,7 +8,12 @@ import type { AsyncDynamicGasHandler, SyncDynamicGasHandler } from './opcodes/ga import type { OpHandler } from './opcodes/index.js' import type { CustomPrecompile } from './precompiles/index.js' import type { PrecompileFunc } from './precompiles/types.js' -import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common' +import type { + AccessWitnessInterface, + Common, + EVMStateManagerInterface, + ParamsDict, +} from '@ethereumjs/common' import type { Account, Address, AsyncEventEmitter, PrefixedHexString } from '@ethereumjs/util' export type DeleteOpcode = { @@ -141,6 +146,7 @@ export type EVMEvents = { } export interface EVMInterface { + common: Common journal: { commit(): Promise revert(): Promise @@ -227,6 +233,24 @@ export interface EVMOpts { */ allowUnlimitedInitCodeSize?: boolean + /** + * EVM parameters sorted by EIP can be found in the exported `paramsEVM` dictionary, + * which is internally passed to the associated `@ethereumjs/common` instance which + * manages parameter selection based on the hardfork and EIP settings. + * + * This option allows providing a custom set of parameters. Note that parameters + * get fully overwritten, so you need to extend the default parameter dict + * to provide the full parameter set. + * + * It is recommended to deep-clone the params object for this to avoid side effects: + * + * ```ts + * const params = JSON.parse(JSON.stringify(paramsEVM)) + * params['1679']['ecAddGas'] = 100 // 150 + * ``` + */ + params?: ParamsDict + /** * Override or add custom opcodes to the EVM instruction set * These custom opcodes are EIP-agnostic and are always statically added diff --git a/packages/evm/test/evm.spec.ts b/packages/evm/test/evm.spec.ts new file mode 100644 index 0000000000..30197834dc --- /dev/null +++ b/packages/evm/test/evm.spec.ts @@ -0,0 +1,24 @@ +import { assert, describe, it } from 'vitest' + +import { createEVM, paramsEVM } from '../src/index.js' + +// TODO: This whole file was missing for quite some time and now (July 2024) +// has been side introduced along another PR. We should add basic initialization +// tests for options and the like. +describe('initialization', () => { + it('basic initialization', async () => { + const evm = await createEVM() + const msg = 'should use the correct parameter defaults' + assert.isFalse(evm.allowUnlimitedContractSize, msg) + }) + + it('EVM parameter customization', async () => { + let evm = await createEVM() + assert.equal(evm.common.param('ecAddGas'), BigInt(150), 'should use default EVM parameters') + + const params = JSON.parse(JSON.stringify(paramsEVM)) + params['1679']['ecAddGas'] = 100 // 150 + evm = await createEVM({ params }) + assert.equal(evm.common.param('ecAddGas'), BigInt(100), 'should use custom parameters provided') + }) +}) diff --git a/packages/evm/vite.config.bundler.ts b/packages/evm/vite.config.bundler.ts index 198b7cc30a..6efc4109c1 100644 --- a/packages/evm/vite.config.bundler.ts +++ b/packages/evm/vite.config.bundler.ts @@ -11,7 +11,7 @@ export default defineConfig({ treeshake: 'safest', }, lib: { - entry: 'src/index.ts', + entry: '../tx/examples/londonTx.ts', name: '@ethereumjs/evm', fileName: (format) => `ethereumjs-evm-bundle.${format}.js`, // only build for es diff --git a/packages/tx/src/1559/tx.ts b/packages/tx/src/1559/tx.ts index 464b255b2a..4ad508615a 100644 --- a/packages/tx/src/1559/tx.ts +++ b/packages/tx/src/1559/tx.ts @@ -13,6 +13,7 @@ import * as EIP1559 from '../capabilities/eip1559.js' import * as EIP2718 from '../capabilities/eip2718.js' import * as EIP2930 from '../capabilities/eip2930.js' import * as Legacy from '../capabilities/legacy.js' +import { paramsTx } from '../params.js' import { TransactionType } from '../types.js' import { AccessLists, validateNotArray } from '../util.js' @@ -59,6 +60,7 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction const createContract = this.to === undefined || this.to === null const allowUnlimitedInitCodeSize = opts.allowUnlimitedInitCodeSize ?? false const common = opts.common ?? this._getCommon() + common.updateParams(opts.params ?? paramsTx) if (createContract && common.isActivatedEIP(3860) && allowUnlimitedInitCodeSize === false) { checkMaxInitCodeSize(common, this.data.length) } diff --git a/packages/tx/src/index.ts b/packages/tx/src/index.ts index 7c89125bf5..d8fc984275 100644 --- a/packages/tx/src/index.ts +++ b/packages/tx/src/index.ts @@ -4,6 +4,8 @@ export * from './2930/index.js' export * from './4844/index.js' export * from './7702/index.js' export * from './legacy/index.js' +// Parameters +export * from './params.js' // Transaction factory export { diff --git a/packages/tx/src/legacy/tx.ts b/packages/tx/src/legacy/tx.ts index ffec6db20f..3db9f75ea7 100644 --- a/packages/tx/src/legacy/tx.ts +++ b/packages/tx/src/legacy/tx.ts @@ -13,6 +13,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { BaseTransaction } from '../baseTransaction.js' import * as Legacy from '../capabilities/legacy.js' +import { paramsTx } from '../index.js' import { Capability, TransactionType } from '../types.js' import { validateNotArray } from '../util.js' @@ -55,6 +56,7 @@ export class LegacyTransaction extends BaseTransaction { super({ ...txData, type: TransactionType.Legacy }, opts) this.common = this._validateTxV(this.v, opts.common) + this.common.updateParams(opts.params ?? paramsTx) this.keccakFunction = this.common.customCrypto.keccak256 ?? keccak256 this.gasPrice = bytesToBigInt(toBytes(txData.gasPrice)) diff --git a/packages/tx/src/params.ts b/packages/tx/src/params.ts new file mode 100644 index 0000000000..02f487b583 --- /dev/null +++ b/packages/tx/src/params.ts @@ -0,0 +1,46 @@ +import type { ParamsDict } from '@ethereumjs/common' + +export const paramsTx: ParamsDict = { + /** + * Frontier/Chainstart + */ + 1: { + // gasPrices + txGas: 21000, // Per transaction. NOTE: Not payable on data of calls between transactions + txCreationGas: 32000, // The cost of creating a contract via tx + txDataZeroGas: 4, // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions + txDataNonZeroGas: 68, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions + accessListStorageKeyGas: 0, + accessListAddressGas: 0, + }, + /** +. * Istanbul HF Meta EIP +. */ + 1679: { + // gasPrices + txDataNonZeroGas: 16, // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions + }, + /** +. * Optional access lists +. */ + 2930: { + // gasPrices + accessListStorageKeyGas: 1900, // Gas cost per storage key in an Access List transaction + accessListAddressGas: 2400, // Gas cost per storage key in an Access List transaction + }, + /** +. * Limit and meter initcode +. */ + 3860: { + // gasPrices + initCodeWordGas: 2, // Gas to pay for each word (32 bytes) of initcode when creating a contract + // format + maxInitCodeSize: 49152, // Maximum length of initialization code when creating a contract + }, + /** +. * Shard Blob Transactions +. */ + 4844: { + blobCommitmentVersionKzg: 1, // The number indicated a versioned hash is a KZG commitment + }, +} diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index f361532663..960fbc7719 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -12,6 +12,7 @@ import type { AuthorizationListBytes, Common, Hardfork, + ParamsDict, } from '@ethereumjs/common' import type { Address, @@ -82,6 +83,23 @@ export interface TxOptions { * Current default hardfork: `istanbul` */ common?: Common + /** + * Tx parameters sorted by EIP can be found in the exported `paramsTx` dictionary, + * which is internally passed to the associated `@ethereumjs/common` instance which + * manages parameter selection based on the hardfork and EIP settings. + * + * This option allows providing a custom set of parameters. Note that parameters + * get fully overwritten, so you need to extend the default parameter dict + * to provide the full parameter set. + * + * It is recommended to deep-clone the params object for this to avoid side effects: + * + * ```ts + * const params = JSON.parse(JSON.stringify(paramsTx)) + * params['1']['txGas'] = 30000 // 21000 + * ``` + */ + params?: ParamsDict /** * A transaction object by default gets frozen along initialization. This gives you * strong additional security guarantees on the consistency of the tx parameters. diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index 1f0d405449..0026c87bd1 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -27,6 +27,7 @@ import { createLegacyTx, createLegacyTxFromBytesArray, createLegacyTxFromRLP, + paramsTx, } from '../src/index.js' import eip1559Fixtures from './json/eip1559txs.json' @@ -147,6 +148,11 @@ describe('[BaseTransaction]', () => { `${txType.name}: tx should not be frozen when freeze deactivated in options`, ) + const params = JSON.parse(JSON.stringify(paramsTx)) + params['1']['txGas'] = 30000 // 21000 + tx = txType.create.txData({}, { common, params }) + assert.equal(tx.common.param('txGas'), BigInt(30000), 'should use custom parameters provided') + // Perform the same test as above, but now using a different construction method. This also implies that passing on the // options object works as expected. tx = txType.create.txData({}, { common, freeze: false }) diff --git a/packages/tx/test/eip3860.spec.ts b/packages/tx/test/eip3860.spec.ts index 8230db40aa..dfcc728476 100644 --- a/packages/tx/test/eip3860.spec.ts +++ b/packages/tx/test/eip3860.spec.ts @@ -2,12 +2,13 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { Address } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' -import { TransactionType, createTxFromTxData } from '../src/index.js' +import { TransactionType, createTxFromTxData, paramsTx } from '../src/index.js' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Paris, eips: [3860, 4844, 4895], + params: paramsTx, }) const maxInitCodeSize = common.param('maxInitCodeSize') diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index dbf8d5136c..1dcab18616 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -23,6 +23,7 @@ import { create2930AccessListTx, create2930AccessListTxFromBytesArray, create2930AccessListTxFromRLP, + paramsTx, } from '../src/index.js' import type { AccessList, AccessListBytesItem, JsonTx } from '../src/index.js' @@ -33,6 +34,7 @@ const address = privateToAddress(pKey) const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London, + params: paramsTx, }) const txTypes = [ diff --git a/packages/vm/src/index.ts b/packages/vm/src/index.ts index 15f81d9347..4c8c96a073 100644 --- a/packages/vm/src/index.ts +++ b/packages/vm/src/index.ts @@ -1,6 +1,7 @@ export { Bloom } from './bloom/index.js' export { BlockBuilder, BuildStatus } from './buildBlock.js' export { buildBlock } from './buildBlock.js' +export * from './params.js' export { encodeReceipt } from './runBlock.js' export { runBlock } from './runBlock.js' export { runTx } from './runTx.js' diff --git a/packages/vm/src/params.ts b/packages/vm/src/params.ts new file mode 100644 index 0000000000..3ee5fd980c --- /dev/null +++ b/packages/vm/src/params.ts @@ -0,0 +1,92 @@ +import type { ParamsDict } from '@ethereumjs/common' + +export const paramsVM: ParamsDict = { + /** + * Frontier/Chainstart + */ + 1: { + // gasConfig + maxRefundQuotient: 2, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) + blobGasPerBlob: 0, + maxblobGasPerBlock: 0, + // pow + minerReward: '5000000000000000000', // the amount a miner get rewarded for mining a block + }, + /** +. * Byzantium HF Meta EIP +. */ + 609: { + // pow + minerReward: '3000000000000000000', // the amount a miner get rewarded for mining a block + }, + /** +. * Constantinope HF Meta EIP +. */ + 1013: { + // pow + minerReward: '2000000000000000000', // The amount a miner gets rewarded for mining a block + }, + /** +. * Fee market change for ETH 1.0 chain +. */ + 1559: { + // gasConfig + elasticityMultiplier: 2, // Maximum block gas target elasticity + initialBaseFee: 1000000000, // Initial base fee on first EIP1559 block + }, + /** + * Save historical block hashes in state (Verkle related usage, UNSTABLE) + */ + 2935: { + // config + historyStorageAddress: '0x0aae40965e6800cd9b1f4b05ff21581047e3f91e', // The address where the historical blockhashes are stored + historyServeWindow: 8192, // The amount of blocks to be served by the historical blockhash contract + }, + /** +. * Reduction in refunds +. */ + 3529: { + // gasConfig + maxRefundQuotient: 5, // Maximum refund quotient; max tx refund is min(tx.gasUsed/maxRefundQuotient, tx.gasRefund) + }, + /** +. * Shard Blob Transactions +. */ + 4844: { + blobGasPerBlob: 131072, // The base fee for blob gas per blob + maxblobGasPerBlock: 786432, // The max blob gas allowable per block + }, + /** +. * Beacon block root in the EVM +. */ + 4788: { + // config + historicalRootsLength: 8191, // The modulo parameter of the beaconroot ring buffer in the beaconroot statefull precompile + }, + /** + * Ethereum state using a unified verkle tree (experimental) + */ + 6800: { + // kaustinen 6 current uses this address, however this will be updated to correct address + // in next iteration + // config + historyStorageAddress: '0xfffffffffffffffffffffffffffffffffffffffe', // The address where the historical blockhashes are stored + }, + /** + * Execution layer triggerable withdrawals (experimental) + */ + 7002: { + // config + systemAddress: '0xfffffffffffffffffffffffffffffffffffffffe', // The system address to perform operations on the withdrawal requests predeploy address + withdrawalRequestPredeployAddress: '0x00A3ca265EBcb825B45F985A16CEFB49958cE017', // Address of the validator excess address + }, + + /** + * Increase the MAX_EFFECTIVE_BALANCE -> Execution layer triggered consolidations (experimental) + */ + 7251: { + // config + systemAddress: '0xfffffffffffffffffffffffffffffffffffffffe', // The system address to perform operations on the consolidation requests predeploy address + consolidationRequestPredeployAddress: '0x00b42dbF2194e931E80326D950320f7d9Dbeac02', // Address of the consolidations contract + }, +} diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 128860c0fa..0ccba5a4f2 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -369,7 +369,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { // the signer must be able to afford the transaction // assert signer(tx).balance >= tx.message.gas * tx.message.max_fee_per_gas + get_total_data_gas(tx) * tx.message.max_fee_per_data_gas const castTx = tx as BlobEIP4844Transaction - totalblobGas = castTx.common.param('blobGasPerBlob') * BigInt(castTx.numBlobs()) + totalblobGas = vm.common.param('blobGasPerBlob') * BigInt(castTx.numBlobs()) maxCost += totalblobGas * castTx.maxFeePerBlobGas // 4844 minimum blobGas price check diff --git a/packages/vm/src/types.ts b/packages/vm/src/types.ts index 28e06ec4cd..c31c17547b 100644 --- a/packages/vm/src/types.ts +++ b/packages/vm/src/types.ts @@ -1,7 +1,7 @@ import type { Bloom } from './bloom/index.js' import type { Block, BlockOptions, HeaderData } from '@ethereumjs/block' import type { BlockchainInterface } from '@ethereumjs/blockchain' -import type { Common, EVMStateManagerInterface } from '@ethereumjs/common' +import type { Common, EVMStateManagerInterface, ParamsDict } from '@ethereumjs/common' import type { EVMInterface, EVMOpts, EVMResult, Log } from '@ethereumjs/evm' import type { AccessList, TypedTransaction } from '@ethereumjs/tx' import type { @@ -153,6 +153,23 @@ export interface VMOpts { * Default: `false` (HF is set to whatever default HF is set by the {@link Common} instance) */ setHardfork?: boolean | BigIntLike + /** + * VM parameters sorted by EIP can be found in the exported `paramsVM` dictionary, + * which is internally passed to the associated `@ethereumjs/common` instance which + * manages parameter selection based on the hardfork and EIP settings. + * + * This option allows providing a custom set of parameters. Note that parameters + * get fully overwritten, so you need to extend the default parameter dict + * to provide the full parameter set. + * + * It is recommended to deep-clone the params object for this to avoid side effects: + * + * ```ts + * const params = JSON.parse(JSON.stringify(paramsVM)) + * params['1559']['elasticityMultiplier'] = 10 // 2 + * ``` + */ + params?: ParamsDict /** * Use a custom EVM to run Messages on. If this is not present, use the default EVM. diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index 4fce2f5cc3..9050c6050b 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -10,6 +10,8 @@ import { unprefixedHexToBytes, } from '@ethereumjs/util' +import { paramsVM } from './params.js' + import type { VMEvents, VMOpts } from './types.js' import type { BlockchainInterface } from '@ethereumjs/blockchain' import type { EVMStateManagerInterface } from '@ethereumjs/common' @@ -158,6 +160,7 @@ export class VM { */ protected constructor(opts: VMOpts = {}) { this.common = opts.common! + this.common.updateParams(opts.params ?? paramsVM) this.stateManager = opts.stateManager! this.blockchain = opts.blockchain! this.evm = opts.evm! 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 b312f056c2..1eff605d0d 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 @@ -19,7 +19,7 @@ import { assert, describe, it } from 'vitest' import { bytesToBigInt } from '../../../../util/src/bytes.js' import { BIGINT_0 } from '../../../../util/src/constants.js' -import { VM, buildBlock, runBlock, runTx } from '../../../src/index.js' +import { VM, buildBlock, paramsVM, runBlock, runTx } from '../../../src/index.js' import type { Block } from '@ethereumjs/block' @@ -203,6 +203,7 @@ describe('EIP 2935: historical block hashes', () => { const blocksToBuild = 500 const commonGetHistoryServeWindow = eip2935ActiveAtCommon(0, historyAddressBigInt) commonGetHistoryServeWindow.setEIPs([2935]) + commonGetHistoryServeWindow.updateParams(paramsVM) const common = eip2935ActiveAtCommon(blocksActivation, historyAddressBigInt) const historyServeWindow = commonGetHistoryServeWindow.param('historyServeWindow') diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index 074141908f..c5323450ca 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -4,6 +4,7 @@ import { Account, Address, KECCAK256_RLP, hexToBytes } from '@ethereumjs/util' import * as util from 'util' // eslint-disable-line @typescript-eslint/no-unused-vars import { assert, describe, it } from 'vitest' +import { type VMOpts, paramsVM } from '../../src/index.js' import { VM } from '../../src/vm.js' import * as testnet from './testdata/testnet.json' @@ -11,7 +12,6 @@ import * as testnet2 from './testdata/testnet2.json' import * as testnetMerge from './testdata/testnetMerge.json' import { setupVM } from './utils.js' -import type { VMOpts } from '../../src/index.js' import type { ChainConfig } from '@ethereumjs/common' import type { DefaultStateManager } from '@ethereumjs/statemanager' @@ -141,14 +141,46 @@ describe('VM -> supportedHardforks', () => { const vm = await VM.create({ common }) assert.equal(vm.common.hardfork(), Hardfork.Byzantium) }) + + it('should overwrite parameters when param option is used', async () => { + let vm = await VM.create() + assert.equal( + vm.common.param('elasticityMultiplier'), + BigInt(2), + 'should use correct default EVM parameters', + ) + + const params = JSON.parse(JSON.stringify(paramsVM)) + params['1559']['elasticityMultiplier'] = 10 // 2 + vm = await VM.create({ params }) + assert.equal( + vm.common.param('elasticityMultiplier'), + BigInt(10), + 'should use custom parameters provided', + ) + + vm = await VM.create() + assert.equal( + vm.common.param('elasticityMultiplier'), + BigInt(2), + 'should again use the correct default EVM parameters', + ) + }) }) describe('VM -> common (chain, HFs, EIPs)', () => { it('should accept a common object as option', async () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) - const vm = await VM.create({ common }) + let vm = await VM.create({ common }) assert.equal(vm.common, common) + + vm = await VM.create() + assert.equal( + vm.common.param('elasticityMultiplier'), + BigInt(2), + 'should use correct default EVM parameters', + ) }) it('should only accept valid chain and fork', async () => { From 91270f538fb25f49aa7137b6b2bba637fa311c58 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Fri, 26 Jul 2024 13:05:27 +0200 Subject: [PATCH 23/58] StateManager: Interface Reworking & Partial Refactor (Options, Name Simplifications) (#3541) * Sort StateManagerInterface methods with comments, make getContractCodeSize() mandatory, clear legacy code * Move all types to a dedicated types.ts file (as we always do) * Option interface simplifications * Add explicit check for Verkle methods in EVM, associated clean-up * Rename putContractCode * Rename getContractCode, getContractCodeSize * Rename getContractStorage * Rename putContractStorage * Rename clearContractStorage --- packages/client/src/rpc/modules/eth.ts | 4 +- packages/common/src/interfaces.ts | 31 ++-- packages/evm/src/evm.ts | 17 +- packages/evm/src/interpreter.ts | 4 +- packages/evm/src/opcodes/functions.ts | 28 +--- packages/evm/src/opcodes/gas.ts | 2 +- packages/evm/test/blobVersionedHashes.spec.ts | 4 +- packages/evm/test/eips/eip-3860.spec.ts | 19 +-- packages/evm/test/eips/eof-runner.spec.ts | 2 +- .../evm/test/precompiles/09-blake2f.spec.ts | 2 +- packages/evm/test/runCall.spec.ts | 40 +++-- packages/evm/test/runCode.spec.ts | 4 +- packages/evm/test/stack.spec.ts | 2 +- .../examples/fromProofInstantiation.ts | 22 +-- .../src/cache/originalStorageCache.ts | 12 +- packages/statemanager/src/cache/storage.ts | 2 +- packages/statemanager/src/index.ts | 1 + packages/statemanager/src/rpcStateManager.ts | 32 ++-- .../statemanager/src/simpleStateManager.ts | 30 +--- packages/statemanager/src/stateManager.ts | 144 +++------------- .../src/statelessVerkleStateManager.ts | 91 ++-------- packages/statemanager/src/types.ts | 155 ++++++++++++++++++ .../test/checkpointing.code.spec.ts | 78 ++++----- .../test/checkpointing.storage.spec.ts | 82 +++++---- .../test/proofStateManager.spec.ts | 6 +- .../statemanager/test/rpcStateManager.spec.ts | 22 +-- .../test/stateManager.account.spec.ts | 8 +- .../test/stateManager.code.spec.ts | 46 +++--- .../statemanager/test/stateManager.spec.ts | 38 ++--- .../test/stateManager.storage.spec.ts | 28 ++-- .../test/statelessVerkleStateManager.spec.ts | 15 +- packages/statemanager/test/vmState.spec.ts | 20 +-- packages/vm/benchmarks/util.ts | 10 +- packages/vm/examples/run-blockchain.ts | 4 +- packages/vm/src/requests.ts | 4 +- packages/vm/src/runBlock.ts | 6 +- packages/vm/src/runTx.ts | 6 +- packages/vm/test/api/EIPs/eip-1153.spec.ts | 2 +- .../EIPs/eip-1283-net-gas-metering.spec.ts | 4 +- .../test/api/EIPs/eip-1559-FeeMarket.spec.ts | 2 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 4 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 2 +- .../eip-2935-historical-block-hashes.spec.ts | 6 +- .../test/api/EIPs/eip-3074-authcall.spec.ts | 34 ++-- packages/vm/test/api/EIPs/eip-3529.spec.ts | 8 +- packages/vm/test/api/EIPs/eip-3541.spec.ts | 14 +- packages/vm/test/api/EIPs/eip-3607.spec.ts | 4 +- .../api/EIPs/eip-3651-warm-coinbase.spec.ts | 2 +- .../test/api/EIPs/eip-4788-beaconroot.spec.ts | 6 +- .../api/EIPs/eip-4895-withdrawals.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-6110.spec.ts | 4 +- .../eip-6780-selfdestruct-same-tx.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-7702.spec.ts | 14 +- packages/vm/test/api/index.spec.ts | 4 +- .../vm/test/api/istanbul/eip-2200.spec.ts | 4 +- packages/vm/test/api/runBlock.spec.ts | 6 +- packages/vm/test/api/runTx.spec.ts | 12 +- .../vm/test/api/state/accountExists.spec.ts | 8 +- packages/vm/test/util.ts | 4 +- 59 files changed, 557 insertions(+), 618 deletions(-) create mode 100644 packages/statemanager/src/types.ts diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index afb2a8ca51..2d1f5b725c 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -738,7 +738,7 @@ export class Eth { await vm.stateManager.setStateRoot(block.header.stateRoot) const address = Address.fromString(addressHex) - const code = await vm.stateManager.getContractCode(address) + const code = await vm.stateManager.getCode(address) return bytesToHex(code) } @@ -784,7 +784,7 @@ export class Eth { return EMPTY_SLOT } const key = setLengthLeft(hexToBytes(keyHex), 32) - const storage = await vm.stateManager.getContractStorage(address, key) + const storage = await vm.stateManager.getStorage(address, key) return storage !== null && storage !== undefined ? bytesToHex(setLengthLeft(Uint8Array.from(storage) as Uint8Array, 32)) : EMPTY_SLOT diff --git a/packages/common/src/interfaces.ts b/packages/common/src/interfaces.ts index 113b5b47e9..e67fe0da76 100644 --- a/packages/common/src/interfaces.ts +++ b/packages/common/src/interfaces.ts @@ -148,31 +148,38 @@ export interface AccessWitnessInterface { * */ export interface StateManagerInterface { + // Account methods getAccount(address: Address): Promise putAccount(address: Address, account?: Account): Promise deleteAccount(address: Address): Promise modifyAccountFields(address: Address, accountFields: AccountFields): Promise - putContractCode(address: Address, value: Uint8Array): Promise - getContractCode(address: Address): Promise - getContractCodeSize?(address: Address): Promise - getContractStorage(address: Address, key: Uint8Array): Promise - putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise - clearContractStorage(address: Address): Promise + + // Code methods + putCode(address: Address, value: Uint8Array): Promise + getCode(address: Address): Promise + getCodeSize(address: Address): Promise + + // Storage methods + getStorage(address: Address, key: Uint8Array): Promise + putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise + clearStorage(address: Address): Promise + + // Checkpointing methods checkpoint(): Promise commit(): Promise revert(): Promise + + // State root methods getStateRoot(): Promise setStateRoot(stateRoot: Uint8Array, clearCache?: boolean): Promise - getProof?(address: Address, storageSlots: Uint8Array[]): Promise hasStateRoot(root: Uint8Array): Promise // only used in client + + // Other + getProof?(address: Address, storageSlots: Uint8Array[]): Promise shallowCopy(downlevelCaches?: boolean): StateManagerInterface getAppliedKey?(address: Uint8Array): Uint8Array - /* - * The following optional methods are Verkle related - * - * Experimental (do not implement) - */ + // Verkle (experimental) checkChunkWitnessPresent?(contract: Address, programCounter: number): Promise } diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index 1aed094c00..fc40cf017b 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -160,6 +160,17 @@ export class EVM implements EVMInterface { this.blockchain = opts.blockchain! this.stateManager = opts.stateManager! + if (this.common.isActivatedEIP(6800)) { + const mandatory = ['checkChunkWitnessPresent'] + for (const m of mandatory) { + if (!(m in this.stateManager)) { + throw new Error( + `State manager used must implement ${m} if Verkle (EIP-6800) is activated`, + ) + } + } + } + this._bn128 = bn128 this.events = new AsyncEventEmitter() this._optsCached = opts @@ -470,7 +481,7 @@ export class EVM implements EVMInterface { } await this.journal.putAccount(message.to, toAccount) - await this.stateManager.clearContractStorage(message.to) + await this.stateManager.clearStorage(message.to) const newContractEvent = { address: message.to, @@ -676,7 +687,7 @@ export class EVM implements EVMInterface { } } - await this.stateManager.putContractCode(message.to, result.returnValue) + await this.stateManager.putCode(message.to, result.returnValue) if (this.DEBUG) { debug(`Code saved on new contract creation`) } @@ -999,7 +1010,7 @@ export class EVM implements EVMInterface { message.code = precompile message.isCompiled = true } else { - message.code = await this.stateManager.getContractCode(message.codeAddress) + message.code = await this.stateManager.getCode(message.codeAddress) message.isCompiled = false message.chargeCodeAccesses = true } diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 8e2516b124..55e776f271 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -601,7 +601,7 @@ export class Interpreter { * Store 256-bit a value in memory to persistent storage. */ async storageStore(key: Uint8Array, value: Uint8Array): Promise { - await this._stateManager.putContractStorage(this._env.address, key, value) + await this._stateManager.putStorage(this._env.address, key, value) const account = await this._stateManager.getAccount(this._env.address) if (!account) { throw new Error('could not read account while persisting memory') @@ -618,7 +618,7 @@ export class Interpreter { if (original) { return this._stateManager.originalStorageCache.get(this._env.address, key) } else { - return this._stateManager.getContractStorage(this._env.address, key) + return this._stateManager.getStorage(this._env.address, key) } } diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 5976f9381e..8b8fc1fde0 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -524,26 +524,16 @@ export const handlers: Map = new Map([ const addressBigInt = runState.stack.pop() const address = new Address(addresstoBytes(addressBigInt)) // EOF check - const code = await runState.stateManager.getContractCode(address) + const code = await runState.stateManager.getCode(address) if (isEOF(code)) { // In legacy code, the target code is treated as to be "EOFBYTES" code runState.stack.push(BigInt(EOFBYTES.length)) return } - let size - if (typeof runState.stateManager.getContractCodeSize === 'function') { - size = BigInt( - await runState.stateManager.getContractCodeSize( - new Address(addresstoBytes(addressBigInt)), - ), - ) - } else { - size = BigInt( - (await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt)))) - .length, - ) - } + const size = BigInt( + await runState.stateManager.getCodeSize(new Address(addresstoBytes(addressBigInt))), + ) runState.stack.push(size) }, @@ -555,9 +545,7 @@ export const handlers: Map = new Map([ const [addressBigInt, memOffset, codeOffset, dataLength] = runState.stack.popN(4) if (dataLength !== BIGINT_0) { - let code = await runState.stateManager.getContractCode( - new Address(addresstoBytes(addressBigInt)), - ) + let code = await runState.stateManager.getCode(new Address(addresstoBytes(addressBigInt))) if (isEOF(code)) { // In legacy code, the target code is treated as to be "EOFBYTES" code @@ -579,7 +567,7 @@ export const handlers: Map = new Map([ const address = new Address(addresstoBytes(addressBigInt)) // EOF check - const code = await runState.stateManager.getContractCode(address) + const code = await runState.stateManager.getCode(address) if (isEOF(code)) { // In legacy code, the target code is treated as to be "EOFBYTES" code // Therefore, push the hash of EOFBYTES to the stack @@ -665,7 +653,7 @@ export const handlers: Map = new Map([ ) runState.interpreter.useGas(statelessGas, `BLOCKHASH`) } - const storage = await runState.stateManager.getContractStorage(historyAddress, key) + const storage = await runState.stateManager.getStorage(historyAddress, key) runState.stack.push(bytesToBigInt(storage)) } else { @@ -1674,7 +1662,7 @@ export const handlers: Map = new Map([ const toAddress = new Address(addresstoBytes(toAddr)) - const code = await runState.stateManager.getContractCode(toAddress) + const code = await runState.stateManager.getCode(toAddress) if (!isEOF(code)) { // EXTDELEGATECALL cannot call legacy contracts diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index dc0ad6e5bf..81cfae362c 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -230,7 +230,7 @@ export const dynamicGasHandlers: Map codeSize) { codeEnd = codeSize } diff --git a/packages/evm/test/blobVersionedHashes.spec.ts b/packages/evm/test/blobVersionedHashes.spec.ts index f8676be1aa..ef97c4bddf 100644 --- a/packages/evm/test/blobVersionedHashes.spec.ts +++ b/packages/evm/test/blobVersionedHashes.spec.ts @@ -51,7 +51,7 @@ describe(`BLOBHASH: access blobVersionedHashes within contract calls`, () => { const getBlobHasIndexCode = '0x60004960005260206000F3' const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // contract address - await evm.stateManager.putContractCode(contractAddress, hexToBytes(getBlobHasIndexCode)) // setup the contract code + await evm.stateManager.putCode(contractAddress, hexToBytes(getBlobHasIndexCode)) // setup the contract code const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) // caller address await evm.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x11111111))) // give the calling account a big balance so we don't run out of funds @@ -132,7 +132,7 @@ describe(`BLOBHASH: access blobVersionedHashes in a CREATE/CREATE2 frame`, () => const res = await evm.runCall(runCallArgs) const address = Address.fromString(bytesToHex(res.execResult.returnValue.slice(12))) - const code = await evm.stateManager.getContractCode(address) + const code = await evm.stateManager.getCode(address) assert.equal( bytesToHex(code), diff --git a/packages/evm/test/eips/eip-3860.spec.ts b/packages/evm/test/eips/eip-3860.spec.ts index 394643bb90..09992f364a 100644 --- a/packages/evm/test/eips/eip-3860.spec.ts +++ b/packages/evm/test/eips/eip-3860.spec.ts @@ -68,8 +68,8 @@ describe('EIP 3860 tests', () => { '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a8160006000f05a8203600a55806000556001600155505050', ) - await evm.stateManager.putContractCode(contractFactory, factoryCode) - await evmWithout3860.stateManager.putContractCode(contractFactory, factoryCode) + await evm.stateManager.putCode(contractFactory, factoryCode) + await evmWithout3860.stateManager.putCode(contractFactory, factoryCode) const data = hexToBytes('0x000000000000000000000000000000000000000000000000000000000000c000') const runCallArgs = { from: caller, @@ -112,8 +112,8 @@ describe('EIP 3860 tests', () => { '0x7f600a80600080396000f3000000000000000000000000000000000000000000006000526000355a60008260006000f55a8203600a55806000556001600155505050', ) - await evm.stateManager.putContractCode(contractFactory, factoryCode) - await evmWithout3860.stateManager.putContractCode(contractFactory, factoryCode) + await evm.stateManager.putCode(contractFactory, factoryCode) + await evmWithout3860.stateManager.putCode(contractFactory, factoryCode) const data = hexToBytes('0x000000000000000000000000000000000000000000000000000000000000c000') const runCallArgs = { from: caller, @@ -190,8 +190,8 @@ describe('EIP 3860 tests', () => { // This is either the contract address if it was succesful, or 0 in case of error const factoryCode = hexToBytes(`0x600060003560006000${code}600055`) - await evm.stateManager.putContractCode(contractFactory, factoryCode) - await evmDisabled.stateManager.putContractCode(contractFactory, factoryCode) + await evm.stateManager.putCode(contractFactory, factoryCode) + await evmDisabled.stateManager.putCode(contractFactory, factoryCode) const runCallArgs = { from: caller, @@ -204,11 +204,8 @@ describe('EIP 3860 tests', () => { await evmDisabled.runCall(runCallArgs) const key0 = hexToBytes(`0x${'00'.repeat(32)}`) - const storageActive = await evm.stateManager.getContractStorage(contractFactory, key0) - const storageInactive = await evmDisabled.stateManager.getContractStorage( - contractFactory, - key0, - ) + const storageActive = await evm.stateManager.getStorage(contractFactory, key0) + const storageInactive = await evmDisabled.stateManager.getStorage(contractFactory, key0) assert.ok( !equalsBytes(storageActive, new Uint8Array()), diff --git a/packages/evm/test/eips/eof-runner.spec.ts b/packages/evm/test/eips/eof-runner.spec.ts index 574a1bf1bf..6cfa643585 100644 --- a/packages/evm/test/eips/eof-runner.spec.ts +++ b/packages/evm/test/eips/eof-runner.spec.ts @@ -23,7 +23,7 @@ describe('EOF: should run a simple contract', async () => { const caller = new Address(hexToBytes('0x00000000000000000000000000000000000000ee')) // caller address const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) // contract address - await evm.stateManager.putContractCode(contractAddress, code) + await evm.stateManager.putCode(contractAddress, code) await evm.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x11111111))) const runCallArgs = { diff --git a/packages/evm/test/precompiles/09-blake2f.spec.ts b/packages/evm/test/precompiles/09-blake2f.spec.ts index a502e1fa91..21a1390896 100644 --- a/packages/evm/test/precompiles/09-blake2f.spec.ts +++ b/packages/evm/test/precompiles/09-blake2f.spec.ts @@ -136,7 +136,7 @@ describe('Precompiles: BLAKE2F', () => { // -> Calls Blake2F with this data (so, with the calldata) // -> Returns the data from Blake2F const code = `0x366000602037600080366020600060095AF1593D6000593E3D90F3` - await evm.stateManager.putContractCode(addr, hexToBytes(code)) + await evm.stateManager.putCode(addr, hexToBytes(code)) const res = await evm.runCall({ data: hexToBytes(calldata), diff --git a/packages/evm/test/runCall.spec.ts b/packages/evm/test/runCall.spec.ts index bdd2a3f899..0e59c6633c 100644 --- a/packages/evm/test/runCall.spec.ts +++ b/packages/evm/test/runCall.spec.ts @@ -70,7 +70,7 @@ describe('RunCall tests', () => { RETURN [0x00, 0x20] */ - await evm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code + await evm.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code await evm.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x11111111))) // give the calling account a big balance so we don't run out of funds const codeHash = keccak256(new Uint8Array()) for (let value = 0; value <= 1000; value += 20) { @@ -122,8 +122,8 @@ describe('RunCall tests', () => { STOP */ - await evmByzantium.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code - await evmConstantinople.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code + await evmByzantium.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code + await evmConstantinople.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code const runCallArgs = { caller, // call address @@ -174,8 +174,8 @@ describe('RunCall tests', () => { */ - await evm.stateManager.putContractCode(address, hexToBytes(code)) - await evm.stateManager.putContractStorage( + await evm.stateManager.putCode(address, hexToBytes(code)) + await evm.stateManager.putStorage( address, new Uint8Array(32), hexToBytes(`0x${'00'.repeat(31)}01`), @@ -204,7 +204,7 @@ describe('RunCall tests', () => { // push 1 push 0 sstore stop const code = '0x600160015500' - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) // setup the call arguments const runCallArgs = { @@ -229,7 +229,7 @@ describe('RunCall tests', () => { // code to call 0x00..00dd, which does not exist const code = '0x6000600060006000600060DD61FFFF5A03F100' - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) // setup the call arguments const runCallArgs = { @@ -257,7 +257,7 @@ describe('RunCall tests', () => { // but using too much memory const code = '0x61FFFF60FF60006000600060EE6000F200' - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) // setup the call arguments const runCallArgs = { @@ -285,7 +285,7 @@ describe('RunCall tests', () => { // this should thus go OOG const code = '0x60FEFF' - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) // setup the call arguments const runCallArgs = { @@ -314,7 +314,7 @@ describe('RunCall tests', () => { const code = '0x3460005500' await evm.stateManager.putAccount(caller, new Account()) - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) const account = await evm.stateManager.getAccount(caller) account!.balance = BigInt(100) @@ -388,7 +388,7 @@ describe('RunCall tests', () => { STOP */ - await evm.stateManager.putContractCode(address, hexToBytes(code)) + await evm.stateManager.putCode(address, hexToBytes(code)) const account = await evm.stateManager.getAccount(address) account!.nonce = MAX_UINT64 - BigInt(1) @@ -402,7 +402,7 @@ describe('RunCall tests', () => { } await evm.runCall(runCallArgs) - let storage = await evm.stateManager.getContractStorage(address, slot) + let storage = await evm.stateManager.getStorage(address, slot) // The nonce is MAX_UINT64 - 1, so we are allowed to create a contract (nonce of creating contract is now MAX_UINT64) assert.notDeepEqual(storage, emptyBytes, 'successfully created contract') @@ -410,7 +410,7 @@ describe('RunCall tests', () => { await evm.runCall(runCallArgs) // The nonce is MAX_UINT64, so we are NOT allowed to create a contract (nonce of creating contract is now MAX_UINT64) - storage = await evm.stateManager.getContractStorage(address, slot) + storage = await evm.stateManager.getStorage(address, slot) assert.deepEqual( storage, emptyBytes, @@ -448,7 +448,7 @@ describe('RunCall tests', () => { '0x00000000000000000000000028373a29d17af317e669579d97e7dddc9da6e3e2e7dddc9da6e3e200000000000000000000000000000000000000000000000000' assert.equal(result.createdAddress?.toString(), expectedAddress, 'created address correct') - const deployedCode = await evm.stateManager.getContractCode(result.createdAddress!) + const deployedCode = await evm.stateManager.getCode(result.createdAddress!) assert.equal(bytesToHex(deployedCode), expectedCode, 'deployed code correct') }) @@ -481,7 +481,7 @@ describe('RunCall tests', () => { // runCall against a contract to reach `_reduceSenderBalance` const contractCode = hexToBytes('0x00') // 00: STOP const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') - await evm.stateManager.putContractCode(contractAddress, contractCode) + await evm.stateManager.putCode(contractAddress, contractCode) const senderKey = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) @@ -616,7 +616,7 @@ describe('RunCall tests', () => { const contractCode = hexToBytes('0x600060405200') // PUSH 0 PUSH 40 MSTORE STOP const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') - await evm.stateManager.putContractCode(contractAddress, contractCode) + await evm.stateManager.putCode(contractAddress, contractCode) const runCallArgs = { gasLimit: BigInt(21000), @@ -730,10 +730,10 @@ describe('RunCall tests', () => { const callerCode = hexToBytes(`0x60008080808061AAAA61${gasLimit}f1600055`) await evm.stateManager.putAccount(callCodeAddress, new Account()) - await evm.stateManager.putContractCode(callCodeAddress, callCode) + await evm.stateManager.putCode(callCodeAddress, callCode) await evm.stateManager.putAccount(callerAddress, new Account(undefined, BigInt(1))) - await evm.stateManager.putContractCode(callerAddress, callerCode) + await evm.stateManager.putCode(callerAddress, callerCode) const runCallArgs = { to: callerAddress, @@ -741,9 +741,7 @@ describe('RunCall tests', () => { } await evm.runCall(runCallArgs) - const callResult = bytesToHex( - await evm.stateManager.getContractStorage(callerAddress, zeros(32)), - ) + const callResult = bytesToHex(await evm.stateManager.getStorage(callerAddress, zeros(32))) // Expect slot to have value of either: 0 since CALLCODE and CODE did not have enough gas to execute // Or 1, if CALL(CODE) has enough gas to enter the new call frame assert.equal(callResult, expectedOutput, `should have result ${expectedOutput}`) diff --git a/packages/evm/test/runCode.spec.ts b/packages/evm/test/runCode.spec.ts index c63560fa9f..00eafbb573 100644 --- a/packages/evm/test/runCode.spec.ts +++ b/packages/evm/test/runCode.spec.ts @@ -77,14 +77,14 @@ describe('VM.runCode: interpreter', () => { it('should throw on non-EvmError', async () => { const evm = await createEVM() - // NOTE: due to now throwing on `getContractStorage` if account does not exist + // 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) // does not exist, then if SSTORE/SLOAD is used, the runCode will immediately fail because StateManager now throws // TODO: is this behavior which we should fix? (Either in StateManager OR in runCode where we load the account first, // then re-put the account after (if account === undefined put empty account, such that the account exists)) const address = Address.fromString(`0x${'00'.repeat(20)}`) await evm.stateManager.putAccount(address, new Account()) - evm.stateManager.putContractStorage = (..._args) => { + evm.stateManager.putStorage = (..._args) => { throw new Error('Test') } diff --git a/packages/evm/test/stack.spec.ts b/packages/evm/test/stack.spec.ts index 4e0fe7e6f0..ed75419f04 100644 --- a/packages/evm/test/stack.spec.ts +++ b/packages/evm/test/stack.spec.ts @@ -122,7 +122,7 @@ describe('Stack', () => { RETURN stack: [0, 0x20] (we thus return the stack item which was originally pushed as 0, and then DUPed) */ await evm.stateManager.putAccount(addr, account) - await evm.stateManager.putContractCode(addr, hexToBytes(code)) + await evm.stateManager.putCode(addr, hexToBytes(code)) await evm.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x11))) const runCallArgs = { caller, diff --git a/packages/statemanager/examples/fromProofInstantiation.ts b/packages/statemanager/examples/fromProofInstantiation.ts index 97df90f29c..2e1117f9c8 100644 --- a/packages/statemanager/examples/fromProofInstantiation.ts +++ b/packages/statemanager/examples/fromProofInstantiation.ts @@ -15,9 +15,9 @@ const main = async () => { const storageValue1 = hexToBytes('0x01') const storageValue2 = hexToBytes('0x02') - await stateManager.putContractCode(contractAddress, byteCode) - await stateManager.putContractStorage(contractAddress, storageKey1, storageValue1) - await stateManager.putContractStorage(contractAddress, storageKey2, storageValue2) + await stateManager.putCode(contractAddress, byteCode) + await stateManager.putStorage(contractAddress, storageKey1, storageValue1) + await stateManager.putStorage(contractAddress, storageKey2, storageValue2) const proof = await stateManager.getProof(contractAddress) const proofWithStorage = await stateManager.getProof(contractAddress, [storageKey1, storageKey2]) @@ -25,22 +25,16 @@ const main = async () => { // To add more proof data, use `addProofData` await partialStateManager.addProofData(proofWithStorage) - console.log(await partialStateManager.getContractCode(contractAddress)) // contract bytecode is not included in proof - console.log( - await partialStateManager.getContractStorage(contractAddress, storageKey1), - storageValue1, - ) // should match - console.log( - await partialStateManager.getContractStorage(contractAddress, storageKey2), - storageValue2, - ) // should match + console.log(await partialStateManager.getCode(contractAddress)) // contract bytecode is not included in proof + console.log(await partialStateManager.getStorage(contractAddress, storageKey1), storageValue1) // should match + console.log(await partialStateManager.getStorage(contractAddress, storageKey2), storageValue2) // should match const accountFromNewSM = await partialStateManager.getAccount(contractAddress) const accountFromOldSM = await stateManager.getAccount(contractAddress) console.log(accountFromNewSM, accountFromOldSM) // should match - const slot1FromNewSM = await stateManager.getContractStorage(contractAddress, storageKey1) - const slot2FromNewSM = await stateManager.getContractStorage(contractAddress, storageKey2) + const slot1FromNewSM = await stateManager.getStorage(contractAddress, storageKey1) + const slot2FromNewSM = await stateManager.getStorage(contractAddress, storageKey2) console.log(slot1FromNewSM, storageValue1) // should match console.log(slot2FromNewSM, storageValue2) // should match } diff --git a/packages/statemanager/src/cache/originalStorageCache.ts b/packages/statemanager/src/cache/originalStorageCache.ts index dd837be4e3..b7093ac9bd 100644 --- a/packages/statemanager/src/cache/originalStorageCache.ts +++ b/packages/statemanager/src/cache/originalStorageCache.ts @@ -2,23 +2,23 @@ import { bytesToUnprefixedHex } from '@ethereumjs/util' import type { Address } from '@ethereumjs/util' -type getContractStorage = (address: Address, key: Uint8Array) => Promise +type getStorage = (address: Address, key: Uint8Array) => Promise /** * Helper class to cache original storage values (so values already being present in * the pre-state of a call), mainly for correct gas cost calculation in EVM/VM. * - * TODO: Usage of this class is very implicit through the injected `getContractStorage()` + * TODO: Usage of this class is very implicit through the injected `getStorage()` * method bound to the calling state manager. It should be examined if there are alternative * designs being more transparent and direct along the next breaking release round. * */ export class OriginalStorageCache { private map: Map> - private getContractStorage: getContractStorage - constructor(getContractStorage: getContractStorage) { + private getStorage: getStorage + constructor(getStorage: getStorage) { this.map = new Map() - this.getContractStorage = getContractStorage + this.getStorage = getStorage } async get(address: Address, key: Uint8Array): Promise { @@ -31,7 +31,7 @@ export class OriginalStorageCache { return value } } - const value = await this.getContractStorage(address, key) + const value = await this.getStorage(address, key) this.put(address, key, value) return value } diff --git a/packages/statemanager/src/cache/storage.ts b/packages/statemanager/src/cache/storage.ts index cf24607219..345e74ad3b 100644 --- a/packages/statemanager/src/cache/storage.ts +++ b/packages/statemanager/src/cache/storage.ts @@ -172,7 +172,7 @@ export class StorageCache extends Cache { * Deletes all storage slots for address from the cache * @param address */ - clearContractStorage(address: Address): void { + clearStorage(address: Address): void { const addressHex = bytesToUnprefixedHex(address.bytes) if (this._lruCache) { this._lruCache!.set(addressHex, new Map()) diff --git a/packages/statemanager/src/index.ts b/packages/statemanager/src/index.ts index d6d3d9c56a..b0059ad440 100644 --- a/packages/statemanager/src/index.ts +++ b/packages/statemanager/src/index.ts @@ -4,3 +4,4 @@ export * from './rpcStateManager.js' export * from './simpleStateManager.js' export * from './statelessVerkleStateManager.js' export * from './stateManager.js' +export * from './types.js' diff --git a/packages/statemanager/src/rpcStateManager.ts b/packages/statemanager/src/rpcStateManager.ts index 3c4f9570d5..71ef9d06ef 100644 --- a/packages/statemanager/src/rpcStateManager.ts +++ b/packages/statemanager/src/rpcStateManager.ts @@ -18,7 +18,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { AccountCache, CacheType, OriginalStorageCache, StorageCache } from './cache/index.js' -import type { Proof } from './index.js' +import type { Proof, RPCStateManagerOpts } from './index.js' import type { AccountFields, EVMStateManagerInterface, @@ -28,16 +28,6 @@ import type { import type { Address, PrefixedHexString } from '@ethereumjs/util' import type { Debugger } from 'debug' -export interface RPCStateManagerOpts { - provider: string - blockTag: bigint | 'earliest' - - /** - * The common to use - */ - common?: Common -} - const KECCAK256_RLP_EMPTY_ACCOUNT = RLP.encode(new Account().serialize()).slice(2) export class RPCStateManager implements EVMStateManagerInterface { @@ -71,7 +61,7 @@ export class RPCStateManager implements EVMStateManagerInterface { this._storageCache = new StorageCache({ size: 100000, type: CacheType.ORDERED_MAP }) this._accountCache = new AccountCache({ size: 100000, type: CacheType.ORDERED_MAP }) - this.originalStorageCache = new OriginalStorageCache(this.getContractStorage.bind(this)) + this.originalStorageCache = new OriginalStorageCache(this.getStorage.bind(this)) this.common = opts.common ?? new Common({ chain: Chain.Mainnet }) this.keccakFunction = opts.common?.customCrypto.keccak256 ?? keccak256 } @@ -125,7 +115,7 @@ export class RPCStateManager implements EVMStateManagerInterface { * @returns {Promise} - Resolves with the code corresponding to the provided address. * Returns an empty `Uint8Array` if the account has no associated code. */ - async getContractCode(address: Address): Promise { + async getCode(address: Address): Promise { let codeBytes = this._contractCache.get(address.toString()) if (codeBytes !== undefined) return codeBytes const code = await fetchFromProvider(this._provider, { @@ -137,8 +127,8 @@ export class RPCStateManager implements EVMStateManagerInterface { return codeBytes } - async getContractCodeSize(address: Address): Promise { - const contractCode = await this.getContractCode(address) + async getCodeSize(address: Address): Promise { + const contractCode = await this.getCode(address) return contractCode.length } @@ -148,7 +138,7 @@ export class RPCStateManager implements EVMStateManagerInterface { * @param address - Address of the `account` to add the `code` for * @param value - The value of the `code` */ - async putContractCode(address: Address, value: Uint8Array): Promise { + async putCode(address: Address, value: Uint8Array): Promise { // Store contract code in the cache this._contractCache.set(address.toString(), value) } @@ -162,7 +152,7 @@ export class RPCStateManager implements EVMStateManagerInterface { * corresponding to the provided address at the provided key. * If this does not exist an empty `Uint8Array` is returned. */ - async getContractStorage(address: Address, key: Uint8Array): Promise { + async getStorage(address: Address, key: Uint8Array): Promise { // Check storage slot in cache if (key.length !== 32) { throw new Error('Storage key must be 32 bytes long') @@ -180,7 +170,7 @@ export class RPCStateManager implements EVMStateManagerInterface { }) value = toBytes(storage) - await this.putContractStorage(address, key, value) + await this.putStorage(address, key, value) return value } @@ -193,7 +183,7 @@ export class RPCStateManager implements EVMStateManagerInterface { * Cannot be more than 32 bytes. Leading zeros are stripped. * If it is empty or filled with zeros, deletes the value. */ - async putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { + async putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { this._storageCache.put(address, key, value) } @@ -201,8 +191,8 @@ export class RPCStateManager implements EVMStateManagerInterface { * Clears all storage entries for the account corresponding to `address`. * @param address - Address to clear the storage of */ - async clearContractStorage(address: Address): Promise { - this._storageCache.clearContractStorage(address) + async clearStorage(address: Address): Promise { + this._storageCache.clearStorage(address) } /** diff --git a/packages/statemanager/src/simpleStateManager.ts b/packages/statemanager/src/simpleStateManager.ts index f9976f3f71..8169bbb1b5 100644 --- a/packages/statemanager/src/simpleStateManager.ts +++ b/packages/statemanager/src/simpleStateManager.ts @@ -3,6 +3,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { OriginalStorageCache } from './cache/originalStorageCache.js' +import type { SimpleStateManagerOpts } from './index.js' import type { AccountFields, Common, @@ -13,16 +14,6 @@ import type { } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' -/** - * Options for constructing a {@link SimpleStateManager}. - */ -export interface SimpleStateManagerOpts { - /** - * The common to use - */ - common?: Common -} - /** * Simple and dependency-free state manager for basic state access use cases * where a merkle-patricia or verkle tree backed state manager is too heavy-weight. @@ -52,7 +43,7 @@ export class SimpleStateManager implements EVMStateManagerInterface { constructor(opts: SimpleStateManagerOpts = {}) { this.checkpointSync() - this.originalStorageCache = new OriginalStorageCache(this.getContractStorage.bind(this)) + this.originalStorageCache = new OriginalStorageCache(this.getStorage.bind(this)) this.common = opts.common } @@ -105,11 +96,11 @@ export class SimpleStateManager implements EVMStateManagerInterface { await this.putAccount(address, account) } - async getContractCode(address: Address): Promise { + async getCode(address: Address): Promise { return this.topCodeStack().get(address.toString()) ?? new Uint8Array(0) } - async putContractCode(address: Address, value: Uint8Array): Promise { + async putCode(address: Address, value: Uint8Array): Promise { this.topCodeStack().set(address.toString(), value) if ((await this.getAccount(address)) === undefined) { await this.putAccount(address, new Account()) @@ -119,18 +110,18 @@ export class SimpleStateManager implements EVMStateManagerInterface { }) } - async getContractCodeSize(address: Address): Promise { - const contractCode = await this.getContractCode(address) + async getCodeSize(address: Address): Promise { + const contractCode = await this.getCode(address) return contractCode.length } - async getContractStorage(address: Address, key: Uint8Array): Promise { + async getStorage(address: Address, key: Uint8Array): Promise { return ( this.topStorageStack().get(`${address.toString()}_${bytesToHex(key)}`) ?? new Uint8Array(0) ) } - async putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { + async putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { this.topStorageStack().set(`${address.toString()}_${bytesToHex(key)}`, value) } @@ -174,12 +165,9 @@ export class SimpleStateManager implements EVMStateManagerInterface { } // Only goes for long term create situations, skip - async clearContractStorage(): Promise {} + async clearStorage(): Promise {} // Only "core" methods implemented - checkChunkWitnessPresent?(): Promise { - throw new Error('Method not implemented.') - } dumpStorage(): Promise { throw new Error('Method not implemented.') } diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 25d7c93068..ab1435118f 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -21,7 +21,6 @@ import { toBytes, unpadBytes, unprefixedHexToBytes, - utf8ToBytes, } from '@ethereumjs/util' import debugDefault from 'debug' import { keccak256 } from 'ethereum-cryptography/keccak.js' @@ -34,124 +33,19 @@ import { StorageCache, } from './cache/index.js' +import { CODEHASH_PREFIX, type CacheSettings, type DefaultStateManagerOpts } from './index.js' + +import type { StorageProof } from './index.js' import type { AccountFields, EVMStateManagerInterface, + Proof, StorageDump, StorageRange, } from '@ethereumjs/common' import type { DB, PrefixedHexString } from '@ethereumjs/util' import type { Debugger } from 'debug' -export type StorageProof = { - key: PrefixedHexString - proof: PrefixedHexString[] - value: PrefixedHexString -} - -export type Proof = { - address: PrefixedHexString - balance: PrefixedHexString - codeHash: PrefixedHexString - nonce: PrefixedHexString - storageHash: PrefixedHexString - accountProof: PrefixedHexString[] - storageProof: StorageProof[] -} - -type CacheOptions = { - /** - * Allows for cache deactivation - * - * Depending on the use case and underlying datastore (and eventual concurrent cache - * mechanisms there), usage with or without cache can be faster - * - * Default: false - */ - deactivate?: boolean - - /** - * Cache type to use. - * - * Available options: - * - * ORDERED_MAP: Cache with no fixed upper bound and dynamic allocation, - * use for dynamic setups like testing or similar. - * - * LRU: LRU cache with pre-allocation of memory and a fixed size. - * Use for larger and more persistent caches. - */ - type?: CacheType - - /** - * Size of the cache (only for LRU cache) - * - * Default: 100000 (account cache) / 20000 (storage cache) / 20000 (code cache) - * - * Note: the cache/trie interplay mechanism is designed in a way that - * the theoretical number of max modified accounts between two flush operations - * should be smaller than the cache size, otherwise the cache will "forget" the - * old modifications resulting in an incomplete set of trie-flushed accounts. - */ - size?: number -} - -type CacheSettings = { - deactivate: boolean - type: CacheType - size: number -} - -/** - * Prefix to distinguish between a contract deployed with code `0x80` - * and `RLP([])` (also having the value `0x80`). - * - * Otherwise the creation of the code hash for the `0x80` contract - * will be the same as the hash of the empty trie which leads to - * misbehaviour in the underlying trie library. - */ -export const CODEHASH_PREFIX = utf8ToBytes('c') - -/** - * Options for constructing a {@link StateManager}. - */ -export interface DefaultStateManagerOpts { - /** - * A {@link Trie} instance - */ - trie?: Trie - /** - * Option to prefix codehashes in the database. This defaults to `true`. - * If this is disabled, note that it is possible to corrupt the trie, by deploying code - * which code is equal to the preimage of a trie-node. - * E.g. by putting the code `0x80` into the empty trie, will lead to a corrupted trie. - */ - prefixCodeHashes?: boolean - - /** - * Option to prefix the keys for the storage tries with the first 7 bytes from the - * associated account address. Activating this option gives a noticeable performance - * boost for storage DB reads when operating on larger tries. - * - * Note: Activating/deactivating this option causes continued state reads to be - * incompatible with existing databases. - * - * Default: false (for backwards compatibility reasons) - */ - prefixStorageTrieKeys?: boolean - - accountCacheOpts?: CacheOptions - - storageCacheOpts?: CacheOptions - - codeCacheOpts?: CacheOptions - - /** - * The common to use - */ - common?: Common -} - /** * Default StateManager implementation for the VM. * @@ -220,7 +114,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { this.keccakFunction = opts.common?.customCrypto.keccak256 ?? keccak256 - this.originalStorageCache = new OriginalStorageCache(this.getContractStorage.bind(this)) + this.originalStorageCache = new OriginalStorageCache(this.getStorage.bind(this)) this._prefixCodeHashes = opts.prefixCodeHashes ?? true this._prefixStorageTrieKeys = opts.prefixStorageTrieKeys ?? false @@ -352,7 +246,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { this._accountCache!.del(address) } if (!this._storageCacheSettings.deactivate) { - this._storageCache?.clearContractStorage(address) + this._storageCache?.clearStorage(address) } } @@ -362,7 +256,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { * @param address - Address of the `account` to add the `code` for * @param value - The value of the `code` */ - async putContractCode(address: Address, value: Uint8Array): Promise { + async putCode(address: Address, value: Uint8Array): Promise { this._codeCache?.put(address, value) const codeHash = this.keccakFunction(value) @@ -382,7 +276,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { * @returns {Promise} - Resolves with the code corresponding to the provided address. * Returns an empty `Uint8Array` if the account has no associated code. */ - async getContractCode(address: Address): Promise { + async getCode(address: Address): Promise { if (!this._codeCacheSettings.deactivate) { const elem = this._codeCache?.get(address) if (elem !== undefined) { @@ -407,8 +301,8 @@ export class DefaultStateManager implements EVMStateManagerInterface { return code } - async getContractCodeSize(address: Address): Promise { - const contractCode = await this.getContractCode(address) + async getCodeSize(address: Address): Promise { + const contractCode = await this.getCode(address) return contractCode.length } @@ -479,7 +373,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { * corresponding to the provided address at the provided key. * If this does not exist an empty `Uint8Array` is returned. */ - async getContractStorage(address: Address, key: Uint8Array): Promise { + async getStorage(address: Address, key: Uint8Array): Promise { if (key.length !== 32) { throw new Error('Storage key must be 32 bytes long') } @@ -493,7 +387,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { const account = await this.getAccount(address) if (!account) { - throw new Error('getContractStorage() called on non-existing account') + throw new Error('getStorage() called on non-existing account') } const trie = this._getStorageTrie(address, account) const value = await trie.get(key) @@ -566,7 +460,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { * Cannot be more than 32 bytes. Leading zeros are stripped. * If it is a empty or filled with zeros, deletes the value. */ - async putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { + async putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { if (key.length !== 32) { throw new Error('Storage key must be 32 bytes long') } @@ -577,7 +471,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { const account = await this.getAccount(address) if (!account) { - throw new Error('putContractStorage() called on non-existing account') + throw new Error('putStorage() called on non-existing account') } value = unpadBytes(value) @@ -593,12 +487,12 @@ export class DefaultStateManager implements EVMStateManagerInterface { * Clears all storage entries for the account corresponding to `address`. * @param address - Address to clear the storage of */ - async clearContractStorage(address: Address): Promise { + async clearStorage(address: Address): Promise { let account = await this.getAccount(address) if (!account) { account = new Account() } - this._storageCache?.clearContractStorage(address) + this._storageCache?.clearStorage(address) await this._modifyContractStorage(address, account, (storageTrie, done) => { storageTrie.root(storageTrie.EMPTY_TRIE_ROOT) done() @@ -748,7 +642,7 @@ export class DefaultStateManager implements EVMStateManagerInterface { for (const storageKey of storageSlots) { const proof = (await storageTrie.createProof(storageKey)).map((p) => bytesToHex(p)) - const value = bytesToHex(await this.getContractStorage(address, storageKey)) + const value = bytesToHex(await this.getStorage(address, storageKey)) const proofItem: StorageProof = { key: bytesToHex(storageKey), value: value === '0x' ? '0x0' : value, // Return '0x' values as '0x0' since this is a JSON RPC response @@ -1058,11 +952,11 @@ export class DefaultStateManager implements EVMStateManagerInterface { const account = createAccount({ balance, nonce }) await this.putAccount(addr, account) if (code !== undefined) { - await this.putContractCode(addr, toBytes(code)) + await this.putCode(addr, toBytes(code)) } if (storage !== undefined) { for (const [key, value] of storage) { - await this.putContractStorage(addr, toBytes(key), toBytes(value)) + await this.putStorage(addr, toBytes(key), toBytes(value)) } } } diff --git a/packages/statemanager/src/statelessVerkleStateManager.ts b/packages/statemanager/src/statelessVerkleStateManager.ts index 498842f074..589d868505 100644 --- a/packages/statemanager/src/statelessVerkleStateManager.ts +++ b/packages/statemanager/src/statelessVerkleStateManager.ts @@ -34,10 +34,10 @@ import { } from './cache/index.js' import type { AccessedStateWithAddress } from './accessWitness.js' +import type { CacheSettings, StatelessVerkleStateManagerOpts, VerkleState } from './index.js' import type { DefaultStateManager } from './stateManager.js' import type { AccountFields, - Common, EVMStateManagerInterface, Proof, StorageDump, @@ -53,73 +53,6 @@ import type { const debug = debugDefault('statemanager:verkle') -export interface VerkleState { - [key: PrefixedHexString]: PrefixedHexString | null -} - -export interface EncodedVerkleProof { - [key: PrefixedHexString]: PrefixedHexString -} - -type CacheOptions = { - /** - * Allows for cache deactivation - * - * Depending on the use case and underlying datastore (and eventual concurrent cache - * mechanisms there), usage with or without cache can be faster - * - * Default: false - */ - deactivate?: boolean - - /** - * Cache type to use. - * - * Available options: - * - * ORDERED_MAP: Cache with no fixed upper bound and dynamic allocation, - * use for dynamic setups like testing or similar. - * - * LRU: LRU cache with pre-allocation of memory and a fixed size. - * Use for larger and more persistent caches. - */ - type?: CacheType - - /** - * Size of the cache (only for LRU cache) - * - * Default: 100000 (account cache) / 20000 (storage cache) - * - * Note: the cache/trie interplay mechanism is designed in a way that - * the theoretical number of max modified accounts between two flush operations - * should be smaller than the cache size, otherwise the cache will "forget" the - * old modifications resulting in an incomplete set of trie-flushed accounts. - */ - size?: number -} - -type CacheSettings = { - deactivate: boolean - type: CacheType - size: number -} - -/** - * Options dictionary. - */ -export interface StatelessVerkleStateManagerOpts { - /** - * The common to use - */ - common?: Common - accountCacheOpts?: CacheOptions - storageCacheOpts?: CacheOptions - codeCacheOpts?: CacheOptions - accesses?: AccessWitness - verkleCrypto: VerkleCrypto - initialStateRoot?: Uint8Array -} - const PUSH_OFFSET = 95 // eslint-disable-next-line @typescript-eslint/no-unused-vars const PUSH1 = PUSH_OFFSET + 1 @@ -185,7 +118,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * Instantiate the StateManager interface. */ constructor(opts: StatelessVerkleStateManagerOpts) { - this.originalStorageCache = new OriginalStorageCache(this.getContractStorage.bind(this)) + this.originalStorageCache = new OriginalStorageCache(this.getStorage.bind(this)) this._accountCacheSettings = { deactivate: opts.accountCacheOpts?.deactivate ?? false, @@ -337,9 +270,9 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * @param address - Address of the `account` to add the `code` for * @param value - The value of the `code` */ - async putContractCode(address: Address, value: Uint8Array): Promise { + async putCode(address: Address, value: Uint8Array): Promise { if (this.DEBUG) { - debug(`putContractCode address=${address.toString()} value=${short(value)}`) + debug(`putCode address=${address.toString()} value=${short(value)}`) } this._codeCache?.put(address, value) @@ -361,9 +294,9 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * @returns {Promise} - Resolves with the code corresponding to the provided address. * Returns an empty `Uint8Array` if the account has no associated code. */ - async getContractCode(address: Address): Promise { + async getCode(address: Address): Promise { if (this.DEBUG) { - debug(`getContractCode address=${address.toString()}`) + debug(`getCode address=${address.toString()}`) } if (!this._codeCacheSettings.deactivate) { @@ -420,7 +353,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { return contactCode } - async getContractCodeSize(address: Address): Promise { + async getCodeSize(address: Address): Promise { if (!this._accountCacheSettings.deactivate) { const elem = this._accountCache!.get(address) if (elem !== undefined) { @@ -452,7 +385,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * corresponding to the provided address at the provided key. * If this does not exist an empty `Uint8Array` is returned. */ - async getContractStorage(address: Address, key: Uint8Array): Promise { + async getStorage(address: Address, key: Uint8Array): Promise { if (!this._storageCacheSettings.deactivate) { const value = this._storageCache!.get(address, key) if (value !== undefined) { @@ -481,7 +414,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * @param key - Key to set the value at. Must be 32 bytes long. * @param value - Value to set at `key` for account corresponding to `address`. Cannot be more than 32 bytes. Leading zeros are stripped. If it is a empty or filled with zeros, deletes the value. */ - async putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { + async putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise { if (!this._storageCacheSettings.deactivate) { this._storageCache!.put(address, key, value) } else { @@ -501,10 +434,10 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * Clears all storage entries for the account corresponding to `address`. * @param address - Address to clear the storage of */ - async clearContractStorage(address: Address): Promise { + async clearStorage(address: Address): Promise { const stem = getVerkleStem(this.verkleCrypto, address, 0) const codeHashKey = getVerkleKey(stem, VerkleLeafType.CodeHash) - this._storageCache?.clearContractStorage(address) + this._storageCache?.clearStorage(address) // Update codeHash to `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470` this._state[bytesToHex(codeHashKey)] = KECCAK256_NULL_S } @@ -639,7 +572,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { this._accountCache!.del(address) if (!this._storageCacheSettings.deactivate) { - this._storageCache?.clearContractStorage(address) + this._storageCache?.clearStorage(address) } } diff --git a/packages/statemanager/src/types.ts b/packages/statemanager/src/types.ts new file mode 100644 index 0000000000..da35fe4a85 --- /dev/null +++ b/packages/statemanager/src/types.ts @@ -0,0 +1,155 @@ +import { type PrefixedHexString, utf8ToBytes } from '@ethereumjs/util' + +import type { CacheType } from './cache/index.js' +import type { AccessWitness } from './index.js' +import type { Common } from '@ethereumjs/common' +import type { Trie } from '@ethereumjs/trie' +import type { VerkleCrypto } from '@ethereumjs/util' + +type CacheOptions = { + /** + * Allows for cache deactivation + * + * Depending on the use case and underlying datastore (and eventual concurrent cache + * mechanisms there), usage with or without cache can be faster + * + * Default: false + */ + deactivate?: boolean + + /** + * Cache type to use. + * + * Available options: + * + * ORDERED_MAP: Cache with no fixed upper bound and dynamic allocation, + * use for dynamic setups like testing or similar. + * + * LRU: LRU cache with pre-allocation of memory and a fixed size. + * Use for larger and more persistent caches. + */ + type?: CacheType + + /** + * Size of the cache (only for LRU cache) + * + * Default: 100000 (account cache) / 20000 (storage cache) / 20000 (code cache) + * + * Note: the cache/trie interplay mechanism is designed in a way that + * the theoretical number of max modified accounts between two flush operations + * should be smaller than the cache size, otherwise the cache will "forget" the + * old modifications resulting in an incomplete set of trie-flushed accounts. + */ + size?: number +} + +export type CacheSettings = { + deactivate: boolean + type: CacheType + size: number +} + +/** + * Basic state manager options (not to be used directly) + */ +interface BaseStateManagerOpts { + /** + * The common to use + */ + common?: Common +} + +/** + * Cache state manager options (not to be used directly) + */ +interface CacheStateManagerOpts { + accountCacheOpts?: CacheOptions + storageCacheOpts?: CacheOptions + codeCacheOpts?: CacheOptions +} + +/** + * Options for constructing a {@link SimpleStateManager}. + */ +export interface SimpleStateManagerOpts extends BaseStateManagerOpts { + // Keep this as an alias so that it might be able to extend in the future +} + +export interface RPCStateManagerOpts extends BaseStateManagerOpts { + provider: string + blockTag: bigint | 'earliest' +} + +/** + * Options for constructing a {@link StateManager}. + */ +export interface DefaultStateManagerOpts extends BaseStateManagerOpts, CacheStateManagerOpts { + /** + * A {@link Trie} instance + */ + trie?: Trie + /** + * Option to prefix codehashes in the database. This defaults to `true`. + * If this is disabled, note that it is possible to corrupt the trie, by deploying code + * which code is equal to the preimage of a trie-node. + * E.g. by putting the code `0x80` into the empty trie, will lead to a corrupted trie. + */ + prefixCodeHashes?: boolean + + /** + * Option to prefix the keys for the storage tries with the first 7 bytes from the + * associated account address. Activating this option gives a noticeable performance + * boost for storage DB reads when operating on larger tries. + * + * Note: Activating/deactivating this option causes continued state reads to be + * incompatible with existing databases. + * + * Default: false (for backwards compatibility reasons) + */ + prefixStorageTrieKeys?: boolean +} + +/** + * Options dictionary. + */ +export interface StatelessVerkleStateManagerOpts + extends BaseStateManagerOpts, + CacheStateManagerOpts { + accesses?: AccessWitness + verkleCrypto: VerkleCrypto + initialStateRoot?: Uint8Array +} + +export interface VerkleState { + [key: PrefixedHexString]: PrefixedHexString | null +} + +export interface EncodedVerkleProof { + [key: PrefixedHexString]: PrefixedHexString +} + +/** + * Prefix to distinguish between a contract deployed with code `0x80` + * and `RLP([])` (also having the value `0x80`). + * + * Otherwise the creation of the code hash for the `0x80` contract + * will be the same as the hash of the empty trie which leads to + * misbehaviour in the underlying trie library. + */ +export const CODEHASH_PREFIX = utf8ToBytes('c') + +export type StorageProof = { + key: PrefixedHexString + proof: PrefixedHexString[] + value: PrefixedHexString +} + +export type Proof = { + address: PrefixedHexString + balance: PrefixedHexString + codeHash: PrefixedHexString + nonce: PrefixedHexString + storageHash: PrefixedHexString + accountProof: PrefixedHexString[] + storageProof: StorageProof[] +} diff --git a/packages/statemanager/test/checkpointing.code.spec.ts b/packages/statemanager/test/checkpointing.code.spec.ts index ddda37eb50..12e8815dd4 100644 --- a/packages/statemanager/test/checkpointing.code.spec.ts +++ b/packages/statemanager/test/checkpointing.code.spec.ts @@ -10,7 +10,7 @@ const codeEval = async ( value: Uint8Array, root: Uint8Array, ) => { - assert.deepEqual(await sm.getContractCode(address), value, 'contract code value should be equal') + assert.deepEqual(await sm.getCode(address), value, 'contract code value should be equal') const accountCMP = await sm.getAccount(address) assert.deepEqual(accountCMP!.codeHash, root, 'account code root should be equal') } @@ -96,13 +96,13 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.flush() await codeEval(sm, address, c.c1.value, c.c1.root) sm.clearCaches() - assert.deepEqual(await sm.getContractCode(address), c.c1.value) + assert.deepEqual(await sm.getCode(address), c.c1.value) await codeEval(sm, address, c.c1.value, c.c1.root) }) @@ -111,7 +111,7 @@ describe('StateManager -> Code Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.commit() await sm.flush() await codeEval(sm, address, c.c1.value, c.c1.root) @@ -125,7 +125,7 @@ describe('StateManager -> Code Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.revert() await sm.flush() @@ -140,7 +140,7 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() await sm.commit() await sm.flush() @@ -154,7 +154,7 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() await sm.revert() await sm.flush() @@ -168,9 +168,9 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.commit() await sm.flush() await codeEval(sm, address, c.c2.value, c.c2.root) @@ -183,11 +183,11 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.commit() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.flush() await codeEval(sm, address, c.c3.value, c.c3.root) @@ -199,10 +199,10 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c2.value) + await sm.putCode(address, c.c3.value) await sm.commit() await sm.flush() await codeEval(sm, address, c.c3.value, c.c3.root) @@ -216,8 +216,8 @@ describe('StateManager -> Code Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractCode(address, c.c1.value) - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c1.value) + await sm.putCode(address, c.c2.value) await sm.commit() await sm.flush() await codeEval(sm, address, c.c2.value, c.c2.root) @@ -231,9 +231,9 @@ describe('StateManager -> Code Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.revert() await sm.flush() await codeEval(sm, address, valueEmpty, rootEmpty) @@ -246,9 +246,9 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.revert() await sm.flush() await codeEval(sm, address, c.c1.value, c.c1.root) @@ -261,11 +261,11 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.checkpoint() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.commit() await sm.commit() await sm.flush() @@ -279,11 +279,11 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.checkpoint() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.commit() await sm.revert() await sm.flush() @@ -297,11 +297,11 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.checkpoint() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.revert() await sm.commit() await sm.flush() @@ -315,13 +315,13 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.checkpoint() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.revert() - await sm.putContractCode(address, c.c4.value) + await sm.putCode(address, c.c4.value) await sm.commit() await sm.flush() await codeEval(sm, address, c.c4.value, c.c4.root) @@ -334,15 +334,15 @@ describe('StateManager -> Code Checkpointing', () => { const sm = new SM() await sm.putAccount(address, new Account()) - await sm.putContractCode(address, c.c1.value) + await sm.putCode(address, c.c1.value) await sm.checkpoint() - await sm.putContractCode(address, c.c2.value) + await sm.putCode(address, c.c2.value) await sm.checkpoint() - await sm.putContractCode(address, c.c3.value) + await sm.putCode(address, c.c3.value) await sm.revert() - await sm.putContractCode(address, c.c4.value) + await sm.putCode(address, c.c4.value) await sm.checkpoint() - await sm.putContractCode(address, c.c5.value) + await sm.putCode(address, c.c5.value) await sm.commit() await sm.commit() await sm.flush() diff --git a/packages/statemanager/test/checkpointing.storage.spec.ts b/packages/statemanager/test/checkpointing.storage.spec.ts index 21a8613746..cd8fbb999c 100644 --- a/packages/statemanager/test/checkpointing.storage.spec.ts +++ b/packages/statemanager/test/checkpointing.storage.spec.ts @@ -13,11 +13,7 @@ const storageEval = async ( root: Uint8Array, rootCheck = true, ) => { - assert.deepEqual( - await sm.getContractStorage(address, key), - value, - 'storage value should be equal', - ) + assert.deepEqual(await sm.getStorage(address, key), value, 'storage value should be equal') if (rootCheck) { const accountCMP = await sm.getAccount(address) assert.deepEqual(accountCMP!.storageRoot, root, 'account storage root should be equal') @@ -116,12 +112,12 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.flush() await storageEval(sm, address, key, s.s1.value, s.s1.root, SMDict.rootCheck) sm.clearCaches() - assert.deepEqual(await sm.getContractStorage(address, key), s.s1.value) + assert.deepEqual(await sm.getStorage(address, key), s.s1.value) await storageEval(sm, address, key, s.s1.value, s.s1.root, SMDict.rootCheck) }) @@ -130,7 +126,7 @@ describe('StateManager -> Storage Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.commit() await sm.flush() await storageEval(sm, address, key, s.s1.value, s.s1.root, SMDict.rootCheck) @@ -144,7 +140,7 @@ describe('StateManager -> Storage Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.revert() await sm.flush() @@ -159,7 +155,7 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() await sm.commit() await sm.flush() @@ -173,7 +169,7 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() await sm.revert() await sm.flush() @@ -187,9 +183,9 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.commit() await sm.flush() await storageEval(sm, address, key, s.s2.value, s.s2.root, SMDict.rootCheck) @@ -202,11 +198,11 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.commit() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.flush() await storageEval(sm, address, key, s.s3.value, s.s3.root, SMDict.rootCheck) @@ -218,10 +214,10 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s3.value) await sm.commit() await sm.flush() await storageEval(sm, address, key, s.s3.value, s.s3.root, SMDict.rootCheck) @@ -235,8 +231,8 @@ describe('StateManager -> Storage Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s1.value) - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s2.value) await sm.commit() await sm.flush() await storageEval(sm, address, key, s.s2.value, s.s2.root, SMDict.rootCheck) @@ -250,9 +246,9 @@ describe('StateManager -> Storage Checkpointing', () => { await sm.putAccount(address, new Account()) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.revert() await sm.flush() await storageEval(sm, address, key, valueEmpty, rootEmpty) @@ -265,9 +261,9 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.revert() await sm.flush() await storageEval(sm, address, key, s.s1.value, s.s1.root, SMDict.rootCheck) @@ -280,11 +276,11 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.commit() await sm.commit() await sm.flush() @@ -298,11 +294,11 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.commit() await sm.revert() await sm.flush() @@ -316,11 +312,11 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.revert() await sm.commit() await sm.flush() @@ -334,13 +330,13 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.revert() - await sm.putContractStorage(address, key, s.s4.value) + await sm.putStorage(address, key, s.s4.value) await sm.commit() await sm.flush() await storageEval(sm, address, key, s.s4.value, s.s4.root, SMDict.rootCheck) @@ -353,15 +349,15 @@ describe('StateManager -> Storage Checkpointing', () => { const sm = new SMDict.SM() await sm.putAccount(address, new Account()) - await sm.putContractStorage(address, key, s.s1.value) + await sm.putStorage(address, key, s.s1.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s2.value) + await sm.putStorage(address, key, s.s2.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s3.value) + await sm.putStorage(address, key, s.s3.value) await sm.revert() - await sm.putContractStorage(address, key, s.s4.value) + await sm.putStorage(address, key, s.s4.value) await sm.checkpoint() - await sm.putContractStorage(address, key, s.s5.value) + await sm.putStorage(address, key, s.s5.value) await sm.commit() await sm.commit() await sm.flush() diff --git a/packages/statemanager/test/proofStateManager.spec.ts b/packages/statemanager/test/proofStateManager.spec.ts index 9bc74fdd86..41c02a7333 100644 --- a/packages/statemanager/test/proofStateManager.spec.ts +++ b/packages/statemanager/test/proofStateManager.spec.ts @@ -40,7 +40,7 @@ describe('ProofStateManager', () => { await stateManager.putAccount(address, new Account(BigInt(100), BigInt(200))) const storageRoot = (await stateManager.getAccount(address))!.storageRoot - await stateManager.putContractStorage(address, key, new Uint8Array([10])) + await stateManager.putStorage(address, key, new Uint8Array([10])) const proof = await stateManager.getProof(address, [key]) assert.ok(!equalsBytes(hexToBytes(proof.storageHash), storageRoot)) @@ -82,8 +82,8 @@ describe('ProofStateManager', () => { const stateManager = new DefaultStateManager() await stateManager.checkpoint() await stateManager.putAccount(address, new Account()) - await stateManager.putContractStorage(address, key, value) - await stateManager.putContractCode(address, code) + await stateManager.putStorage(address, key, value) + await stateManager.putCode(address, code) const account = await stateManager.getAccount(address) account!.balance = BigInt(1) account!.nonce = BigInt(2) diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index 1e425abbe8..d4a4f1f03f 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -98,31 +98,31 @@ describe('RPC State Manager API tests', () => { assert.ok(state.getAccount(vitalikDotEth) !== undefined, 'vitalik.eth does exist') const UNIerc20ContractAddress = Address.fromString('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') - const UNIContractCode = await state.getContractCode(UNIerc20ContractAddress) + const UNIContractCode = await state.getCode(UNIerc20ContractAddress) assert.ok(UNIContractCode.length > 0, 'was able to retrieve UNI contract code') - await state.putContractCode(UNIerc20ContractAddress, UNIContractCode) + await state.putCode(UNIerc20ContractAddress, UNIContractCode) assert.ok( typeof (state as any)._contractCache.get(UNIerc20ContractAddress.toString()) !== 'undefined', 'UNI ERC20 contract code was found in cache', ) - const storageSlot = await state.getContractStorage( + const storageSlot = await state.getStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(1n), 32), ) assert.ok(storageSlot.length > 0, 'was able to retrieve storage slot 1 for the UNI contract') await expect(async () => { - await state.getContractStorage(UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(1n), 31)) + await state.getStorage(UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(1n), 31)) }).rejects.toThrowError('Storage key must be 32 bytes long') - await state.putContractStorage( + await state.putStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), utf8ToBytes('abcd'), ) - const slotValue = await state.getContractStorage( + const slotValue = await state.getStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), ) @@ -141,7 +141,7 @@ describe('RPC State Manager API tests', () => { await state.checkpoint() - await state.putContractStorage( + await state.putStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), new Uint8Array(0), @@ -165,7 +165,7 @@ describe('RPC State Manager API tests', () => { assert.ok(true, 'calls getAccountFromProvider for non-cached account') } - const deletedSlot = await state.getContractStorage( + const deletedSlot = await state.getStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), ) @@ -184,7 +184,7 @@ describe('RPC State Manager API tests', () => { 'account deleted since last checkpoint should exist after revert called', ) - const deletedSlotAfterRevert = await state.getContractStorage( + const deletedSlotAfterRevert = await state.getStorage( UNIerc20ContractAddress, setLengthLeft(bigIntToBytes(2n), 32), ) @@ -201,7 +201,7 @@ describe('RPC State Manager API tests', () => { Object.keys(cacheStorage).length, 'should have 2 storage slots in cache before clear', ) - await state.clearContractStorage(UNIerc20ContractAddress) + await state.clearStorage(UNIerc20ContractAddress) const clearedStorage = await state.dumpStorage(UNIerc20ContractAddress) assert.deepEqual({}, clearedStorage, 'storage cache should be empty after clear') @@ -328,7 +328,7 @@ describe('blockchain', () => hexToBytes('0xf8506f559699a58a4724df4fcf2ad4fd242d20324db541823f128f5974feb6c7'), ) const block = await createBlockFromJsonRpcProvider(provider, 500000n, { setHardfork: true }) - await evm.stateManager.putContractCode(contractAddress, hexToBytes(code)) + await evm.stateManager.putCode(contractAddress, hexToBytes(code)) const runCallArgs: Partial = { caller, gasLimit: BigInt(0xffffffffff), diff --git a/packages/statemanager/test/stateManager.account.spec.ts b/packages/statemanager/test/stateManager.account.spec.ts index 9b4b01989a..ef97c11ce7 100644 --- a/packages/statemanager/test/stateManager.account.spec.ts +++ b/packages/statemanager/test/stateManager.account.spec.ts @@ -57,9 +57,9 @@ describe('StateManager -> General/Account', () => { const key = hexToBytes('0x1234567890123456789012345678901234567890123456789012345678901234') const value = hexToBytes('0x1234') await stateManager.putAccount(address, account) - await stateManager.putContractStorage(address, key, value) + await stateManager.putStorage(address, key, value) - const contract0 = await stateManager.getContractStorage(address, key) + const contract0 = await stateManager.getStorage(address, key) assert.ok( equalsBytes(contract0, value), "contract key's value is set in the _storageTries cache", @@ -68,9 +68,9 @@ describe('StateManager -> General/Account', () => { await stateManager.commit() await stateManager.setStateRoot(initialStateRoot) try { - await stateManager.getContractStorage(address, key) + await stateManager.getStorage(address, key) } catch (e) { - assert.ok(true, 'should throw if getContractStorage() is called on non existing address') + assert.ok(true, 'should throw if getStorage() is called on non existing address') } }) diff --git a/packages/statemanager/test/stateManager.code.spec.ts b/packages/statemanager/test/stateManager.code.spec.ts index 98e713b23c..db47c19a03 100644 --- a/packages/statemanager/test/stateManager.code.spec.ts +++ b/packages/statemanager/test/stateManager.code.spec.ts @@ -33,29 +33,29 @@ describe('StateManager -> Code', () => { const key2 = hexToBytes(`0x${'00'.repeat(31)}01`) await stateManager.putAccount(address1, account) - await stateManager.putContractStorage(address1, key1, key2) - await stateManager.putContractStorage(address1, key2, key2) + await stateManager.putStorage(address1, key1, key2) + await stateManager.putStorage(address1, key2, key2) const root = await stateManager.getStateRoot() const rawNode = await stateManager['_trie']['_db'].get(root) - await codeStateManager.putContractCode(address1, rawNode!) + await codeStateManager.putCode(address1, rawNode!) - let codeSlot1 = await codeStateManager.getContractStorage(address1, key1) - let codeSlot2 = await codeStateManager.getContractStorage(address1, key2) + let codeSlot1 = await codeStateManager.getStorage(address1, key1) + let codeSlot2 = await codeStateManager.getStorage(address1, key2) assert.ok(codeSlot1.length === 0, 'slot 0 is empty') assert.ok(codeSlot2.length === 0, 'slot 1 is empty') - const code = await codeStateManager.getContractCode(address1) + const code = await codeStateManager.getCode(address1) assert.ok(code.length > 0, 'code deposited correctly') - const slot1 = await stateManager.getContractStorage(address1, key1) - const slot2 = await stateManager.getContractStorage(address1, key2) + const slot1 = await stateManager.getStorage(address1, key1) + const slot2 = await stateManager.getStorage(address1, key2) assert.ok(slot1.length > 0, 'storage key0 deposited correctly') assert.ok(slot2.length > 0, 'storage key1 deposited correctly') - let slotCode = await stateManager.getContractCode(address1) + let slotCode = await stateManager.getCode(address1) assert.ok(slotCode.length === 0, 'code cannot be loaded') // Checks by either setting state root to codeHash, or codeHash to stateRoot @@ -65,7 +65,7 @@ describe('StateManager -> Code', () => { await stateManager.putAccount(address1, account1!) - slotCode = await stateManager.getContractCode(address1) + slotCode = await stateManager.getCode(address1) assert.ok(slotCode.length === 0, 'code cannot be loaded') // This test fails if no code prefix is used account1 = await codeStateManager.getAccount(address1) @@ -73,8 +73,8 @@ describe('StateManager -> Code', () => { await codeStateManager.putAccount(address1, account1!) - codeSlot1 = await codeStateManager.getContractStorage(address1, key1) - codeSlot2 = await codeStateManager.getContractStorage(address1, key2) + codeSlot1 = await codeStateManager.getStorage(address1, key1) + codeSlot2 = await codeStateManager.getStorage(address1, key2) assert.ok(codeSlot1.length === 0, 'slot 0 is empty') assert.ok(codeSlot2.length === 0, 'slot 1 is empty') @@ -93,8 +93,8 @@ describe('StateManager -> Code', () => { } const account = createAccount(raw) await stateManager.putAccount(address, account) - await stateManager.putContractCode(address, code) - const codeRetrieved = await stateManager.getContractCode(address) + await stateManager.putCode(address, code) + const codeRetrieved = await stateManager.getCode(address) assert.ok(equalsBytes(code, codeRetrieved)) }) @@ -107,7 +107,7 @@ describe('StateManager -> Code', () => { } const account = createAccount(raw) await stateManager.putAccount(address, account) - const code = await stateManager.getContractCode(address) + const code = await stateManager.getCode(address) assert.ok(equalsBytes(code, new Uint8Array(0))) }) @@ -121,8 +121,8 @@ describe('StateManager -> Code', () => { const account = createAccount(raw) const code = new Uint8Array(0) await stateManager.putAccount(address, account) - await stateManager.putContractCode(address, code) - const codeRetrieved = await stateManager.getContractCode(address) + await stateManager.putCode(address, code) + const codeRetrieved = await stateManager.getCode(address) assert.ok(equalsBytes(codeRetrieved, new Uint8Array(0))) }) @@ -130,8 +130,8 @@ describe('StateManager -> Code', () => { const stateManager = new DefaultStateManager({ accountCacheOpts }) const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) const code = hexToBytes('0x80') - await stateManager.putContractCode(address, code) - const codeRetrieved = await stateManager.getContractCode(address) + await stateManager.putCode(address, code) + const codeRetrieved = await stateManager.getCode(address) assert.ok(equalsBytes(codeRetrieved, code)) }) @@ -142,18 +142,18 @@ describe('StateManager -> Code', () => { const address = new Address(hexToBytes('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b')) const code = hexToBytes('0x80') try { - await stateManager.putContractCode(address, code) + await stateManager.putCode(address, code) assert.fail('should throw') } catch (e) { assert.ok(true, 'successfully threw') } }) - it('putContractCode with empty code on existing address should correctly propagate', async () => { + it('putCode with empty code on existing address should correctly propagate', async () => { const stateManager = new DefaultStateManager() const address = Address.zero() - await stateManager.putContractCode(address, new Uint8Array([1])) - await stateManager.putContractCode(address, new Uint8Array()) + await stateManager.putCode(address, new Uint8Array([1])) + await stateManager.putCode(address, new Uint8Array()) const account = await stateManager.getAccount(address) assert.ok(account !== undefined) assert.ok(account?.isEmpty()) diff --git a/packages/statemanager/test/stateManager.spec.ts b/packages/statemanager/test/stateManager.spec.ts index 9c1b019f3d..585fa1654e 100644 --- a/packages/statemanager/test/stateManager.spec.ts +++ b/packages/statemanager/test/stateManager.spec.ts @@ -49,14 +49,14 @@ describe('StateManager -> General', () => { const storageKey = setLengthLeft(bigIntToBytes(2n), 32) const storedData = utf8ToBytes('abcd') - await sm.putContractCode(contractAddress, contractCode) - await sm.putContractStorage(contractAddress, storageKey, storedData) + await sm.putCode(contractAddress, contractCode) + await sm.putStorage(contractAddress, storageKey, storedData) - let storage = await sm.getContractStorage(contractAddress, storageKey) + let storage = await sm.getStorage(contractAddress, storageKey) assert.equal(JSON.stringify(storage), JSON.stringify(storedData), 'contract storage updated') - await sm.clearContractStorage(contractAddress) - storage = await sm.getContractStorage(contractAddress, storageKey) + await sm.clearStorage(contractAddress) + storage = await sm.getStorage(contractAddress, storageKey) assert.equal( JSON.stringify(storage), JSON.stringify(new Uint8Array()), @@ -187,11 +187,11 @@ describe('StateManager -> General', () => { const address = Address.fromString(addressStr) const account = new Account(entry.nonce, entry.balance) await stateManager.putAccount(address, account) - await stateManager.putContractCode(address, entry.code) + await stateManager.putCode(address, entry.code) for (let i = 0; i < entry.keys.length; i++) { const key = entry.keys[i] const value = entry.values[i] - await stateManager.putContractStorage(address, key, value) + await stateManager.putStorage(address, key, value) } await stateManager.flush() stateSetup[addressStr].codeHash = (await stateManager.getAccount(address)!)?.codeHash @@ -218,13 +218,13 @@ describe('StateManager -> General', () => { const stProof = await stateManager.getProof(address1, [state1.keys[0], state1.keys[1]]) await partialStateManager.addProofData(stProof) - let stSlot1_0 = await partialStateManager.getContractStorage(address1, state1.keys[0]) + let stSlot1_0 = await partialStateManager.getStorage(address1, state1.keys[0]) assert.ok(equalsBytes(stSlot1_0, state1.values[0])) - let stSlot1_1 = await partialStateManager.getContractStorage(address1, state1.keys[1]) + let stSlot1_1 = await partialStateManager.getStorage(address1, state1.keys[1]) assert.ok(equalsBytes(stSlot1_1, state1.values[1])) - let stSlot1_2 = await partialStateManager.getContractStorage(address1, state1.keys[2]) + let stSlot1_2 = await partialStateManager.getStorage(address1, state1.keys[2]) assert.ok(equalsBytes(stSlot1_2, new Uint8Array())) // Check Array support as input @@ -240,13 +240,13 @@ describe('StateManager -> General', () => { account3 = await sm.getAccount(address3) assert.ok(account3 === undefined) - stSlot1_0 = await sm.getContractStorage(address1, state1.keys[0]) + stSlot1_0 = await sm.getStorage(address1, state1.keys[0]) assert.ok(equalsBytes(stSlot1_0, state1.values[0])) - stSlot1_1 = await sm.getContractStorage(address1, state1.keys[1]) + stSlot1_1 = await sm.getStorage(address1, state1.keys[1]) assert.ok(equalsBytes(stSlot1_1, state1.values[1])) - stSlot1_2 = await sm.getContractStorage(address1, state1.keys[2]) + stSlot1_2 = await sm.getStorage(address1, state1.keys[2]) assert.ok(equalsBytes(stSlot1_2, new Uint8Array())) } @@ -299,7 +299,7 @@ describe('StateManager -> General', () => { const account2 = new Account(undefined, 100n) await sm.putAccount(address, account) await sm.putAccount(address2, account2) - await sm.putContractStorage(address, setLengthLeft(intToBytes(0), 32), intToBytes(32)) + await sm.putStorage(address, setLengthLeft(intToBytes(0), 32), intToBytes(32)) const storage = await sm.dumpStorage(address) const keys = Object.keys(storage) as PrefixedHexString[] const proof = await sm.getProof( @@ -319,10 +319,7 @@ describe('StateManager -> General', () => { false, 'trie opts are preserved in new sm', ) - assert.deepEqual( - intToBytes(32), - await partialSM.getContractStorage(address, hexToBytes(keys[0])), - ) + assert.deepEqual(intToBytes(32), await partialSM.getStorage(address, hexToBytes(keys[0]))) assert.equal((await partialSM.getAccount(address2))?.balance, 100n) const partialSM2 = await DefaultStateManager.fromProof(proof, true, { trie: newTrie, @@ -333,10 +330,7 @@ describe('StateManager -> General', () => { false, 'trie opts are preserved in new sm', ) - assert.deepEqual( - intToBytes(32), - await partialSM2.getContractStorage(address, hexToBytes(keys[0])), - ) + assert.deepEqual(intToBytes(32), await partialSM2.getStorage(address, hexToBytes(keys[0]))) assert.equal((await partialSM2.getAccount(address2))?.balance, 100n) }, ) diff --git a/packages/statemanager/test/stateManager.storage.spec.ts b/packages/statemanager/test/stateManager.storage.spec.ts index d3829a1028..40d8113348 100644 --- a/packages/statemanager/test/stateManager.storage.spec.ts +++ b/packages/statemanager/test/stateManager.storage.spec.ts @@ -31,7 +31,7 @@ describe('StateManager -> Storage', () => { const key = hexToBytes('0x1234567890123456789012345678901234567890123456789012345678901234') const value = hexToBytes('0x0a') // We used this value as its RLP encoding is also 0a - await stateManager.putContractStorage(address, key, value) + await stateManager.putStorage(address, key, value) const data = await stateManager.dumpStorage(address) const expect = { [bytesToHex(keccak256(key))]: '0x0a' } @@ -45,7 +45,7 @@ describe('StateManager -> Storage', () => { await stateManager.putAccount(address, account) try { - await stateManager.putContractStorage(address, new Uint8Array(12), hexToBytes('0x1231')) + await stateManager.putStorage(address, new Uint8Array(12), hexToBytes('0x1231')) } catch (e: any) { assert.equal(e.message, 'Storage key must be 32 bytes long') return @@ -61,7 +61,7 @@ describe('StateManager -> Storage', () => { await stateManager.putAccount(address, account) try { - await stateManager.getContractStorage(address, new Uint8Array(12)) + await stateManager.getStorage(address, new Uint8Array(12)) } catch (e: any) { assert.equal(e.message, 'Storage key must be 32 bytes long') return @@ -79,7 +79,7 @@ describe('StateManager -> Storage', () => { const key = zeros(32) const value = hexToBytes(`0x${'aa'.repeat(33)}`) try { - await stateManager.putContractStorage(address, key, value) + await stateManager.putStorage(address, key, value) assert.fail('did not throw') } catch (e: any) { assert.ok(true, 'threw on trying to set storage values larger than 32 bytes') @@ -95,15 +95,15 @@ describe('StateManager -> Storage', () => { const key0 = zeros(32) const value0 = hexToBytes(`0x00${'aa'.repeat(30)}`) // put a value of 31-bytes length with a leading zero byte const expect0 = unpadBytes(value0) - await stateManager.putContractStorage(address, key0, value0) - const slot0 = await stateManager.getContractStorage(address, key0) + await stateManager.putStorage(address, key0, value0) + const slot0 = await stateManager.getStorage(address, key0) assert.ok(equalsBytes(slot0, expect0), 'value of 31 bytes padded correctly') const key1 = concatBytes(zeros(31), hexToBytes('0x01')) const value1 = hexToBytes(`0x0000${'aa'.repeat(1)}`) // put a value of 1-byte length with two leading zero bytes const expect1 = unpadBytes(value1) - await stateManager.putContractStorage(address, key1, value1) - const slot1 = await stateManager.getContractStorage(address, key1) + await stateManager.putStorage(address, key1, value1) + const slot1 = await stateManager.getStorage(address, key1) assert.ok(equalsBytes(slot1, expect1), 'value of 1 byte padded correctly') }) @@ -122,15 +122,15 @@ describe('StateManager -> Storage', () => { await stateManager.putAccount(address, account) const value = zeros(length) - await stateManager.putContractStorage(address, key, startValue) - const currentValue = await stateManager.getContractStorage(address, key) + await stateManager.putStorage(address, key, startValue) + const currentValue = await stateManager.getStorage(address, key) if (!equalsBytes(currentValue, startValue)) { // sanity check assert.fail('contract value not set correctly') } else { // delete the value - await stateManager.putContractStorage(address, key, value) - const deleted = await stateManager.getContractStorage(address, key) + await stateManager.putStorage(address, key, value) + const deleted = await stateManager.getStorage(address, key) assert.ok(equalsBytes(deleted, zeros(0)), 'the storage key should be deleted') } } @@ -146,8 +146,8 @@ describe('StateManager -> Storage', () => { const value = hexToBytes('0x0000aabb00') const expect = hexToBytes('0xaabb00') - await stateManager.putContractStorage(address, key, value) - const contractValue = await stateManager.getContractStorage(address, key) + await stateManager.putStorage(address, key, value) + const contractValue = await stateManager.getStorage(address, key) assert.ok(equalsBytes(contractValue, expect), 'trailing zeros are not stripped') }) } diff --git a/packages/statemanager/test/statelessVerkleStateManager.spec.ts b/packages/statemanager/test/statelessVerkleStateManager.spec.ts index 76c36e0dfd..da1588b4e1 100644 --- a/packages/statemanager/test/statelessVerkleStateManager.spec.ts +++ b/packages/statemanager/test/statelessVerkleStateManager.spec.ts @@ -178,20 +178,13 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { const contractAddress = Address.fromString('0x4242424242424242424242424242424242424242') const storageKey = '0x0000000000000000000000000000000000000000000000000000000000000022' const storageValue = '0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b' - await stateManager.putContractStorage( - contractAddress, - hexToBytes(storageKey), - hexToBytes(storageValue), - ) - let contractStorage = await stateManager.getContractStorage( - contractAddress, - hexToBytes(storageKey), - ) + await stateManager.putStorage(contractAddress, hexToBytes(storageKey), hexToBytes(storageValue)) + let contractStorage = await stateManager.getStorage(contractAddress, hexToBytes(storageKey)) assert.equal(bytesToHex(contractStorage), storageValue) - await stateManager.clearContractStorage(contractAddress) - contractStorage = await stateManager.getContractStorage(contractAddress, hexToBytes(storageKey)) + await stateManager.clearStorage(contractAddress) + contractStorage = await stateManager.getStorage(contractAddress, hexToBytes(storageKey)) assert.equal(bytesToHex(contractStorage), bytesToHex(new Uint8Array())) }) diff --git a/packages/statemanager/test/vmState.spec.ts b/packages/statemanager/test/vmState.spec.ts index d486f191ca..698a3196cc 100644 --- a/packages/statemanager/test/vmState.spec.ts +++ b/packages/statemanager/test/vmState.spec.ts @@ -73,7 +73,7 @@ describe('Original storage cache', async () => { it(`should initially have empty storage value`, async () => { await stateManager.checkpoint() - const res = await stateManager.getContractStorage(address, key) + const res = await stateManager.getStorage(address, key) assert.deepEqual(res, new Uint8Array(0)) const origRes = await stateManager.originalStorageCache.get(address, key) @@ -83,8 +83,8 @@ describe('Original storage cache', async () => { }) it(`should set original storage value`, async () => { - await stateManager.putContractStorage(address, key, value) - const res = await stateManager.getContractStorage(address, key) + await stateManager.putStorage(address, key, value) + const res = await stateManager.getStorage(address, key) assert.deepEqual(res, value) }) @@ -95,8 +95,8 @@ describe('Original storage cache', async () => { it(`should return correct original value after modification`, async () => { const newValue = hexToBytes('0x1235') - await stateManager.putContractStorage(address, key, newValue) - const res = await stateManager.getContractStorage(address, key) + await stateManager.putStorage(address, key, newValue) + const res = await stateManager.getStorage(address, key) assert.deepEqual(res, newValue) const origRes = await stateManager.originalStorageCache.get(address, key) @@ -107,22 +107,22 @@ describe('Original storage cache', async () => { const key2 = hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000012') const value2 = utf8ToBytes('12') const value3 = utf8ToBytes('123') - await stateManager.putContractStorage(address, key2, value2) + await stateManager.putStorage(address, key2, value2) - let res = await stateManager.getContractStorage(address, key2) + let res = await stateManager.getStorage(address, key2) assert.deepEqual(res, value2) let origRes = await stateManager.originalStorageCache.get(address, key2) assert.deepEqual(origRes, value2) - await stateManager.putContractStorage(address, key2, value3) + await stateManager.putStorage(address, key2, value3) - res = await stateManager.getContractStorage(address, key2) + res = await stateManager.getStorage(address, key2) assert.deepEqual(res, value3) origRes = await stateManager.originalStorageCache.get(address, key2) assert.deepEqual(origRes, value2) // Check previous key - res = await stateManager.getContractStorage(address, key) + res = await stateManager.getStorage(address, key) assert.deepEqual(res, hexToBytes('0x1235')) origRes = await stateManager.originalStorageCache.get(address, key) assert.deepEqual(origRes, value) diff --git a/packages/vm/benchmarks/util.ts b/packages/vm/benchmarks/util.ts index 460f29ce30..f346134417 100644 --- a/packages/vm/benchmarks/util.ts +++ b/packages/vm/benchmarks/util.ts @@ -33,7 +33,7 @@ export async function getPreState( pre: { [k: string]: StateTestPreAccount }, - common: Common + common: Common, ): Promise { const state = new DefaultStateManager() await state.checkpoint() @@ -42,19 +42,19 @@ export async function getPreState( const { nonce, balance, code, storage } = pre[k] const account = new Account(BigInt(nonce), BigInt(balance)) await state.putAccount(address, account) - await state.putContractCode(address, toBytes(code)) + await state.putCode(address, toBytes(code)) for (const storageKey in storage) { const storageValue = storage[storageKey] const storageValueBytes = hexToBytes( - isHexString(storageValue) ? storageValue : `0x${storageValue}` + isHexString(storageValue) ? storageValue : `0x${storageValue}`, ) // verify if this value buffer is not a zero buffer. if so, we should not write it... const zeroBytesEquivalent = new Uint8Array(storageValueBytes.length) if (!equalsBytes(zeroBytesEquivalent, storageValueBytes)) { - await state.putContractStorage( + await state.putStorage( address, hexToBytes(isHexString(storageKey) ? storageKey : `0x${storageKey}`), - storageValueBytes + storageValueBytes, ) } } diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index 92aa4b6f69..b5115de95d 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -75,11 +75,11 @@ 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) - await vm.stateManager.putContractStorage(address, storageKey, storageVal) + await vm.stateManager.putStorage(address, storageKey, storageVal) } const codeBuf = hexToBytes('0x' + code) - await vm.stateManager.putContractCode(address, codeBuf) + await vm.stateManager.putCode(address, codeBuf) } await vm.stateManager.commit() diff --git a/packages/vm/src/requests.ts b/packages/vm/src/requests.ts index 10100698c0..1d5955058a 100644 --- a/packages/vm/src/requests.ts +++ b/packages/vm/src/requests.ts @@ -67,7 +67,7 @@ const accumulateEIP7002Requests = async ( ) const withdrawalsAddress = Address.fromString(bytesToHex(addressBytes)) - const code = await vm.stateManager.getContractCode(withdrawalsAddress) + const code = await vm.stateManager.getCode(withdrawalsAddress) if (code.length === 0) { throw new Error( @@ -117,7 +117,7 @@ const accumulateEIP7251Requests = async ( ) const consolidationsAddress = Address.fromString(bytesToHex(addressBytes)) - const code = await vm.stateManager.getContractCode(consolidationsAddress) + const code = await vm.stateManager.getCode(consolidationsAddress) if (code.length === 0) { throw new Error( diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 3715a65d78..49534c088a 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -527,7 +527,7 @@ export async function accumulateParentBlockHash( ).accessWitness!.touchAddressOnWriteAndComputeGas(historyAddress, treeIndex, subIndex) } const key = setLengthLeft(bigIntToBytes(ringKey), 32) - await vm.stateManager.putContractStorage(historyAddress, key, hash) + await vm.stateManager.putStorage(historyAddress, key, hash) } await putBlockHash(vm, parentHash, currentBlockNumber - BIGINT_1) @@ -564,12 +564,12 @@ export async function accumulateParentBeaconBlockRoot(vm: VM, root: Uint8Array, await vm.evm.journal.putAccount(parentBeaconBlockRootAddress, new Account()) } - await vm.stateManager.putContractStorage( + await vm.stateManager.putStorage( parentBeaconBlockRootAddress, setLengthLeft(bigIntToBytes(timestampIndex), 32), bigIntToBytes(timestamp), ) - await vm.stateManager.putContractStorage( + await vm.stateManager.putStorage( parentBeaconBlockRootAddress, setLengthLeft(bigIntToBytes(timestampExtended), 32), root, diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 0ccba5a4f2..a51be5d7b8 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -494,8 +494,8 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { } const addressConverted = new Address(address) - const addressCode = await vm.stateManager.getContractCode(addressConverted) - await vm.stateManager.putContractCode(authority, addressCode) + const addressCode = await vm.stateManager.getCode(addressConverted) + await vm.stateManager.putCode(authority, addressCode) writtenAddresses.add(authority.toString()) vm.evm.journal.addAlwaysWarmAddress(authority.toString()) @@ -687,7 +687,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise { for (const str of writtenAddresses) { const address = Address.fromString(str) - await vm.stateManager.putContractCode(address, new Uint8Array()) + await vm.stateManager.putCode(address, new Uint8Array()) } if (enableProfiler) { diff --git a/packages/vm/test/api/EIPs/eip-1153.spec.ts b/packages/vm/test/api/EIPs/eip-1153.spec.ts index 894cfc57b0..23e76af7d4 100644 --- a/packages/vm/test/api/EIPs/eip-1153.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1153.spec.ts @@ -54,7 +54,7 @@ describe('EIP 1153: transient storage', () => { }) for (const { code, address } of test.contracts) { - await vm.stateManager.putContractCode(address, hexToBytes(code as PrefixedHexString)) + await vm.stateManager.putCode(address, hexToBytes(code as PrefixedHexString)) } const fromAddress = new Address(privateToAddress(senderKey)) diff --git a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts index f772db6d6f..37ba98da19 100644 --- a/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1283-net-gas-metering.spec.ts @@ -42,9 +42,9 @@ describe('Constantinople: EIP-1283', () => { const account = createAccountWithDefaults(BigInt(0), BigInt(0)) await vm.stateManager.putAccount(addr, account) - await vm.stateManager.putContractCode(addr, hexToBytes(testCase.code as PrefixedHexString)) + await vm.stateManager.putCode(addr, hexToBytes(testCase.code as PrefixedHexString)) if (testCase.original !== BigInt(0)) { - await vm.stateManager.putContractStorage(addr, key, bigIntToBytes(testCase.original)) + await vm.stateManager.putStorage(addr, key, bigIntToBytes(testCase.original)) } const runCallArgs = { diff --git a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts index 6a4d50708e..1a16a18a67 100644 --- a/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts +++ b/packages/vm/test/api/EIPs/eip-1559-FeeMarket.spec.ts @@ -196,7 +196,7 @@ describe('EIP1559 tests', () => { // (This code returns the reported GASPRICE) const code = hexToBytes('0x3A60005260206000F3') - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const result = await runTx(vm, { tx: block.transactions[0], block }) const returnValue = result.execResult.returnValue diff --git a/packages/vm/test/api/EIPs/eip-2929.spec.ts b/packages/vm/test/api/EIPs/eip-2929.spec.ts index e1c0f4967d..3083489663 100644 --- a/packages/vm/test/api/EIPs/eip-2929.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2929.spec.ts @@ -47,7 +47,7 @@ describe('EIP 2929: gas cost tests', () => { i++ }) - await vm.stateManager.putContractCode(address, hexToBytes(test.code)) + await vm.stateManager.putCode(address, hexToBytes(test.code)) const unsignedTx = createLegacyTx({ gasLimit: initialGas, // ensure we pass a lot of gas, so we do not run out of gas @@ -73,7 +73,7 @@ describe('EIP 2929: gas cost tests', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin, eips: [2929] }) const vm = await VM.create({ common }) - await vm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code + await vm.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code // setup the call arguments const unsignedTx = createLegacyTx({ diff --git a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts index 042377e11b..01d0bc4b06 100644 --- a/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2930-accesslists.spec.ts @@ -48,7 +48,7 @@ describe('EIP-2930 Optional Access Lists tests', () => { const vm = await VM.create({ common }) // contract code PUSH1 0x00 SLOAD STOP - await vm.stateManager.putContractCode(contractAddress, hexToBytes('0x60005400')) + await vm.stateManager.putCode(contractAddress, hexToBytes('0x60005400')) const address = Address.fromPrivateKey(privateKey) const initialBalance = BigInt(10) ** BigInt(18) 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 1eff605d0d..f38c999b80 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 @@ -131,7 +131,7 @@ describe('EIP 2935: historical block hashes', () => { const account = await vm.stateManager.getAccount(callerAddress) account!.balance = PREBALANCE await vm.stateManager.putAccount(callerAddress, account!) - await vm.stateManager.putContractCode(historyAddress, contract2935Code) + await vm.stateManager.putCode(historyAddress, contract2935Code) const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) const blockHashi = result.execResult.returnValue @@ -190,7 +190,7 @@ describe('EIP 2935: historical block hashes', () => { await vm.blockchain.putBlock(block) await runBlock(vm, { block, generate: true }) - const storage = await vm.stateManager.getContractStorage( + const storage = await vm.stateManager.getStorage( historyAddress, setLengthLeft(bigIntToBytes(BigInt(0)), 32), ) @@ -247,7 +247,7 @@ describe('EIP 2935: historical block hashes', () => { for (let i = 1; i <= blocksToBuild; i++) { const block = await blockchain.getBlock(i) - const storage = await vm.stateManager.getContractStorage( + const storage = await vm.stateManager.getStorage( historyAddress, setLengthLeft(bigIntToBytes(BigInt(i) % historyServeWindow), 32), ) diff --git a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts index e912290e6d..1e9d5d23db 100644 --- a/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3074-authcall.spec.ts @@ -239,7 +239,7 @@ describe('EIP-3074 AUTH', () => { const signature = signMessage(message, contractAddress, privateKey) const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -263,7 +263,7 @@ describe('EIP-3074 AUTH', () => { signature.r = signature.s const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -288,7 +288,7 @@ describe('EIP-3074 AUTH', () => { // use the contractAddress instead of authAddress for the expected address (this should fail) const code = concatBytes(getAuthCode(message, signature, contractAddress), RETURNTOP) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -311,7 +311,7 @@ describe('EIP-3074 AUTH', () => { const signature = flipSignature(signMessage(message, contractAddress, privateKey)) const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -335,7 +335,7 @@ describe('EIP-3074 AUTH', () => { signature.v = 2 const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNTOP) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -364,7 +364,7 @@ describe('EIP-3074 AUTH', () => { RETURNTOP, ) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -390,7 +390,7 @@ describe('EIP-3074 AUTH', () => { RETURNTOP, ) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -413,7 +413,7 @@ describe('EIP-3074 AUTH', () => { const signature = signMessage(message, contractAddress, privateKey) const code = concatBytes(getAuthCode(message, signature, authAddress), RETURNMEMSIZE) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) const tx = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -439,7 +439,7 @@ describe('EIP-3074 AUTH', () => { RETURNMEMSIZE, ) - await vm.stateManager.putContractCode(contractAddress, code2) + await vm.stateManager.putCode(contractAddress, code2) const tx2 = createLegacyTx({ to: contractAddress, gasLimit: 1000000, @@ -463,8 +463,8 @@ describe('EIP-3074 AUTH', () => { // Setups the environment for the VM, puts `code` at contractAddress and also puts the STORECALLER bytecode at the contractStorageAddress async function setupVM(code: Uint8Array) { const vm = await VM.create({ common: common.copy() }) - await vm.stateManager.putContractCode(contractAddress, code) - await vm.stateManager.putContractCode(contractStorageAddress, STORECALLER) + await vm.stateManager.putCode(contractAddress, code) + await vm.stateManager.putCode(contractStorageAddress, STORECALLER) await vm.stateManager.putAccount(callerAddress, new Account()) const account = await vm.stateManager.getAccount(callerAddress) account!.balance = PREBALANCE @@ -496,7 +496,7 @@ describe('EIP-3074 AUTHCALL', () => { const buf = result.execResult.returnValue.slice(31) assert.deepEqual(buf, hexToBytes('0x01'), 'authcall success') - const storage = await vm.stateManager.getContractStorage(contractStorageAddress, zeros(32)) + const storage = await vm.stateManager.getStorage(contractStorageAddress, zeros(32)) assert.deepEqual(storage, address.bytes, 'caller set correctly') }) @@ -527,7 +527,7 @@ describe('EIP-3074 AUTHCALL', () => { await runTx(vm, { tx, block, skipHardForkValidation: true }) - const gasUsed = await vm.stateManager.getContractStorage( + const gasUsed = await vm.stateManager.getStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}01`), ) @@ -568,7 +568,7 @@ describe('EIP-3074 AUTHCALL', () => { await runTx(vm, { tx, block, skipHardForkValidation: true }) - const gasUsed = await vm.stateManager.getContractStorage( + const gasUsed = await vm.stateManager.getStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}01`), ) @@ -657,7 +657,7 @@ describe('EIP-3074 AUTHCALL', () => { const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) - const gasUsed = await vm.stateManager.getContractStorage( + const gasUsed = await vm.stateManager.getStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}01`), ) @@ -818,7 +818,7 @@ describe('EIP-3074 AUTHCALL', () => { }).sign(callerPrivateKey) await runTx(vm, { tx, block, skipHardForkValidation: true }) - const gas = await vm.stateManager.getContractStorage( + const gas = await vm.stateManager.getStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}01`), ) @@ -851,7 +851,7 @@ describe('EIP-3074 AUTHCALL', () => { }).sign(callerPrivateKey) const result = await runTx(vm, { tx, block, skipHardForkValidation: true }) - const callInput = await vm.stateManager.getContractStorage( + const callInput = await vm.stateManager.getStorage( contractStorageAddress, hexToBytes(`0x${'00'.repeat(31)}02`), ) diff --git a/packages/vm/test/api/EIPs/eip-3529.spec.ts b/packages/vm/test/api/EIPs/eip-3529.spec.ts index 1a80cd793f..0ce7155b93 100644 --- a/packages/vm/test/api/EIPs/eip-3529.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3529.spec.ts @@ -132,13 +132,13 @@ describe('EIP-3529 tests', () => { const code = hexToBytes(`${testCase.code as PrefixedHexString}00`) // add a STOP opcode (0 gas) so we can find the gas used / effective gas await vm.stateManager.putAccount(address, new Account()) - await vm.stateManager.putContractStorage( + await vm.stateManager.putStorage( address, key, hexToBytes(`0x${testCase.original.toString().padStart(64, '0')}`), ) - await vm.stateManager.getContractStorage(address, key) + await vm.stateManager.getStorage(address, key) vm.evm.journal.addAlwaysWarmSlot(bytesToHex(address.bytes), bytesToHex(key)) await vm.evm.runCode!({ @@ -202,7 +202,7 @@ describe('EIP-3529 tests', () => { for (let i = 0; i < 100; i++) { const key = hexToBytes(`0x${i.toString(16).padStart(64, '0')}`) await vm.stateManager.putAccount(address, new Account()) - await vm.stateManager.putContractStorage(address, key, value) + await vm.stateManager.putStorage(address, key, value) const hex = i.toString(16).padStart(2, '0') // push 0 push sstore code = `${code}600060${hex}55` @@ -210,7 +210,7 @@ describe('EIP-3529 tests', () => { code = `${code}00` - await vm.stateManager.putContractCode(address, hexToBytes(code)) + await vm.stateManager.putCode(address, hexToBytes(code)) const tx = createLegacyTx({ to: address, diff --git a/packages/vm/test/api/EIPs/eip-3541.spec.ts b/packages/vm/test/api/EIPs/eip-3541.spec.ts index d30c7fd17e..7edee010b9 100644 --- a/packages/vm/test/api/EIPs/eip-3541.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3541.spec.ts @@ -26,7 +26,7 @@ describe('EIP 3541 tests', () => { let result = await runTx(vm, { tx, skipHardForkValidation: true }) let created = result.createdAddress - let code = await vm.stateManager.getContractCode(created!) + let code = await vm.stateManager.getCode(created!) assert.equal(code.length, 0, 'did not deposit code') @@ -42,7 +42,7 @@ describe('EIP 3541 tests', () => { result = await runTx(vm, { tx: tx1, skipHardForkValidation: true }) created = result.createdAddress - code = await vm.stateManager.getContractCode(created!) + code = await vm.stateManager.getCode(created!) assert.ok(code.length > 0, 'did deposit code') @@ -57,7 +57,7 @@ describe('EIP 3541 tests', () => { result = await runTx(vm, { tx: tx2, skipHardForkValidation: true }) created = result.createdAddress - code = await vm.stateManager.getContractCode(created!) + code = await vm.stateManager.getCode(created!) assert.ok(code.length > 0, 'did deposit code') }) @@ -79,7 +79,7 @@ describe('EIP 3541 tests', () => { await runTx(vm, { tx, skipHardForkValidation: true }) - let code = await vm.stateManager.getContractCode(address!) + let code = await vm.stateManager.getCode(address!) assert.equal(code.length, 0, 'did not deposit code') @@ -92,7 +92,7 @@ describe('EIP 3541 tests', () => { await runTx(vm, { tx: tx1, skipHardForkValidation: true }) - code = await vm.stateManager.getContractCode(address!) + code = await vm.stateManager.getCode(address!) assert.ok(code.length > 0, 'did deposit code') }) @@ -114,7 +114,7 @@ describe('EIP 3541 tests', () => { await runTx(vm, { tx, skipHardForkValidation: true }) - let code = await vm.stateManager.getContractCode(address!) + let code = await vm.stateManager.getCode(address!) assert.equal(code.length, 0, 'did not deposit code') @@ -127,7 +127,7 @@ describe('EIP 3541 tests', () => { await runTx(vm, { tx: tx1, skipHardForkValidation: true }) - code = await vm.stateManager.getContractCode(address!) + code = await vm.stateManager.getCode(address!) assert.ok(code.length > 0, 'did deposit code') }) diff --git a/packages/vm/test/api/EIPs/eip-3607.spec.ts b/packages/vm/test/api/EIPs/eip-3607.spec.ts index 4a8b12b977..a091769b45 100644 --- a/packages/vm/test/api/EIPs/eip-3607.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3607.spec.ts @@ -12,7 +12,7 @@ describe('EIP-3607 tests', () => { it('should reject txs from senders with deployed code when EIP is enabled', async () => { const vm = await VM.create({ common }) - await vm.stateManager.putContractCode(precompileAddr, new Uint8Array(32).fill(1)) + await vm.stateManager.putCode(precompileAddr, new Uint8Array(32).fill(1)) const tx = createLegacyTx({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { @@ -29,7 +29,7 @@ describe('EIP-3607 tests', () => { it('should not reject txs from senders with deployed code when EIP is not enabled', async () => { const vm = await VM.create({ common: commonNoEIP3607 }) - await vm.stateManager.putContractCode(precompileAddr, new Uint8Array(32).fill(1)) + await vm.stateManager.putCode(precompileAddr, new Uint8Array(32).fill(1)) const tx = createLegacyTx({ gasLimit: 100000 }, { freeze: false }) tx.getSenderAddress = () => precompileAddr try { diff --git a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts index 8a43198746..a3367ba614 100644 --- a/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3651-warm-coinbase.spec.ts @@ -38,7 +38,7 @@ async function getVM(common: Common) { account!.balance = balance await vm.stateManager.putAccount(sender, account!) - await vm.stateManager.putContractCode(contractAddress, code) + await vm.stateManager.putCode(contractAddress, code) return vm } diff --git a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts index 1e00713d3c..fd962e1951 100644 --- a/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4788-beaconroot.spec.ts @@ -105,8 +105,8 @@ async function runBlock(block: Block) { common, }) - await vm.stateManager.putContractCode(contractAddress, hexToBytes(CODE)) - await vm.stateManager.putContractCode(BROOT_Address, hexToBytes(BROOT_CODE)) + await vm.stateManager.putCode(contractAddress, hexToBytes(CODE)) + await vm.stateManager.putCode(BROOT_Address, hexToBytes(BROOT_CODE)) return { vmResult: await runBlockVM(vm, { block, @@ -122,7 +122,7 @@ async function runBlock(block: Block) { * Get call status saved in the contract */ async function getCallStatus(vm: VM) { - const stat = await vm.stateManager.getContractStorage(contractAddress, zeros(32)) + const stat = await vm.stateManager.getStorage(contractAddress, zeros(32)) return bytesToBigInt(stat) } diff --git a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts index fb313c63bd..097d4561ca 100644 --- a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts @@ -49,7 +49,7 @@ describe('EIP4895 tests', () => { const withdrawalCheckAddress = new Address(hexToBytes(`0x${'fe'.repeat(20)}`)) const withdrawalCode = hexToBytes('0x6002600055') - await vm.stateManager.putContractCode(withdrawalCheckAddress, withdrawalCode) + await vm.stateManager.putCode(withdrawalCheckAddress, withdrawalCode) const contractAddress = new Address(hexToBytes(`0x${'ff'.repeat(20)}`)) @@ -62,7 +62,7 @@ describe('EIP4895 tests', () => { PUSH 0 RETURN // Return the balance */ - await vm.stateManager.putContractCode( + await vm.stateManager.putCode( contractAddress, hexToBytes(`0x73${addresses[0]}3160005260206000F3`), ) @@ -123,7 +123,7 @@ describe('EIP4895 tests', () => { assert.deepEqual(zeros(32), result!, 'withdrawals happen after transactions') - const slotValue = await vm.stateManager.getContractStorage(withdrawalCheckAddress, zeros(32)) + const slotValue = await vm.stateManager.getStorage(withdrawalCheckAddress, zeros(32)) assert.deepEqual(zeros(0), slotValue, 'withdrawals do not invoke code') }) diff --git a/packages/vm/test/api/EIPs/eip-6110.spec.ts b/packages/vm/test/api/EIPs/eip-6110.spec.ts index d7d1425bd0..2f6341f3f3 100644 --- a/packages/vm/test/api/EIPs/eip-6110.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6110.spec.ts @@ -47,7 +47,7 @@ describe('EIP-6110 runBlock tests', () => { }) const beaconContractAddress = Address.fromString(DEPOSIT_CONTRACT_ADDRESS) await vm.stateManager.putAccount(beaconContractAddress, beaconContractAccount) - await vm.stateManager.putContractCode(beaconContractAddress, depositContractByteCode) + await vm.stateManager.putCode(beaconContractAddress, depositContractByteCode) await vm.stateManager.putAccount(sender, createAccount({ balance: 540000000030064771065n })) const block = createBlockFromBlockData( { @@ -80,7 +80,7 @@ describe('EIP-7685 buildBlock tests', () => { }) const beaconContractAddress = Address.fromString(DEPOSIT_CONTRACT_ADDRESS) await vm.stateManager.putAccount(beaconContractAddress, beaconContractAccount) - await vm.stateManager.putContractCode(beaconContractAddress, depositContractByteCode) + await vm.stateManager.putCode(beaconContractAddress, depositContractByteCode) await vm.stateManager.putAccount(sender, createAccount({ balance: 540000000030064771065n })) const block = createBlockFromBlockData({}, { common }) ;(vm.blockchain as any)['dbManager']['getHeader'] = () => block.header diff --git a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts index 236c3cb238..ffe1936b26 100644 --- a/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts +++ b/packages/vm/test/api/EIPs/eip-6780-selfdestruct-same-tx.spec.ts @@ -72,7 +72,7 @@ describe('EIP 6780 tests', () => { const target = Address.fromString('0x' + 'ff'.repeat(20)) - await vm.stateManager.putContractCode(target, payload) + await vm.stateManager.putCode(target, payload) const targetContract = await vm.stateManager.getAccount(target) targetContract!.nonce = BigInt(1) await vm.stateManager.putAccount(target, targetContract) @@ -92,7 +92,7 @@ describe('EIP 6780 tests', () => { assert.equal(contract.nonce, BigInt(1), 'nonce 1') const key = hexToBytes(`0x${'00'.repeat(31)}01`) - const storage = await vm.stateManager.getContractStorage(target, key) + const storage = await vm.stateManager.getStorage(target, key) assert.ok(equalsBytes(storage, hexToBytes('0x01')), 'storage not cleared') assert.equal( diff --git a/packages/vm/test/api/EIPs/eip-7702.spec.ts b/packages/vm/test/api/EIPs/eip-7702.spec.ts index bb94ba5226..89f0d4ad87 100644 --- a/packages/vm/test/api/EIPs/eip-7702.spec.ts +++ b/packages/vm/test/api/EIPs/eip-7702.spec.ts @@ -78,10 +78,10 @@ async function runTest( ).sign(defaultSenderPkey) const code1 = hexToBytes('0x600160015500') - await vm.stateManager.putContractCode(code1Addr, code1) + await vm.stateManager.putCode(code1Addr, code1) const code2 = hexToBytes('0x600260015500') - await vm.stateManager.putContractCode(code2Addr, code2) + await vm.stateManager.putCode(code2Addr, code2) const acc = (await vm.stateManager.getAccount(defaultSenderAddr)) ?? new Account() acc.balance = BigInt(1_000_000_000) @@ -90,7 +90,7 @@ async function runTest( await runTx(vm, { tx }) const slot = hexToBytes('0x' + '00'.repeat(31) + '01') - const value = await vm.stateManager.getContractStorage(defaultAuthAddr, slot) + const value = await vm.stateManager.getStorage(defaultAuthAddr, slot) assert.ok(equalsBytes(unpadBytes(expect), value)) if (skipEmptyCode === undefined) { @@ -172,7 +172,7 @@ describe('EIP 7702: set code to EOA accounts', () => { it('Code is already present in account', async () => { const vm = await VM.create({ common }) - await vm.stateManager.putContractCode(defaultAuthAddr, new Uint8Array([1])) + await vm.stateManager.putCode(defaultAuthAddr, new Uint8Array([1])) await runTest( [ { @@ -205,7 +205,7 @@ describe('EIP 7702: set code to EOA accounts', () => { ) const checkAddressWarm = Address.fromString(`0x${'FA'.repeat(20)}`) - await vm.stateManager.putContractCode(checkAddressWarm, checkAddressWarmCode) + await vm.stateManager.putCode(checkAddressWarm, checkAddressWarmCode) const tx = create7702EOACodeTx( { @@ -219,7 +219,7 @@ describe('EIP 7702: set code to EOA accounts', () => { ).sign(defaultSenderPkey) const code1 = hexToBytes('0x') - await vm.stateManager.putContractCode(code1Addr, code1) + await vm.stateManager.putCode(code1Addr, code1) const acc = (await vm.stateManager.getAccount(defaultSenderAddr)) ?? new Account() acc.balance = BigInt(1_000_000_000) @@ -254,7 +254,7 @@ describe('EIP 7702: set code to EOA accounts', () => { // Store value 1 in storage slot 1 // PUSH1 PUSH1 SSTORE STOP const code = hexToBytes('0x600160015500') - await vm.stateManager.putContractCode(code1Addr, code) + await vm.stateManager.putCode(code1Addr, code) const acc = (await vm.stateManager.getAccount(defaultSenderAddr)) ?? new Account() acc.balance = BigInt(1_000_000_000) diff --git a/packages/vm/test/api/index.spec.ts b/packages/vm/test/api/index.spec.ts index c5323450ca..61a187cd0e 100644 --- a/packages/vm/test/api/index.spec.ts +++ b/packages/vm/test/api/index.spec.ts @@ -328,9 +328,9 @@ describe('VM -> setHardfork, state (deprecated), blockchain', () => { STOP */ - await vmNotActivated.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code + await vmNotActivated.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code await vmNotActivated.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x111))) // give calling account a positive balance - await vmActivated.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code + await vmActivated.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code await vmActivated.stateManager.putAccount(caller, new Account(BigInt(0), BigInt(0x111))) // give calling account a positive balance // setup the call arguments const runCallArgs = { diff --git a/packages/vm/test/api/istanbul/eip-2200.spec.ts b/packages/vm/test/api/istanbul/eip-2200.spec.ts index dd3b2948c5..d12a8766b7 100644 --- a/packages/vm/test/api/istanbul/eip-2200.spec.ts +++ b/packages/vm/test/api/istanbul/eip-2200.spec.ts @@ -54,9 +54,9 @@ describe('Istanbul: EIP-2200', () => { const account = createAccountWithDefaults(BigInt(0), BigInt(0)) await vm.stateManager.putAccount(addr, account) - await vm.stateManager.putContractCode(addr, hexToBytes(`0x${testCase.code}`)) + await vm.stateManager.putCode(addr, hexToBytes(`0x${testCase.code}`)) if (testCase.original !== BigInt(0)) { - await vm.stateManager.putContractStorage( + await vm.stateManager.putStorage( addr, key, hexToBytes(`0x${testCase.original.toString(16)}`), diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 0d554e61f5..c9be021617 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -619,10 +619,10 @@ describe('runBlock() -> tx types', async () => { await setBalance(vm, defaultSenderAddr, 0xfffffffffffffn) const code1 = hexToBytes('0x600160005500') - await vm.stateManager.putContractCode(code1Addr, code1) + await vm.stateManager.putCode(code1Addr, code1) const code2 = hexToBytes('0x600260005500') - await vm.stateManager.putContractCode(code2Addr, code2) + await vm.stateManager.putCode(code2Addr, code2) const authorizationListOpts = [ { address: code1Addr, @@ -667,7 +667,7 @@ describe('runBlock() -> tx types', async () => { ) await runBlock(vm, { block, skipBlockValidation: true, generate: true }) - const storage = await vm.stateManager.getContractStorage(defaultAuthAddr, zeros(32)) + const storage = await vm.stateManager.getStorage(defaultAuthAddr, zeros(32)) assert.ok(equalsBytes(storage, new Uint8Array([2]))) }) }) diff --git a/packages/vm/test/api/runTx.spec.ts b/packages/vm/test/api/runTx.spec.ts index f3b6920f11..7378d5c4f7 100644 --- a/packages/vm/test/api/runTx.spec.ts +++ b/packages/vm/test/api/runTx.spec.ts @@ -468,8 +468,8 @@ describe('runTx() -> runtime behavior', () => { */ const code = hexToBytes('0x6001600055FE') const address = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) - await vm.stateManager.putContractCode(address, code) - await vm.stateManager.putContractStorage( + await vm.stateManager.putCode(address, code) + await vm.stateManager.putStorage( address, hexToBytes(`0x${'00'.repeat(32)}`), hexToBytes(`0x${'00'.repeat(31)}01`), @@ -797,7 +797,7 @@ it('Validate EXTCODEHASH puts KECCAK256_NULL on stack if calling account has no // Puts EXTCODEHASH of CALLER into slot 0 const code = hexToBytes('0x333F60005500') const codeAddr = Address.fromString('0x' + '20'.repeat(20)) - await vm.stateManager.putContractCode(codeAddr, code) + await vm.stateManager.putCode(codeAddr, code) const tx = createLegacyTx({ gasLimit: 100000, @@ -812,7 +812,7 @@ it('Validate EXTCODEHASH puts KECCAK256_NULL on stack if calling account has no await vm.stateManager.putAccount(addr, acc!) await runTx(vm, { tx, skipHardForkValidation: true }) - const hash = await vm.stateManager.getContractStorage(codeAddr, zeros(32)) + const hash = await vm.stateManager.getStorage(codeAddr, zeros(32)) assert.deepEqual(hash, KECCAK256_NULL, 'hash ok') }) @@ -830,7 +830,7 @@ it('Validate CALL does not charge new account gas when calling CALLER and caller // Calls CALLER and sends back the ETH just sent with the transaction const code = hexToBytes('0x600080808034335AF100') const codeAddr = Address.fromString('0x' + '20'.repeat(20)) - await vm.stateManager.putContractCode(codeAddr, code) + await vm.stateManager.putCode(codeAddr, code) const tx = createLegacyTx({ gasLimit: 100000, @@ -861,7 +861,7 @@ it('Validate SELFDESTRUCT does not charge new account gas when calling CALLER an // Puts EXTCODEHASH of CALLER into slot 0 const code = hexToBytes('0x33FF') const codeAddr = Address.fromString('0x' + '20'.repeat(20)) - await vm.stateManager.putContractCode(codeAddr, code) + await vm.stateManager.putCode(codeAddr, code) const tx = createLegacyTx({ gasLimit: 100000, diff --git a/packages/vm/test/api/state/accountExists.spec.ts b/packages/vm/test/api/state/accountExists.spec.ts index 71ddc7c518..13cb994ef6 100644 --- a/packages/vm/test/api/state/accountExists.spec.ts +++ b/packages/vm/test/api/state/accountExists.spec.ts @@ -26,8 +26,8 @@ describe('correctly apply new account gas fee on pre-Spurious Dragon hardforks', const existingAccount = await vm.stateManager.getAccount(existingAddress) existingAccount!.balance = BigInt(1) await vm.stateManager.putAccount(existingAddress, existingAccount!) - await vm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code - await vm.stateManager.putContractStorage( + await vm.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code + await vm.stateManager.putStorage( contractAddress, hexToBytes('0xd08f588b94e47566eea77acec87441cecca23f61aea9ed8eb086c062d3837605'), hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001'), @@ -75,8 +75,8 @@ describe('do not apply new account gas fee for empty account in DB on pre-Spurio toBytes(emptyAddress), emptyAccount.serialize(), ) - await vm.stateManager.putContractCode(contractAddress, hexToBytes(code)) // setup the contract code - await vm.stateManager.putContractStorage( + await vm.stateManager.putCode(contractAddress, hexToBytes(code)) // setup the contract code + await vm.stateManager.putStorage( contractAddress, hexToBytes('0xd08f588b94e47566eea77acec87441cecca23f61aea9ed8eb086c062d3837605'), hexToBytes('0x0000000000000000000000000000000000000000000000000000000000000001'), diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 96ed73a1ba..98d877ec09 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -382,11 +382,11 @@ export async function setupPreConditions(state: EVMStateManagerInterface, testDa continue } const key = setLengthLeft(format(storageKey), 32) - await state.putContractStorage(address, key, val) + await state.putStorage(address, key, val) } // Put contract code - await state.putContractCode(address, codeBuf) + await state.putCode(address, codeBuf) const storageRoot = (await state.getAccount(address))!.storageRoot From 8d87e806add36b8face7a90e69636bf5f14a08b1 Mon Sep 17 00:00:00 2001 From: Holger Drewes Date: Fri, 26 Jul 2024 20:52:15 +0200 Subject: [PATCH 24/58] StateManager: Interface Refactor/Simplification (#3543) * Move originalStorageCache to main interface (implemented by all SMs, alternative: make optional) * Remove redundand getProof from interface * Move generateCanonicalGenesis to main SM interface, make optional, remove VM genesisState option (only 1 internal usage, can be easily replaced) * Move dumpStorage() over to main interface, make optional * Move dumpStorageRange() over to main interface, make optional, SM method clean up * Bug fix, fix Kaustinen6 test * Add simple clearStorage() implementation for simple SM * Fully remove EVMStateManager interface * Add clearCaches() to the official interface (called into from runBlock(), implemented by all SMs * Lint and test fixes * Edit comment --------- Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com> --- packages/client/src/execution/vmexecution.ts | 4 +- packages/client/src/rpc/modules/debug.ts | 24 ++++++++-- .../client/test/rpc/eth/estimateGas.spec.ts | 2 +- .../client/test/rpc/eth/getBalance.spec.ts | 2 +- .../getBlockTransactionCountByNumber.spec.ts | 4 +- packages/client/test/rpc/eth/getCode.spec.ts | 2 +- .../test/rpc/eth/getTransactionCount.spec.ts | 2 +- .../client/test/rpc/txpool/content.spec.ts | 2 +- packages/common/src/interfaces.ts | 46 ++++++++++++------- packages/evm/src/evm.ts | 4 +- packages/evm/src/interpreter.ts | 10 ++-- packages/evm/src/journal.ts | 6 +-- packages/evm/src/types.ts | 6 +-- packages/statemanager/src/rpcStateManager.ts | 18 +------- .../statemanager/src/simpleStateManager.ts | 35 ++------------ packages/statemanager/src/stateManager.ts | 4 +- .../src/statelessVerkleStateManager.ts | 35 +++----------- packages/vm/src/types.ts | 10 +--- packages/vm/src/vm.ts | 9 +--- .../api/EIPs/eip-4895-withdrawals.spec.ts | 4 +- packages/vm/test/api/customChain.spec.ts | 10 ++-- packages/vm/test/util.ts | 4 +- 22 files changed, 103 insertions(+), 140 deletions(-) diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index 87e73cd7e3..3b84ac4fef 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -296,11 +296,11 @@ export class VMExecution extends Execution { this.chain['_customGenesisState'] ?? getGenesis(Number(blockchain.common.chainId())) if ( !genesisState && - (this.vm instanceof DefaultStateManager || !this.config.statelessVerkle) + (!('generateCanonicalGenesis' in this.vm.stateManager) || !this.config.statelessVerkle) ) { throw new Error('genesisState not available') } else { - await this.vm.stateManager.generateCanonicalGenesis(genesisState) + await this.vm.stateManager.generateCanonicalGenesis!(genesisState) } } diff --git a/packages/client/src/rpc/modules/debug.ts b/packages/client/src/rpc/modules/debug.ts index 729889f199..758525c1cb 100644 --- a/packages/client/src/rpc/modules/debug.ts +++ b/packages/client/src/rpc/modules/debug.ts @@ -179,7 +179,13 @@ export class Debug { const memory = [] let storage = {} if (opts.disableStorage === false) { - storage = await vmCopy.stateManager.dumpStorage(step.address) + if (!('dumpStorage' in vmCopy.stateManager)) { + throw { + message: 'stateManager has no dumpStorage implementation', + code: INTERNAL_ERROR, + } + } + storage = await vmCopy.stateManager.dumpStorage!(step.address) } if (opts.enableMemory === true) { for (let x = 0; x < step.memoryWordCount; x++) { @@ -260,7 +266,13 @@ export class Debug { const memory = [] let storage = {} if (opts.disableStorage === false) { - storage = await vm.stateManager.dumpStorage(step.address) + if (!('dumpStorage' in vm.stateManager)) { + throw { + message: 'stateManager has no dumpStorage implementation', + code: INTERNAL_ERROR, + } + } + storage = await vm.stateManager.dumpStorage!(step.address) } if (opts.enableMemory === true) { for (let x = 0; x < step.memoryWordCount; x++) { @@ -347,13 +359,19 @@ export class Debug { const parentBlock = await this.chain.getBlock(block.header.parentHash) // Copy the VM and run transactions including the relevant transaction. const vmCopy = await this.vm.shallowCopy() + if (!('dumpStorageRange' in vmCopy.stateManager)) { + throw { + code: INTERNAL_ERROR, + message: 'stateManager has no dumpStorageRange implementation', + } + } await vmCopy.stateManager.setStateRoot(parentBlock.header.stateRoot) for (let i = 0; i <= txIndex; i++) { await runTx(vmCopy, { tx: block.transactions[i], block }) } // await here so that any error can be handled in the catch below for proper response - return vmCopy.stateManager.dumpStorageRange( + return vmCopy.stateManager.dumpStorageRange!( // Validator already verified that `account` and `startKey` are properly formatted. Address.fromString(account), BigInt(startKey), diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index a31fc8f10c..4210479c1a 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -39,7 +39,7 @@ describe( const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService assert.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address with balance const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index 2598d61a2f..63c5b34e30 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -32,7 +32,7 @@ describe( // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address with balance const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index ae29e1c366..63418f5b06 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -33,7 +33,7 @@ describe(method, () => { assert.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') @@ -80,7 +80,7 @@ describe(method, () => { assert.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index e214c0c882..720fd4496c 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -28,7 +28,7 @@ describe(method, () => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService assert.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index fbb77b7608..03d8e6e068 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -34,7 +34,7 @@ describe(method, () => { // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // a genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/txpool/content.spec.ts b/packages/client/test/rpc/txpool/content.spec.ts index bf95e680fa..d62745c125 100644 --- a/packages/client/test/rpc/txpool/content.spec.ts +++ b/packages/client/test/rpc/txpool/content.spec.ts @@ -29,7 +29,7 @@ describe(method, () => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService assert.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(getGenesis(1)) + await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) const gasLimit = 2000000 const parent = await blockchain.getCanonicalHeadHeader() const block = createBlockFromBlockData( diff --git a/packages/common/src/interfaces.ts b/packages/common/src/interfaces.ts index e67fe0da76..1768e417b1 100644 --- a/packages/common/src/interfaces.ts +++ b/packages/common/src/interfaces.ts @@ -148,6 +148,9 @@ export interface AccessWitnessInterface { * */ export interface StateManagerInterface { + /* + * Core Access Functionality + */ // Account methods getAccount(address: Address): Promise putAccount(address: Address, account?: Account): Promise @@ -164,35 +167,46 @@ export interface StateManagerInterface { putStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise clearStorage(address: Address): Promise - // Checkpointing methods + /* + * Checkpointing Functionality + */ checkpoint(): Promise commit(): Promise revert(): Promise - // State root methods + /* + * State Root Functionality + */ getStateRoot(): Promise setStateRoot(stateRoot: Uint8Array, clearCache?: boolean): Promise hasStateRoot(root: Uint8Array): Promise // only used in client - // Other + /* + * Extra Functionality + * + * Optional non-essential methods, these methods should always be guarded + * on usage (check for existance) + */ + // Client RPC getProof?(address: Address, storageSlots: Uint8Array[]): Promise - shallowCopy(downlevelCaches?: boolean): StateManagerInterface - getAppliedKey?(address: Uint8Array): Uint8Array + dumpStorage?(address: Address): Promise + dumpStorageRange?(address: Address, startKey: bigint, limit: number): Promise - // Verkle (experimental) - checkChunkWitnessPresent?(contract: Address, programCounter: number): Promise -} - -export interface EVMStateManagerInterface extends StateManagerInterface { + /* + * EVM/VM Specific Functionality + */ originalStorageCache: { get(address: Address, key: Uint8Array): Promise clear(): void } + generateCanonicalGenesis?(initState: any): Promise // TODO make input more typesafe + // only Verkle/EIP-6800 (experimental) + checkChunkWitnessPresent?(contract: Address, programCounter: number): Promise + getAppliedKey?(address: Uint8Array): Uint8Array // only for preimages - dumpStorage(address: Address): Promise // only used in client - dumpStorageRange(address: Address, startKey: bigint, limit: number): Promise // only used in client - generateCanonicalGenesis(initState: any): Promise // TODO make input more typesafe - getProof(address: Address, storageSlots?: Uint8Array[]): Promise - - shallowCopy(downlevelCaches?: boolean): EVMStateManagerInterface + /* + * Utility + */ + clearCaches(): void + shallowCopy(downlevelCaches?: boolean): StateManagerInterface } diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index fc40cf017b..cf954832e2 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -50,7 +50,7 @@ import type { ExecResult, bn128, } from './types.js' -import type { Common, EVMStateManagerInterface } from '@ethereumjs/common' +import type { Common, StateManagerInterface } from '@ethereumjs/common' const debug = debugDefault('evm:evm') const debugGas = debugDefault('evm:gas') @@ -94,7 +94,7 @@ export class EVM implements EVMInterface { public readonly common: Common public readonly events: AsyncEventEmitter - public stateManager: EVMStateManagerInterface + public stateManager: StateManagerInterface public blockchain: Blockchain public journal: Journal diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 55e776f271..ea3332427c 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -27,7 +27,7 @@ import type { EVM } from './evm.js' import type { Journal } from './journal.js' import type { AsyncOpHandler, Opcode, OpcodeMapEntry } from './opcodes/index.js' import type { Block, Blockchain, EOFEnv, EVMProfilerOpts, EVMResult, Log } from './types.js' -import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common' +import type { AccessWitnessInterface, Common, StateManagerInterface } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' const debugGas = debugDefault('evm:gas') @@ -86,7 +86,7 @@ export interface RunState { shouldDoJumpAnalysis: boolean validJumps: Uint8Array // array of values where validJumps[index] has value 0 (default), 1 (jumpdest), 2 (beginsub) cachedPushes: { [pc: number]: bigint } - stateManager: EVMStateManagerInterface + stateManager: StateManagerInterface blockchain: Blockchain env: Env messageGasLimit?: bigint // Cache value from `gas.ts` to save gas limit for a message call @@ -105,7 +105,7 @@ export interface InterpreterResult { export interface InterpreterStep { gasLeft: bigint gasRefund: bigint - stateManager: EVMStateManagerInterface + stateManager: StateManagerInterface stack: bigint[] pc: number depth: number @@ -128,7 +128,7 @@ export interface InterpreterStep { export class Interpreter { protected _vm: any protected _runState: RunState - protected _stateManager: EVMStateManagerInterface + protected _stateManager: StateManagerInterface protected common: Common public _evm: EVM public journal: Journal @@ -147,7 +147,7 @@ export class Interpreter { // TODO remove gasLeft as constructor argument constructor( evm: EVM, - stateManager: EVMStateManagerInterface, + stateManager: StateManagerInterface, blockchain: Blockchain, env: Env, gasLeft: bigint, diff --git a/packages/evm/src/journal.ts b/packages/evm/src/journal.ts index 9c17a3e861..c07884f620 100644 --- a/packages/evm/src/journal.ts +++ b/packages/evm/src/journal.ts @@ -10,7 +10,7 @@ import { import debugDefault from 'debug' import { hexToBytes } from 'ethereum-cryptography/utils' -import type { Common, EVMStateManagerInterface } from '@ethereumjs/common' +import type { Common, StateManagerInterface } from '@ethereumjs/common' import type { Account, PrefixedHexString } from '@ethereumjs/util' import type { Debugger } from 'debug' @@ -32,7 +32,7 @@ type JournalDiffItem = [Set, Map>, type JournalHeight = number export class Journal { - private stateManager: EVMStateManagerInterface + private stateManager: StateManagerInterface private common: Common private DEBUG: boolean private _debug: Debugger @@ -47,7 +47,7 @@ export class Journal { public accessList?: Map> public preimages?: Map - constructor(stateManager: EVMStateManagerInterface, common: Common) { + constructor(stateManager: StateManagerInterface, common: Common) { // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = diff --git a/packages/evm/src/types.ts b/packages/evm/src/types.ts index 4f001da07d..109b79129d 100644 --- a/packages/evm/src/types.ts +++ b/packages/evm/src/types.ts @@ -11,8 +11,8 @@ import type { PrecompileFunc } from './precompiles/types.js' import type { AccessWitnessInterface, Common, - EVMStateManagerInterface, ParamsDict, + StateManagerInterface, } from '@ethereumjs/common' import type { Account, Address, AsyncEventEmitter, PrefixedHexString } from '@ethereumjs/util' @@ -162,7 +162,7 @@ export interface EVMInterface { startReportingAccessList(): void startReportingPreimages?(): void } - stateManager: EVMStateManagerInterface + stateManager: StateManagerInterface precompiles: Map runCall(opts: EVMRunCallOpts): Promise runCode(opts: EVMRunCodeOpts): Promise @@ -312,7 +312,7 @@ export interface EVMOpts { * implementations for different needs (MPT-tree backed, RPC, experimental verkle) * which can be used by this option as a replacement. */ - stateManager?: EVMStateManagerInterface + stateManager?: StateManagerInterface /** * diff --git a/packages/statemanager/src/rpcStateManager.ts b/packages/statemanager/src/rpcStateManager.ts index 71ef9d06ef..6843ec0d7e 100644 --- a/packages/statemanager/src/rpcStateManager.ts +++ b/packages/statemanager/src/rpcStateManager.ts @@ -19,18 +19,13 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { AccountCache, CacheType, OriginalStorageCache, StorageCache } from './cache/index.js' import type { Proof, RPCStateManagerOpts } from './index.js' -import type { - AccountFields, - EVMStateManagerInterface, - StorageDump, - StorageRange, -} from '@ethereumjs/common' +import type { AccountFields, StateManagerInterface, StorageDump } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' import type { Debugger } from 'debug' const KECCAK256_RLP_EMPTY_ACCOUNT = RLP.encode(new Account().serialize()).slice(2) -export class RPCStateManager implements EVMStateManagerInterface { +export class RPCStateManager implements StateManagerInterface { protected _provider: string protected _contractCache: Map protected _storageCache: StorageCache @@ -213,11 +208,6 @@ export class RPCStateManager implements EVMStateManagerInterface { return Promise.resolve(dump) } - dumpStorageRange(_address: Address, _startKey: bigint, _limit: number): Promise { - // TODO: Implement. - return Promise.reject() - } - /** * Checks if an `account` exists at `address` * @param address - Address of the `account` to check @@ -436,10 +426,6 @@ export class RPCStateManager implements EVMStateManagerInterface { hasStateRoot = () => { throw new Error('function not implemented') } - - generateCanonicalGenesis(_initState: any): Promise { - return Promise.resolve() - } } export class RPCBlockChain { diff --git a/packages/statemanager/src/simpleStateManager.ts b/packages/statemanager/src/simpleStateManager.ts index 8169bbb1b5..8c58c616ba 100644 --- a/packages/statemanager/src/simpleStateManager.ts +++ b/packages/statemanager/src/simpleStateManager.ts @@ -4,14 +4,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { OriginalStorageCache } from './cache/originalStorageCache.js' import type { SimpleStateManagerOpts } from './index.js' -import type { - AccountFields, - Common, - EVMStateManagerInterface, - Proof, - StorageDump, - StorageRange, -} from '@ethereumjs/common' +import type { AccountFields, Common, StateManagerInterface } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' /** @@ -29,7 +22,7 @@ import type { Address, PrefixedHexString } from '@ethereumjs/util' * For a more full fledged and MPT-backed state manager implementation * have a look at the `@ethereumjs/statemanager` package. */ -export class SimpleStateManager implements EVMStateManagerInterface { +export class SimpleStateManager implements StateManagerInterface { public accountStack: Map[] = [] public codeStack: Map[] = [] public storageStack: Map[] = [] @@ -125,6 +118,8 @@ export class SimpleStateManager implements EVMStateManagerInterface { this.topStorageStack().set(`${address.toString()}_${bytesToHex(key)}`, value) } + async clearStorage(): Promise {} + async checkpoint(): Promise { this.checkpointSync() } @@ -143,7 +138,7 @@ export class SimpleStateManager implements EVMStateManagerInterface { async flush(): Promise {} clearCaches(): void {} - shallowCopy(): EVMStateManagerInterface { + shallowCopy(): StateManagerInterface { const copy = new SimpleStateManager({ common: this.common }) for (let i = 0; i < this.accountStack.length; i++) { copy.accountStack.push(new Map(this.accountStack[i])) @@ -163,24 +158,4 @@ export class SimpleStateManager implements EVMStateManagerInterface { hasStateRoot(): Promise { throw new Error('Method not implemented.') } - - // Only goes for long term create situations, skip - async clearStorage(): Promise {} - - // Only "core" methods implemented - dumpStorage(): Promise { - throw new Error('Method not implemented.') - } - dumpStorageRange(): Promise { - throw new Error('Method not implemented.') - } - generateCanonicalGenesis(): Promise { - throw new Error('Method not implemented.') - } - getProof(): Promise { - throw new Error('Method not implemented.') - } - getAppliedKey?(): Uint8Array { - throw new Error('Method not implemented.') - } } diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index ab1435118f..50aad47542 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -38,8 +38,8 @@ import { CODEHASH_PREFIX, type CacheSettings, type DefaultStateManagerOpts } fro import type { StorageProof } from './index.js' import type { AccountFields, - EVMStateManagerInterface, Proof, + StateManagerInterface, StorageDump, StorageRange, } from '@ethereumjs/common' @@ -61,7 +61,7 @@ import type { Debugger } from 'debug' * package which might be an alternative to this implementation * for many basic use cases. */ -export class DefaultStateManager implements EVMStateManagerInterface { +export class DefaultStateManager implements StateManagerInterface { protected _debug: Debugger protected _accountCache?: AccountCache protected _storageCache?: StorageCache diff --git a/packages/statemanager/src/statelessVerkleStateManager.ts b/packages/statemanager/src/statelessVerkleStateManager.ts index 589d868505..4fc1d33211 100644 --- a/packages/statemanager/src/statelessVerkleStateManager.ts +++ b/packages/statemanager/src/statelessVerkleStateManager.ts @@ -36,13 +36,7 @@ import { import type { AccessedStateWithAddress } from './accessWitness.js' import type { CacheSettings, StatelessVerkleStateManagerOpts, VerkleState } from './index.js' import type { DefaultStateManager } from './stateManager.js' -import type { - AccountFields, - EVMStateManagerInterface, - Proof, - StorageDump, - StorageRange, -} from '@ethereumjs/common' +import type { AccountFields, Proof, StateManagerInterface } from '@ethereumjs/common' import type { Address, PrefixedHexString, @@ -72,7 +66,7 @@ const ZEROVALUE = '0x00000000000000000000000000000000000000000000000000000000000 * to fetch data requested by the the VM. * */ -export class StatelessVerkleStateManager implements EVMStateManagerInterface { +export class StatelessVerkleStateManager implements StateManagerInterface { _accountCache?: AccountCache _storageCache?: StorageCache _codeCache?: CodeCache @@ -259,7 +253,7 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { * at the last fully committed point, i.e. as if all current * checkpoints were reverted. */ - shallowCopy(): EVMStateManagerInterface { + shallowCopy(): StateManagerInterface { const stateManager = new StatelessVerkleStateManager({ verkleCrypto: this.verkleCrypto }) return stateManager } @@ -847,21 +841,6 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { this._cachedStateRoot = stateRoot } - /** - * Dumps the RLP-encoded storage values for an `account` specified by `address`. - * @param address - The address of the `account` to return storage for - * @returns {Promise} - The state of the account as an `Object` map. - * Keys are are the storage keys, values are the storage values as strings. - * Both are represented as hex strings without the `0x` prefix. - */ - async dumpStorage(_: Address): Promise { - throw Error('not implemented') - } - - dumpStorageRange(_: Address, __: bigint, ___: number): Promise { - throw Error('not implemented') - } - /** * Clears all underlying caches */ @@ -871,11 +850,11 @@ export class StatelessVerkleStateManager implements EVMStateManagerInterface { this._storageCache?.clear() } + // TODO: Removing this causes a Kaustinen6 test in client to fail + // Seems to point to a more general (non-severe) bug and can likely be fixed + // by having the `statelessVerkle` config option more properly set by the + // test for the check in the VM execution to call into this method generateCanonicalGenesis(_initState: any): Promise { return Promise.resolve() } - - getAppliedKey(_: Uint8Array): Uint8Array { - throw Error('not implemented') - } } diff --git a/packages/vm/src/types.ts b/packages/vm/src/types.ts index c31c17547b..7b35718782 100644 --- a/packages/vm/src/types.ts +++ b/packages/vm/src/types.ts @@ -1,14 +1,13 @@ import type { Bloom } from './bloom/index.js' import type { Block, BlockOptions, HeaderData } from '@ethereumjs/block' import type { BlockchainInterface } from '@ethereumjs/blockchain' -import type { Common, EVMStateManagerInterface, ParamsDict } from '@ethereumjs/common' +import type { Common, ParamsDict, StateManagerInterface } from '@ethereumjs/common' import type { EVMInterface, EVMOpts, EVMResult, Log } from '@ethereumjs/evm' import type { AccessList, TypedTransaction } from '@ethereumjs/tx' import type { BigIntLike, CLRequest, CLRequestType, - GenesisState, PrefixedHexString, WithdrawalData, } from '@ethereumjs/util' @@ -118,7 +117,7 @@ export interface VMOpts { /** * A {@link StateManager} instance to use as the state store */ - stateManager?: EVMStateManagerInterface + stateManager?: StateManagerInterface /** * A {@link Blockchain} object for storing/retrieving blocks */ @@ -137,11 +136,6 @@ export interface VMOpts { * Default: `false` */ activatePrecompiles?: boolean - /** - * A genesisState to generate canonical genesis for the "in-house" created stateManager if external - * stateManager not provided for the VM, defaults to an empty state - */ - genesisState?: GenesisState /** * Set the hardfork either by timestamp (for HFs from Shanghai onwards) or by block number diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index 9050c6050b..7cd54434c3 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -14,7 +14,7 @@ import { paramsVM } from './params.js' import type { VMEvents, VMOpts } from './types.js' import type { BlockchainInterface } from '@ethereumjs/blockchain' -import type { EVMStateManagerInterface } from '@ethereumjs/common' +import type { StateManagerInterface } from '@ethereumjs/common' import type { EVMInterface } from '@ethereumjs/evm' import type { BigIntLike } from '@ethereumjs/util' @@ -28,7 +28,7 @@ export class VM { /** * The StateManager used by the VM */ - readonly stateManager: EVMStateManagerInterface + readonly stateManager: StateManagerInterface /** * The blockchain the VM operates on @@ -89,11 +89,6 @@ export class VM { opts.blockchain = await createBlockchain({ common: opts.common }) } - const genesisState = opts.genesisState ?? {} - if (opts.genesisState !== undefined) { - await opts.stateManager.generateCanonicalGenesis(genesisState) - } - if (opts.profilerOpts !== undefined) { const profilerOpts = opts.profilerOpts if (profilerOpts.reportAfterBlock === true && profilerOpts.reportAfterTx === true) { diff --git a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts index 097d4561ca..50a704a2d8 100644 --- a/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts +++ b/packages/vm/test/api/EIPs/eip-4895-withdrawals.spec.ts @@ -130,7 +130,7 @@ describe('EIP4895 tests', () => { it('EIP4895: state updation should exclude 0 amount updates', async () => { const vm = await VM.create({ common }) - await vm.stateManager.generateCanonicalGenesis(parseGethGenesisState(genesisJSON)) + await vm.stateManager.generateCanonicalGenesis!(parseGethGenesisState(genesisJSON)) const preState = bytesToHex(await vm.stateManager.getStateRoot()) assert.equal( preState, @@ -208,7 +208,7 @@ describe('EIP4895 tests', () => { 'correct state root should be generated', ) const vm = await VM.create({ common, blockchain }) - await vm.stateManager.generateCanonicalGenesis(parseGethGenesisState(genesisJSON)) + await vm.stateManager.generateCanonicalGenesis!(parseGethGenesisState(genesisJSON)) const vmCopy = await vm.shallowCopy() const gethBlockBufferArray = decode(hexToBytes(gethWithdrawals8BlockRlp)) diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index be4387d97a..e9e5b7821c 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -65,7 +65,8 @@ const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3 describe('VM initialized with custom state', () => { it('should transfer eth from already existent account', async () => { const blockchain = await createBlockchain({ common, genesisState }) - const vm = await VM.create({ blockchain, common, genesisState }) + const vm = await VM.create({ blockchain, common }) + await vm.stateManager.generateCanonicalGenesis!(genesisState) const to = '0x00000000000000000000000000000000000000ff' const tx = createTxFromTxData( @@ -93,7 +94,8 @@ describe('VM initialized with custom state', () => { it('should retrieve value from storage', async () => { const blockchain = await createBlockchain({ common, genesisState }) common.setHardfork(Hardfork.London) - const vm = await VM.create({ blockchain, common, genesisState }) + const vm = await VM.create({ blockchain, common }) + await vm.stateManager.generateCanonicalGenesis!(genesisState) const sigHash = new Interface(['function retrieve()']).getSighash( 'retrieve', ) as PrefixedHexString @@ -114,10 +116,10 @@ describe('VM initialized with custom state', () => { const customChains = [testnetMerge] as ChainConfig[] const common = new Common({ chain: 'testnetMerge', hardfork: Hardfork.Istanbul, customChains }) - let vm = await VM.create({ common, setHardfork: true, genesisState: {} }) + let vm = await VM.create({ common, setHardfork: true }) assert.equal((vm as any)._setHardfork, true, 'should set setHardfork option') - vm = await VM.create({ common, setHardfork: 5001, genesisState: {} }) + vm = await VM.create({ common, setHardfork: 5001 }) assert.equal((vm as any)._setHardfork, BigInt(5001), 'should set setHardfork option') }) }) diff --git a/packages/vm/test/util.ts b/packages/vm/test/util.ts index 98d877ec09..c2ace8fa1e 100644 --- a/packages/vm/test/util.ts +++ b/packages/vm/test/util.ts @@ -26,7 +26,7 @@ import { import { keccak256 } from 'ethereum-cryptography/keccak' import type { BlockOptions } from '@ethereumjs/block' -import type { EVMStateManagerInterface } from '@ethereumjs/common' +import type { StateManagerInterface } from '@ethereumjs/common' import type { AccessListEIP2930Transaction, BlobEIP4844Transaction, @@ -363,7 +363,7 @@ export function makeBlockFromEnv(env: any, opts?: BlockOptions): Block { * @param state - the state DB/trie * @param testData - JSON from tests repo */ -export async function setupPreConditions(state: EVMStateManagerInterface, testData: any) { +export async function setupPreConditions(state: StateManagerInterface, testData: any) { await state.checkpoint() for (const addressStr of Object.keys(testData.pre)) { const { nonce, balance, code, storage } = testData.pre[addressStr] From 8441f9c5341bba19a9ee5850d7253ba009d6ecb7 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Jul 2024 18:51:27 -0400 Subject: [PATCH 25/58] util: refactor bigint to address helper into Address.fromBigInt method (#3544) * util: refactor bigint to address helper into fromBigInt constructor * evm: refactor using fromBigInt method * refactor: address constructor usage * evm: wrapper helper for evm stack bigint addresses * Update packages/evm/src/opcodes/util.ts Co-authored-by: Jochem Brouwer * util: remove redundant conversion * address: add test vectors for big int constructor --------- Co-authored-by: Jochem Brouwer --- packages/block/examples/4844.ts | 4 +- packages/block/src/header.ts | 8 +- packages/block/test/clique.spec.ts | 10 +- packages/block/test/header.spec.ts | 10 +- packages/block/test/mergeBlock.spec.ts | 4 +- packages/blockchain/test/clique.spec.ts | 12 +- packages/client/bin/cli.ts | 15 +- .../devnets/4844-interop/tools/txGenerator.ts | 14 +- packages/client/src/miner/pendingBlock.ts | 4 +- packages/client/src/rpc/modules/debug.ts | 15 +- packages/client/src/rpc/modules/eth.ts | 23 +-- packages/client/test/integration/pow.spec.ts | 6 +- packages/client/test/miner/miner.spec.ts | 2 +- .../test/net/protocol/ethprotocol.spec.ts | 14 +- .../client/test/rpc/debug/getRawBlock.spec.ts | 4 +- .../test/rpc/debug/getRawHeader.spec.ts | 4 +- .../engine/getPayloadBodiesByHashV1.spec.ts | 12 +- .../engine/getPayloadBodiesByRangeV1.spec.ts | 6 +- .../test/rpc/engine/getPayloadV3.spec.ts | 7 +- .../test/rpc/engine/newPayloadV1.spec.ts | 14 +- .../test/rpc/engine/newPayloadV2.spec.ts | 12 +- .../client/test/rpc/eth/blobBaseFee.spec.ts | 7 +- packages/client/test/rpc/eth/call.spec.ts | 8 +- .../client/test/rpc/eth/estimateGas.spec.ts | 6 +- .../client/test/rpc/eth/getBalance.spec.ts | 4 +- .../test/rpc/eth/getBlockByNumber.spec.ts | 4 +- .../getBlockTransactionCountByNumber.spec.ts | 6 +- packages/client/test/rpc/eth/getCode.spec.ts | 8 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 9 +- packages/client/test/rpc/eth/getLogs.spec.ts | 6 +- packages/client/test/rpc/eth/getProof.spec.ts | 4 +- .../client/test/rpc/eth/getStorageAt.spec.ts | 4 +- .../test/rpc/eth/getTransactionCount.spec.ts | 12 +- packages/client/test/rpc/helpers.ts | 3 +- packages/client/test/sim/simutils.ts | 6 +- packages/client/test/sim/snapsync.spec.ts | 4 +- packages/client/test/sim/txGenerator.ts | 6 +- packages/evm/src/evm.ts | 21 +-- packages/evm/src/message.ts | 6 +- packages/evm/src/opcodes/functions.ts | 30 ++-- packages/evm/src/opcodes/gas.ts | 69 ++++---- packages/evm/src/opcodes/util.ts | 21 ++- packages/evm/test/blobVersionedHashes.spec.ts | 11 +- packages/evm/test/customPrecompiles.spec.ts | 6 +- packages/evm/test/eips/eip-3860.spec.ts | 21 ++- .../evm/test/precompiles/09-blake2f.spec.ts | 4 +- .../evm/test/precompiles/eip-2537-bls.spec.ts | 4 +- .../evm/test/precompiles/hardfork.spec.ts | 8 +- packages/evm/test/runCall.spec.ts | 15 +- packages/evm/test/runCode.spec.ts | 4 +- packages/evm/test/transientStorage.spec.ts | 22 +-- .../statemanager/examples/rpcStateManager.ts | 4 +- packages/statemanager/examples/simple.ts | 4 +- packages/statemanager/src/stateManager.ts | 14 +- .../test/proofStateManager.spec.ts | 25 +-- .../statemanager/test/rpcStateManager.spec.ts | 15 +- .../test/stateManager.code.spec.ts | 12 +- .../statemanager/test/stateManager.spec.ts | 26 +-- .../test/stateManager.storage.spec.ts | 9 +- .../test/statelessVerkleStateManager.spec.ts | 7 +- packages/tx/examples/custom-chain-tx.ts | 4 +- packages/tx/examples/l2tx.ts | 4 +- packages/tx/test/eip3860.spec.ts | 4 +- packages/tx/test/eip4844.spec.ts | 16 +- packages/tx/test/eip7702.spec.ts | 8 +- packages/util/examples/address.ts | 4 +- packages/util/examples/browser.html | 6 +- packages/util/src/address.ts | 159 ++++++++++-------- packages/util/test/address.spec.ts | 65 ++++--- packages/util/test/bytes.spec.ts | 8 +- packages/util/test/verkle.spec.ts | 12 +- packages/vm/examples/browser.html | 6 +- packages/vm/examples/buildBlock.ts | 4 +- packages/vm/examples/helpers/account-utils.ts | 5 +- packages/vm/examples/run-solidity-contract.ts | 6 +- packages/vm/examples/runTx.ts | 4 +- packages/vm/examples/vmWithGenesisState.ts | 4 +- packages/vm/src/buildBlock.ts | 3 +- packages/vm/src/requests.ts | 10 +- packages/vm/src/runBlock.ts | 3 +- packages/vm/src/runTx.ts | 3 +- .../test/api/EIPs/eip-1559-FeeMarket.spec.ts | 7 +- .../api/EIPs/eip-2565-modexp-gas-cost.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-2929.spec.ts | 4 +- .../api/EIPs/eip-2930-accesslists.spec.ts | 10 +- .../eip-2935-historical-block-hashes.spec.ts | 6 +- packages/vm/test/api/EIPs/eip-3607.spec.ts | 4 +- .../test/api/EIPs/eip-4788-beaconroot.spec.ts | 6 +- .../vm/test/api/EIPs/eip-4844-blobs.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-6110.spec.ts | 17 +- .../eip-6780-selfdestruct-same-tx.spec.ts | 16 +- packages/vm/test/api/EIPs/eip-7002.spec.ts | 7 +- packages/vm/test/api/EIPs/eip-7702.spec.ts | 9 +- packages/vm/test/api/buildBlock.spec.ts | 29 ++-- packages/vm/test/api/copy.spec.ts | 4 +- packages/vm/test/api/customChain.spec.ts | 13 +- packages/vm/test/api/events.spec.ts | 8 +- packages/vm/test/api/index.spec.ts | 6 +- packages/vm/test/api/runBlock.spec.ts | 16 +- packages/vm/test/api/runTx.spec.ts | 31 ++-- .../tester/runners/GeneralStateTestsRunner.ts | 10 +- 101 files changed, 707 insertions(+), 497 deletions(-) diff --git a/packages/block/examples/4844.ts b/packages/block/examples/4844.ts index 5331a68e20..a88f701620 100644 --- a/packages/block/examples/4844.ts +++ b/packages/block/examples/4844.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { create4844BlobTx } from '@ethereumjs/tx' -import { Address } from '@ethereumjs/util' +import { createAddressFromPrivateKey } from '@ethereumjs/util' import { randomBytes } from 'crypto' import { loadKZG } from 'kzg-wasm' @@ -16,7 +16,7 @@ const main = async () => { }, }) const blobTx = create4844BlobTx( - { blobsData: ['myFirstBlob'], to: Address.fromPrivateKey(randomBytes(32)) }, + { blobsData: ['myFirstBlob'], to: createAddressFromPrivateKey(randomBytes(32)) }, { common }, ) diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index f8f417362d..0c220f07d4 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -17,6 +17,8 @@ import { bytesToHex, bytesToUtf8, concatBytes, + createAddressFromPublicKey, + createZeroAddress, ecrecover, ecsign, equalsBytes, @@ -177,7 +179,7 @@ export class BlockHeader { const defaults = { parentHash: zeros(32), uncleHash: KECCAK256_RLP_ARRAY, - coinbase: Address.zero(), + coinbase: createZeroAddress(), stateRoot: zeros(32), transactionsTrie: KECCAK256_RLP, receiptTrie: KECCAK256_RLP, @@ -932,13 +934,13 @@ export class BlockHeader { const extraSeal = this.cliqueExtraSeal() // Reasonable default for default blocks if (extraSeal.length === 0 || equalsBytes(extraSeal, new Uint8Array(65))) { - return Address.zero() + return createZeroAddress() } const r = extraSeal.subarray(0, 32) const s = extraSeal.subarray(32, 64) const v = bytesToBigInt(extraSeal.subarray(64, 65)) + BIGINT_27 const pubKey = ecrecover(this.cliqueSigHash(), v, r, s) - return Address.fromPublicKey(pubKey) + return createAddressFromPublicKey(pubKey) } /** diff --git a/packages/block/test/clique.spec.ts b/packages/block/test/clique.spec.ts index 2c000d2bb3..a9ee44e710 100644 --- a/packages/block/test/clique.spec.ts +++ b/packages/block/test/clique.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, hexToBytes } from '@ethereumjs/util' +import { Address, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { BlockHeader } from '../src/header.js' @@ -68,7 +68,11 @@ describe('[Header]: Clique PoA Functionality', () => { ) const msg = 'cliqueEpochTransitionSigners() -> should return the correct epoch transition signer list on epoch block' - assert.deepEqual(header.cliqueEpochTransitionSigners(), [Address.zero(), Address.zero()], msg) + assert.deepEqual( + header.cliqueEpochTransitionSigners(), + [createZeroAddress(), createZeroAddress()], + msg, + ) }) type Signer = { @@ -99,7 +103,7 @@ describe('[Header]: Clique PoA Functionality', () => { header = BlockHeader.fromHeaderData({ extraData: new Uint8Array(97) }, { common }) assert.ok( - header.cliqueSigner().equals(Address.zero()), + header.cliqueSigner().equals(createZeroAddress()), 'should return zero address on default block', ) }) diff --git a/packages/block/test/header.spec.ts b/packages/block/test/header.spec.ts index 92d4d11c75..29f1beeddb 100644 --- a/packages/block/test/header.spec.ts +++ b/packages/block/test/header.spec.ts @@ -1,11 +1,11 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { - Address, KECCAK256_RLP, KECCAK256_RLP_ARRAY, bytesToHex, concatBytes, + createZeroAddress, equalsBytes, hexToBytes, zeros, @@ -28,7 +28,7 @@ describe('[Block]: Header functions', () => { function compareDefaultHeader(header: BlockHeader) { assert.ok(equalsBytes(header.parentHash, zeros(32))) assert.ok(equalsBytes(header.uncleHash, KECCAK256_RLP_ARRAY)) - assert.ok(header.coinbase.equals(Address.zero())) + assert.ok(header.coinbase.equals(createZeroAddress())) assert.ok(equalsBytes(header.stateRoot, zeros(32))) assert.ok(equalsBytes(header.transactionsTrie, KECCAK256_RLP)) assert.ok(equalsBytes(header.receiptTrie, KECCAK256_RLP)) @@ -380,7 +380,7 @@ describe('[Block]: Header functions', () => { testCase = 'should throw on non-zero beneficiary (coinbase) for epoch transition block' headerData.number = common.consensusConfig().epoch - headerData.coinbase = Address.fromString('0x091dcd914fCEB1d47423e532955d1E62d1b2dAEf') + headerData.coinbase = createAddressFromString('0x091dcd914fCEB1d47423e532955d1E62d1b2dAEf') header = BlockHeader.fromHeaderData(headerData, { common }) try { await header.validate(blockchain) @@ -393,7 +393,7 @@ describe('[Block]: Header functions', () => { } } headerData.number = 1 - headerData.coinbase = Address.zero() + headerData.coinbase = createZeroAddress() testCase = 'should throw on non-zero mixHash' headerData.mixHash = new Uint8Array(32).fill(1) @@ -455,7 +455,7 @@ describe('[Block]: Header functions', () => { */ it('should test validateGasLimit()', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) - const bcBlockGasLimitTestData = testData.tests.BlockGasLimit2p63m1 + const bcBlockGasLimitTestData = testData.default.tests.BlockGasLimit2p63m1 for (const key of Object.keys(bcBlockGasLimitTestData)) { const genesisRlp = hexToBytes( diff --git a/packages/block/test/mergeBlock.spec.ts b/packages/block/test/mergeBlock.spec.ts index 3a0ac43597..803dc9fc61 100644 --- a/packages/block/test/mergeBlock.spec.ts +++ b/packages/block/test/mergeBlock.spec.ts @@ -1,8 +1,8 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { - Address, KECCAK256_RLP, KECCAK256_RLP_ARRAY, + createZeroAddress, equalsBytes, hexToBytes, zeros, @@ -21,7 +21,7 @@ const common = new Common({ function validateMergeHeader(header: BlockHeader) { assert.ok(equalsBytes(header.parentHash, zeros(32)), 'parentHash') assert.ok(equalsBytes(header.uncleHash, KECCAK256_RLP_ARRAY), 'uncleHash') - assert.ok(header.coinbase.equals(Address.zero()), 'coinbase') + assert.ok(header.coinbase.equals(createZeroAddress()), 'coinbase') assert.ok(equalsBytes(header.stateRoot, zeros(32)), 'stateRoot') assert.ok(equalsBytes(header.transactionsTrie, KECCAK256_RLP), 'transactionsTrie') assert.ok(equalsBytes(header.receiptTrie, KECCAK256_RLP), 'receiptTrie') diff --git a/packages/blockchain/test/clique.spec.ts b/packages/blockchain/test/clique.spec.ts index 544f6bf093..1159b17889 100644 --- a/packages/blockchain/test/clique.spec.ts +++ b/packages/blockchain/test/clique.spec.ts @@ -7,7 +7,13 @@ import { Hardfork, createCustomCommon, } from '@ethereumjs/common' -import { Address, concatBytes, hexToBytes } from '@ethereumjs/util' +import { + Address, + concatBytes, + createAddressFromString, + createZeroAddress, + hexToBytes, +} from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { CLIQUE_NONCE_AUTH, CLIQUE_NONCE_DROP, CliqueConsensus } from '../src/consensus/clique.js' @@ -114,7 +120,7 @@ function getBlock( common = common ?? COMMON const number = lastBlock.header.number + BigInt(1) - let coinbase = Address.zero() + let coinbase = createZeroAddress() let nonce = CLIQUE_NONCE_DROP let extraData = EXTRA_DATA if (beneficiary) { @@ -214,7 +220,7 @@ describe('Clique: Initialization', () => { // _validateConsensus needs to be true to trigger this test condition ;(blockchain as any)._validateConsensus = true const number = (COMMON.consensusConfig() as CliqueConfig).epoch - const unauthorizedSigner = Address.fromString('0x00a839de7922491683f547a67795204763ff8237') + const unauthorizedSigner = createAddressFromString('0x00a839de7922491683f547a67795204763ff8237') const extraData = concatBytes( new Uint8Array(32), A.address.toBytes(), diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 7488a7d1d6..29b70eecc3 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -12,11 +12,12 @@ import { } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { - Address, BIGINT_2, bytesToHex, calculateSigRecovery, concatBytes, + createAddressFromPrivateKey, + createAddressFromString, ecrecover, ecsign, hexToBytes, @@ -65,7 +66,7 @@ import type { RPCArgs } from './startRpc.js' import type { Block, BlockBytes } from '@ethereumjs/block' import type { ConsensusDict } from '@ethereumjs/blockchain' import type { CustomCrypto } from '@ethereumjs/common' -import type { GenesisState, PrefixedHexString } from '@ethereumjs/util' +import type { Address, GenesisState, PrefixedHexString } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' import type { Server as RPCServer } from 'jayson/promise/index.js' @@ -371,7 +372,7 @@ const args: ClientOpts = yargs describe: 'Address for mining rewards (etherbase). If not provided, defaults to the primary account', string: true, - coerce: (coinbase) => Address.fromString(coinbase), + coerce: (coinbase) => createAddressFromString(coinbase), }) .option('saveReceipts', { describe: @@ -835,13 +836,13 @@ async function inputAccounts() { const isFile = existsSync(path.resolve(addresses[0])) if (!isFile) { for (const addressString of addresses) { - const address = Address.fromString(addressString) + const address = createAddressFromString(addressString) const inputKey = (await question( `Please enter the 0x-prefixed private key to unlock ${address}:\n`, )) as PrefixedHexString ;(rl as any).history = (rl as any).history.slice(1) const privKey = hexToBytes(inputKey) - const derivedAddress = Address.fromPrivateKey(privKey) + const derivedAddress = createAddressFromPrivateKey(privKey) if (address.equals(derivedAddress)) { accounts.push([address, privKey]) } else { @@ -854,7 +855,7 @@ async function inputAccounts() { } else { const acc = readFileSync(path.resolve(args.unlock!), 'utf-8').replace(/(\r\n|\n|\r)/gm, '') const privKey = hexToBytes(`0x${acc}`) // See docs: acc has to be non-zero prefixed in the file - const derivedAddress = Address.fromPrivateKey(privKey) + const derivedAddress = createAddressFromPrivateKey(privKey) accounts.push([derivedAddress, privKey]) } } catch (e: any) { @@ -870,7 +871,7 @@ async function inputAccounts() { */ function generateAccount(): Account { const privKey = randomBytes(32) - const address = Address.fromPrivateKey(privKey) + const address = createAddressFromPrivateKey(privKey) console.log('='.repeat(50)) console.log('Account generated for mining blocks:') console.log(`Address: ${address}`) diff --git a/packages/client/devnets/4844-interop/tools/txGenerator.ts b/packages/client/devnets/4844-interop/tools/txGenerator.ts index f6d6aea8a1..4d799e65c5 100644 --- a/packages/client/devnets/4844-interop/tools/txGenerator.ts +++ b/packages/client/devnets/4844-interop/tools/txGenerator.ts @@ -1,13 +1,13 @@ // Adapted from - https://github.com/Inphi/eip4844-interop/blob/master/blob_tx_generator/blob.js -import { Common, Hardfork } from '@ethereumjs/common' -import { BlobEIP4844Transaction, TransactionType, TxData } from '@ethereumjs/tx' +import { createCommonFromGethGenesis, Hardfork } from '@ethereumjs/common' +import { createTxFromTxData, TransactionType, TxData } from '@ethereumjs/tx' import { - Address, blobsToCommitments, commitmentsToVersionedHashes, getBlobs, bytesToHex, hexToBytes, + createAddressFromPrivateKey, } from '@ethereumjs/util' import { randomBytes } from '@ethereumjs/util' @@ -18,8 +18,8 @@ import { loadKZG } from 'kzg-wasm' const clientPort = parseInt(process.argv[2]) // EL client port number const input = process.argv[3] // text to generate blob from const genesisJson = require(process.argv[4]) // Genesis parameters -const pkey = hexToBytes('0x' + process.argv[5]) // private key of tx sender as unprefixed hex string (unprefixed in args) -const sender = Address.fromPrivateKey(pkey) +const pkey = hexToBytes(`0x${process.argv[5]}`) // private key of tx sender as unprefixed hex string (unprefixed in args) +const sender = createAddressFromPrivateKey(pkey) async function getNonce(client: Client, account: string) { const nonce = await client.request('eth_getTransactionCount', [account, 'latest'], 2.0) @@ -41,7 +41,7 @@ async function run(data: any) { const commitments = blobsToCommitments(kzg, blobs) const hashes = commitmentsToVersionedHashes(commitments) - const account = Address.fromPrivateKey(randomBytes(32)) + const account = createAddressFromPrivateKey(randomBytes(32)) const txData: TxData[TransactionType.BlobEIP4844] = { to: account.toString(), data: '0x', @@ -62,7 +62,7 @@ async function run(data: any) { txData.gasLimit = BigInt(28000000) const nonce = await getNonce(client, sender.toString()) txData.nonce = BigInt(nonce) - const blobTx = BlobEIP4844Transaction.fromTxData(txData, { common }).sign(pkey) + const blobTx = createTxFromTxData(txData, { common }).sign(pkey) const serializedWrapper = blobTx.serializeNetworkWrapper() diff --git a/packages/client/src/miner/pendingBlock.ts b/packages/client/src/miner/pendingBlock.ts index 0d08db6e76..dfb58fad31 100644 --- a/packages/client/src/miner/pendingBlock.ts +++ b/packages/client/src/miner/pendingBlock.ts @@ -1,13 +1,13 @@ import { Hardfork } from '@ethereumjs/common' import { BlobEIP4844Transaction } from '@ethereumjs/tx' import { - Address, BIGINT_1, BIGINT_2, TypeOutput, bigIntToUnpaddedBytes, bytesToHex, concatBytes, + createZeroAddress, equalsBytes, toBytes, toType, @@ -140,7 +140,7 @@ export class PendingBlock { const validatorIndex = bigIntToUnpaddedBytes( toType(withdrawal.validatorIndex ?? 0, TypeOutput.BigInt), ) - const address = toType(withdrawal.address ?? Address.zero(), TypeOutput.Uint8Array) + const address = toType(withdrawal.address ?? createZeroAddress(), TypeOutput.Uint8Array) const amount = bigIntToUnpaddedBytes(toType(withdrawal.amount ?? 0, TypeOutput.BigInt)) withdrawalsBufTemp.push(concatBytes(indexBuf, validatorIndex, address, amount)) } diff --git a/packages/client/src/rpc/modules/debug.ts b/packages/client/src/rpc/modules/debug.ts index 758525c1cb..f118b561a9 100644 --- a/packages/client/src/rpc/modules/debug.ts +++ b/packages/client/src/rpc/modules/debug.ts @@ -1,4 +1,11 @@ -import { Address, TypeOutput, bigIntToHex, bytesToHex, hexToBytes, toType } from '@ethereumjs/util' +import { + TypeOutput, + bigIntToHex, + bytesToHex, + createAddressFromString, + hexToBytes, + toType, +} from '@ethereumjs/util' import { type VM, encodeReceipt, runTx } from '@ethereumjs/vm' import { INTERNAL_ERROR, INVALID_PARAMS } from '../error-code.js' @@ -304,8 +311,8 @@ export class Debug { next?.() }) const runCallOpts = { - caller: from !== undefined ? Address.fromString(from) : undefined, - to: to !== undefined ? Address.fromString(to) : undefined, + caller: from !== undefined ? createAddressFromString(from) : undefined, + to: to !== undefined ? createAddressFromString(to) : undefined, gasLimit: toType(gasLimit, TypeOutput.BigInt), gasPrice: toType(gasPrice, TypeOutput.BigInt), value: toType(value, TypeOutput.BigInt), @@ -373,7 +380,7 @@ export class Debug { // await here so that any error can be handled in the catch below for proper response return vmCopy.stateManager.dumpStorageRange!( // Validator already verified that `account` and `startKey` are properly formatted. - Address.fromString(account), + createAddressFromString(account), BigInt(startKey), limit, ) diff --git a/packages/client/src/rpc/modules/eth.ts b/packages/client/src/rpc/modules/eth.ts index 2d1f5b725c..e874293daf 100644 --- a/packages/client/src/rpc/modules/eth.ts +++ b/packages/client/src/rpc/modules/eth.ts @@ -7,7 +7,6 @@ import { createTxFromTxData, } from '@ethereumjs/tx' import { - Address, BIGINT_0, BIGINT_1, BIGINT_100, @@ -16,6 +15,8 @@ import { bigIntMax, bigIntToHex, bytesToHex, + createAddressFromString, + createZeroAddress, equalsBytes, hexToBytes, intToHex, @@ -51,7 +52,7 @@ import type { LegacyTransaction, TypedTransaction, } from '@ethereumjs/tx' -import type { PrefixedHexString } from '@ethereumjs/util' +import type { Address, PrefixedHexString } from '@ethereumjs/util' const EMPTY_SLOT = `0x${'00'.repeat(32)}` @@ -517,8 +518,8 @@ export class Eth { const data = transaction.data ?? transaction.input const runCallOpts = { - caller: from !== undefined ? Address.fromString(from) : undefined, - to: to !== undefined ? Address.fromString(to) : undefined, + caller: from !== undefined ? createAddressFromString(from) : undefined, + to: to !== undefined ? createAddressFromString(to) : undefined, gasLimit: toType(gasLimit, TypeOutput.BigInt), gasPrice: toType(gasPrice, TypeOutput.BigInt), value: toType(value, TypeOutput.BigInt), @@ -608,7 +609,9 @@ export class Eth { // set from address const from = - transaction.from !== undefined ? Address.fromString(transaction.from) : Address.zero() + transaction.from !== undefined + ? createAddressFromString(transaction.from) + : createZeroAddress() tx.getSenderAddress = () => { return from } @@ -631,7 +634,7 @@ export class Eth { */ async getBalance(params: [string, string]) { const [addressHex, blockOpt] = params - const address = Address.fromString(addressHex) + const address = createAddressFromString(addressHex) const block = await getBlockByOption(blockOpt, this._chain) if (this._vm === undefined) { @@ -737,7 +740,7 @@ export class Eth { const vm = await this._vm.shallowCopy() await vm.stateManager.setStateRoot(block.header.stateRoot) - const address = Address.fromString(addressHex) + const address = createAddressFromString(addressHex) const code = await vm.stateManager.getCode(address) return bytesToHex(code) } @@ -778,7 +781,7 @@ export class Eth { const block = await getBlockByOption(blockOpt, this._chain) await vm.stateManager.setStateRoot(block.header.stateRoot) - const address = Address.fromString(addressHex) + const address = createAddressFromString(addressHex) const account = await vm.stateManager.getAccount(address) if (account === undefined) { return EMPTY_SLOT @@ -875,7 +878,7 @@ export class Eth { const vm = await this._vm.shallowCopy() await vm.stateManager.setStateRoot(block.header.stateRoot) - const address = Address.fromString(addressHex) + const address = createAddressFromString(addressHex) const account = await vm.stateManager.getAccount(address) if (account === undefined) { return '0x0' @@ -1245,7 +1248,7 @@ export class Eth { } await vm.stateManager.setStateRoot(block.header.stateRoot) - const address = Address.fromString(addressHex) + const address = createAddressFromString(addressHex) const slots = slotsHex.map((slotHex) => setLengthLeft(hexToBytes(slotHex), 32)) const proof = await vm.stateManager.getProof!(address, slots) for (const p of proof.storageProof) { diff --git a/packages/client/test/integration/pow.spec.ts b/packages/client/test/integration/pow.spec.ts index 51f0b3d4ba..c2af982121 100644 --- a/packages/client/test/integration/pow.spec.ts +++ b/packages/client/test/integration/pow.spec.ts @@ -1,13 +1,15 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' -import { Address, hexToBytes, parseGethGenesisState } from '@ethereumjs/util' +import { createAddressFromPrivateKey, hexToBytes, parseGethGenesisState } from '@ethereumjs/util' import { rmSync } from 'fs' import { assert, describe, it } from 'vitest' import { Config } from '../../src/index.js' import { createInlineClient } from '../sim/simutils.js' +import type { Address } from '@ethereumjs/util' + const pk = hexToBytes('0x95a602ff1ae30a2243f400dcf002561b9743b2ae9827b1008e3714a5cc1c0cfe') -const minerAddress = Address.fromPrivateKey(pk) +const minerAddress = createAddressFromPrivateKey(pk) async function setupPowDevnet(prefundAddress: Address, cleanStart: boolean) { if (cleanStart) { diff --git a/packages/client/test/miner/miner.spec.ts b/packages/client/test/miner/miner.spec.ts index 0fa1c2e97b..ec82090d15 100644 --- a/packages/client/test/miner/miner.spec.ts +++ b/packages/client/test/miner/miner.spec.ts @@ -570,7 +570,7 @@ describe.skip('assembleBlocks() -> should stop assembling when a new block is re for (let i = 0; i < 1000; i++) { // In order not to pollute TxPool with too many txs from the same address // (or txs which are already known), keep generating a new address for each tx - const address = Address.fromPrivateKey(privateKey) + const address = createAddressFromPrivateKey(privateKey) await setBalance(vm, address, BigInt('200000000000001')) const tx = createTx({ address, privateKey }) await txPool.add(tx) diff --git a/packages/client/test/net/protocol/ethprotocol.spec.ts b/packages/client/test/net/protocol/ethprotocol.spec.ts index fb6ef7ce84..20fdc24c23 100644 --- a/packages/client/test/net/protocol/ethprotocol.spec.ts +++ b/packages/client/test/net/protocol/ethprotocol.spec.ts @@ -1,7 +1,13 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' import { TransactionType, create1559FeeMarketTx, createTxFromTxData } from '@ethereumjs/tx' -import { Address, bigIntToBytes, bytesToBigInt, hexToBytes, randomBytes } from '@ethereumjs/util' +import { + bigIntToBytes, + bytesToBigInt, + createZeroAddress, + hexToBytes, + randomBytes, +} from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -224,7 +230,11 @@ describe('[EthProtocol]', () => { const eip2929Tx = createTxFromTxData({ type: 1 }, { common: config.chainCommon }) const eip1559Tx = createTxFromTxData({ type: 2 }, { common: config.chainCommon }) const blobTx = createTxFromTxData( - { type: 3, to: Address.zero(), blobVersionedHashes: [hexToBytes(`0x01${'00'.repeat(31)}`)] }, + { + type: 3, + to: createZeroAddress(), + blobVersionedHashes: [hexToBytes(`0x01${'00'.repeat(31)}`)], + }, { common: config.chainCommon }, ) const res = p.encode(p.messages.filter((message) => message.name === 'Transactions')[0], [ diff --git a/packages/client/test/rpc/debug/getRawBlock.spec.ts b/packages/client/test/rpc/debug/getRawBlock.spec.ts index 4e560c185b..8c32a58cc1 100644 --- a/packages/client/test/rpc/debug/getRawBlock.spec.ts +++ b/packages/client/test/rpc/debug/getRawBlock.spec.ts @@ -1,7 +1,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -16,7 +16,7 @@ common.setHardfork('cancun') const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( - { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, + { nonce: 2, blobsData: ['0x1234'], to: createZeroAddress() }, { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') diff --git a/packages/client/test/rpc/debug/getRawHeader.spec.ts b/packages/client/test/rpc/debug/getRawHeader.spec.ts index bd86b30f3c..19752304ac 100644 --- a/packages/client/test/rpc/debug/getRawHeader.spec.ts +++ b/packages/client/test/rpc/debug/getRawHeader.spec.ts @@ -1,7 +1,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -16,7 +16,7 @@ common.setHardfork('cancun') const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( - { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, + { nonce: 2, blobsData: ['0x1234'], to: createZeroAddress() }, { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts index c43e167931..eb32e274ac 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByHashV1.spec.ts @@ -2,7 +2,13 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' import { createTxFromTxData } from '@ethereumjs/tx' -import { Account, Address, bytesToHex, hexToBytes, randomBytes } from '@ethereumjs/util' +import { + Account, + bytesToHex, + createAddressFromPrivateKey, + hexToBytes, + randomBytes, +} from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { TOO_LARGE_REQUEST } from '../../../src/rpc/error-code.js' @@ -39,7 +45,7 @@ describe(method, () => { const rpc = getRpcClient(server) common.setHardfork(Hardfork.Cancun) const pkey = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const address = Address.fromPrivateKey(pkey) + const address = createAddressFromPrivateKey(pkey) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) @@ -125,7 +131,7 @@ describe(method, () => { const rpc = getRpcClient(server) common.setHardfork(Hardfork.London) const pkey = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const address = Address.fromPrivateKey(pkey) + const address = createAddressFromPrivateKey(pkey) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) diff --git a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts index 45c4226068..1d5890fefb 100644 --- a/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadBodiesByRangeV1.spec.ts @@ -2,7 +2,7 @@ import { BlockHeader, createBlockFromBlockData } from '@ethereumjs/block' import { Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' import { createTxFromTxData } from '@ethereumjs/tx' -import { Account, Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { Account, bytesToHex, createAddressFromPrivateKey, hexToBytes } from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' import { INVALID_PARAMS, TOO_LARGE_REQUEST } from '../../../src/rpc/error-code.js' @@ -41,7 +41,7 @@ describe(method, () => { const rpc = getRpcClient(server) common.setHardfork(Hardfork.Cancun) const pkey = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const address = Address.fromPrivateKey(pkey) + const address = createAddressFromPrivateKey(pkey) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) @@ -123,7 +123,7 @@ describe(method, () => { const rpc = getRpcClient(server) common.setHardfork(Hardfork.London) const pkey = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const address = Address.fromPrivateKey(pkey) + const address = createAddressFromPrivateKey(pkey) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) diff --git a/packages/client/test/rpc/engine/getPayloadV3.spec.ts b/packages/client/test/rpc/engine/getPayloadV3.spec.ts index def3e58408..35aa080b5e 100644 --- a/packages/client/test/rpc/engine/getPayloadV3.spec.ts +++ b/packages/client/test/rpc/engine/getPayloadV3.spec.ts @@ -3,11 +3,12 @@ import { DefaultStateManager } from '@ethereumjs/statemanager' import { createTxFromTxData } from '@ethereumjs/tx' import { Account, - Address, blobsToCommitments, blobsToProofs, bytesToHex, commitmentsToVersionedHashes, + createAddressFromPrivateKey, + createZeroAddress, getBlobs, hexToBytes, } from '@ethereumjs/util' @@ -78,7 +79,7 @@ describe(method, () => { const rpc = getRpcClient(server) common.setHardfork(Hardfork.Cancun) const pkey = hexToBytes('0x9c9996335451aab4fc4eac58e31a8c300e095cdbcee532d53d09280e83360355') - const address = Address.fromPrivateKey(pkey) + const address = createAddressFromPrivateKey(pkey) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) @@ -104,7 +105,7 @@ describe(method, () => { maxFeePerGas: 10000000000n, maxPriorityFeePerGas: 100000000n, gasLimit: 30000000n, - to: Address.zero(), + to: createZeroAddress(), }, { common }, ).sign(pkey) diff --git a/packages/client/test/rpc/engine/newPayloadV1.spec.ts b/packages/client/test/rpc/engine/newPayloadV1.spec.ts index df1155e379..6a9402859e 100644 --- a/packages/client/test/rpc/engine/newPayloadV1.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV1.spec.ts @@ -1,6 +1,12 @@ import { BlockHeader } from '@ethereumjs/block' import { create1559FeeMarketTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes, zeros } from '@ethereumjs/util' +import { + bytesToHex, + createAddressFromPrivateKey, + createAddressFromString, + hexToBytes, + zeros, +} from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -160,7 +166,7 @@ describe(method, () => { gasLimit: 21_000, maxFeePerGas: 10, value: 1, - to: Address.fromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), + to: createAddressFromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), }, { common }, ) @@ -182,7 +188,7 @@ describe(method, () => { const accountPk = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) - const accountAddress = Address.fromPrivateKey(accountPk) + const accountAddress = createAddressFromPrivateKey(accountPk) const newGenesisJSON = { ...genesisJSON, alloc: { @@ -222,7 +228,7 @@ describe(method, () => { const accountPk = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) - const accountAddress = Address.fromPrivateKey(accountPk) + const accountAddress = createAddressFromPrivateKey(accountPk) const newGenesisJSON = { ...genesisJSON, alloc: { diff --git a/packages/client/test/rpc/engine/newPayloadV2.spec.ts b/packages/client/test/rpc/engine/newPayloadV2.spec.ts index f11aaad90f..98ea103f73 100644 --- a/packages/client/test/rpc/engine/newPayloadV2.spec.ts +++ b/packages/client/test/rpc/engine/newPayloadV2.spec.ts @@ -1,6 +1,12 @@ import { BlockHeader } from '@ethereumjs/block' import { create1559FeeMarketTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes, zeros } from '@ethereumjs/util' +import { + bytesToHex, + createAddressFromPrivateKey, + createAddressFromString, + hexToBytes, + zeros, +} from '@ethereumjs/util' import { assert, describe, it, vi } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -158,7 +164,7 @@ describe(`${method}: call with executionPayloadV1`, () => { gasLimit: 21_000, maxFeePerGas: 10, value: 1, - to: Address.fromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), + to: createAddressFromString('0x61FfE691821291D02E9Ba5D33098ADcee71a3a17'), }, { common }, ) @@ -179,7 +185,7 @@ describe(`${method}: call with executionPayloadV1`, () => { const accountPk = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) - const accountAddress = Address.fromPrivateKey(accountPk) + const accountAddress = createAddressFromPrivateKey(accountPk) const newGenesisJSON = { ...genesisJSON, alloc: { diff --git a/packages/client/test/rpc/eth/blobBaseFee.spec.ts b/packages/client/test/rpc/eth/blobBaseFee.spec.ts index 5a2dc594fc..5ca11d3b1f 100644 --- a/packages/client/test/rpc/eth/blobBaseFee.spec.ts +++ b/packages/client/test/rpc/eth/blobBaseFee.spec.ts @@ -1,11 +1,12 @@ import { Hardfork } from '@ethereumjs/common' import { createTxFromTxData } from '@ethereumjs/tx' import { - Address, BIGINT_0, BIGINT_256, blobsToCommitments, commitmentsToVersionedHashes, + createAddressFromPrivateKey, + createZeroAddress, getBlobs, hexToBytes, } from '@ethereumjs/util' @@ -21,7 +22,7 @@ import type { VMExecution } from '../../../src/execution/vmexecution.js' const method = 'eth_blobBaseFee' const privateKey = hexToBytes('0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8') -const accountAddress = Address.fromPrivateKey(privateKey) +const accountAddress = createAddressFromPrivateKey(privateKey) const produceBlockWith4844Tx = async ( execution: VMExecution, chain: Chain, @@ -53,7 +54,7 @@ const produceBlockWith4844Tx = async ( const blobVersionedHashes = [] const blobs = [] const kzgCommitments = [] - const to = Address.zero() + const to = createZeroAddress() if (blobsCount[i] > 0) { for (let blob = 0; blob < blobsCount[i]; blob++) { blobVersionedHashes.push(...blobVersionedHash) diff --git a/packages/client/test/rpc/eth/call.spec.ts b/packages/client/test/rpc/eth/call.spec.ts index a2d7613d0e..53cdad15a1 100644 --- a/packages/client/test/rpc/eth/call.spec.ts +++ b/packages/client/test/rpc/eth/call.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bigIntToHex, bytesToHex } from '@ethereumjs/util' +import { bigIntToHex, bytesToHex, createAddressFromString } from '@ethereumjs/util' import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -33,7 +33,7 @@ describe(method, () => { const { vm } = execution // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // contract: /* @@ -130,7 +130,7 @@ describe(method, () => { const rpc = getRpcClient(startRPC(manager.getMethods())) // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') const funcHash = '26b85ee1' // borrowed from valid test above const estimateTxData = { @@ -156,7 +156,7 @@ describe(method, () => { const rpc = getRpcClient(startRPC(manager.getMethods())) // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') const estimateTxData = { to: address.toString(), from: address.toString(), diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index 4210479c1a..c3c7da94c8 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -3,7 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { createCommonFromGethGenesis } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bigIntToHex } from '@ethereumjs/util' +import { bigIntToHex, createAddressFromString } from '@ethereumjs/util' import { runBlock, runTx } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -42,7 +42,7 @@ describe( await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // contract: /* @@ -196,7 +196,7 @@ describe( const rpc = getRpcClient(startRPC(manager.getMethods())) // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') const funcHash = '26b85ee1' // borrowed from valid test above const estimateTxData = { diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index 63c5b34e30..8b03a6e546 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -3,7 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bigIntToHex } from '@ethereumjs/util' +import { bigIntToHex, createAddressFromString } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -35,7 +35,7 @@ describe( await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // verify balance is genesis amount const genesisBalance = BigInt(0x15ac56edc4d12c0000) diff --git a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts index 2e21890b93..4bec9dd941 100644 --- a/packages/client/test/rpc/eth/getBlockByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockByNumber.spec.ts @@ -1,7 +1,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createCustomCommon } from '@ethereumjs/common' import { create4844BlobTx, createLegacyTx } from '@ethereumjs/tx' -import { Address, hexToBytes } from '@ethereumjs/util' +import { createZeroAddress, hexToBytes } from '@ethereumjs/util' import { loadKZG } from 'kzg-wasm' import { assert, describe, it } from 'vitest' @@ -16,7 +16,7 @@ common.setHardfork('cancun') const mockedTx1 = createLegacyTx({}).sign(dummy.privKey) const mockedTx2 = createLegacyTx({ nonce: 1 }).sign(dummy.privKey) const mockedBlobTx3 = create4844BlobTx( - { nonce: 2, blobsData: ['0x1234'], to: Address.zero() }, + { nonce: 2, blobsData: ['0x1234'], to: createZeroAddress() }, { common }, ).sign(dummy.privKey) const blockHash = hexToBytes('0xdcf93da321b27bca12087d6526d2c10540a4c8dc29db1b36610c3004e0e5d2d5') diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index 63418f5b06..df9b14ceac 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -3,7 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createLegacyTx } from '@ethereumjs/tx' -import { Address } from '@ethereumjs/util' +import { createAddressFromString } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -35,7 +35,7 @@ describe(method, () => { await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // construct block with tx const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) @@ -82,7 +82,7 @@ describe(method, () => { await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // construct block with tx const tx = createLegacyTx({ gasLimit: 53000 }, { common, freeze: false }) diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index 720fd4496c..a580abc3c1 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -3,7 +3,7 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createLegacyTx } from '@ethereumjs/tx' -import { Address } from '@ethereumjs/util' +import { createAddressFromString, createContractAddress } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -31,7 +31,7 @@ describe(method, () => { await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // genesis address - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // verify code is null const res = await rpc.request(method, [address.toString(), 'latest']) @@ -54,7 +54,7 @@ describe(method, () => { const { vm } = execution // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // sample contract from https://ethereum.stackexchange.com/a/70791 const data = @@ -88,7 +88,7 @@ describe(method, () => { const { createdAddress } = result.results[0] await vm.blockchain.putBlock(ranBlock!) - const expectedContractAddress = Address.generate(address, BigInt(0)) + const expectedContractAddress = createContractAddress(address, BigInt(0)) assert.ok( createdAddress!.equals(expectedContractAddress), 'should match the expected contract address', diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index e49108903f..4a21400160 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -2,13 +2,14 @@ import { paramsBlock } from '@ethereumjs/block' import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common' import { createTxFromTxData } from '@ethereumjs/tx' import { - Address, BIGINT_0, BIGINT_256, bigIntToHex, blobsToCommitments, bytesToBigInt, commitmentsToVersionedHashes, + createAddressFromPrivateKey, + createZeroAddress, getBlobs, } from '@ethereumjs/util' import { buildBlock } from '@ethereumjs/vm' @@ -26,12 +27,12 @@ import type { VMExecution } from '../../../src/execution/index.js' const method = 'eth_feeHistory' const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109') -const pKeyAddress = Address.fromPrivateKey(privateKey) +const pKeyAddress = createAddressFromPrivateKey(privateKey) const privateKey4844 = hexToBytes( '0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8', ) -const p4844Address = Address.fromPrivateKey(privateKey4844) +const p4844Address = createAddressFromPrivateKey(privateKey4844) const produceFakeGasUsedBlock = async (execution: VMExecution, chain: Chain, gasUsed: bigint) => { const { vm } = execution @@ -148,7 +149,7 @@ const produceBlockWith4844Tx = async ( const blobVersionedHashes = [] const blobs = [] const kzgCommitments = [] - const to = Address.zero() + const to = createZeroAddress() if (blobsCount[i] > 0) { for (let blob = 0; blob < blobsCount[i]; blob++) { blobVersionedHashes.push(...blobVersionedHash) diff --git a/packages/client/test/rpc/eth/getLogs.spec.ts b/packages/client/test/rpc/eth/getLogs.spec.ts index c433cddea8..db1f6e6d91 100644 --- a/packages/client/test/rpc/eth/getLogs.spec.ts +++ b/packages/client/test/rpc/eth/getLogs.spec.ts @@ -1,5 +1,5 @@ import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex, createContractAddress, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { INVALID_PARAMS } from '../../../src/rpc/error-code.js' @@ -49,8 +49,8 @@ describe(method, async () => { { common }, ).sign(dummy.privKey) - const contractAddr1 = Address.generate(dummy.addr, BigInt(0)) - const contractAddr2 = Address.generate(dummy.addr, BigInt(1)) + const contractAddr1 = createContractAddress(dummy.addr, BigInt(0)) + const contractAddr2 = createContractAddress(dummy.addr, BigInt(1)) // construct txs to emit the logs // data calls log(logCount: 10, num1: 1, num2: 2, num3: 3, num4: 4) const data = hexToBytes( diff --git a/packages/client/test/rpc/eth/getProof.spec.ts b/packages/client/test/rpc/eth/getProof.spec.ts index 84f52a7db8..dd3befdfcb 100644 --- a/packages/client/test/rpc/eth/getProof.spec.ts +++ b/packages/client/test/rpc/eth/getProof.spec.ts @@ -2,7 +2,7 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { Common } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bigIntToHex } from '@ethereumjs/util' +import { bigIntToHex, createAddressFromString } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -106,7 +106,7 @@ describe(method, async () => { const { vm } = execution // genesis address with balance - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // contract inspired from https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat/ /* diff --git a/packages/client/test/rpc/eth/getStorageAt.spec.ts b/packages/client/test/rpc/eth/getStorageAt.spec.ts index e5d3784ead..b51f409155 100644 --- a/packages/client/test/rpc/eth/getStorageAt.spec.ts +++ b/packages/client/test/rpc/eth/getStorageAt.spec.ts @@ -1,6 +1,6 @@ import { createBlockFromBlockData } from '@ethereumjs/block' import { createLegacyTx } from '@ethereumjs/tx' -import { Address } from '@ethereumjs/util' +import { createAddressFromString } from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -14,7 +14,7 @@ const method = 'eth_getStorageAt' describe(method, async () => { it('call with valid arguments', async () => { - const address = Address.fromString(`0x${'11'.repeat(20)}`) + const address = createAddressFromString(`0x${'11'.repeat(20)}`) const emptySlotStr = `0x${'00'.repeat(32)}` const { execution, common, server, chain } = await setupChain(pow, 'pow') diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 03d8e6e068..334725ecca 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -3,7 +3,13 @@ import { createBlockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { getGenesis } from '@ethereumjs/genesis' import { createLegacyTx, createTxFromTxData } from '@ethereumjs/tx' -import { Account, Address, hexToBytes, randomBytes } from '@ethereumjs/util' +import { + Account, + createAddressFromPrivateKey, + createAddressFromString, + hexToBytes, + randomBytes, +} from '@ethereumjs/util' import { runBlock } from '@ethereumjs/vm' import { assert, describe, it } from 'vitest' @@ -37,7 +43,7 @@ describe(method, () => { await vm.stateManager.generateCanonicalGenesis!(getGenesis(1)) // a genesis address - const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') + const address = createAddressFromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') // verify nonce is 0 let res = await rpc.request(method, [address.toString(), 'latest']) @@ -84,7 +90,7 @@ describe(method, () => { const rpc = getRpcClient(startRPC(manager.getMethods())) const pk = hexToBytes('0x266682876da8fd86410d001ec33c7c281515aeeb640d175693534062e2599238') - const address = Address.fromPrivateKey(pk) + const address = createAddressFromPrivateKey(pk) await service.execution.vm.stateManager.putAccount(address, new Account()) const account = await service.execution.vm.stateManager.getAccount(address) account!.balance = 0xffffffffffffffn diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 551daab306..e25fccdc05 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -6,6 +6,7 @@ import { Address, BIGINT_1, KECCAK256_RLP, + createAddressFromString, hexToBytes, parseGethGenesisState, } from '@ethereumjs/util' @@ -93,7 +94,7 @@ export async function createClient(clientOpts: Partial = {}) { const config = new Config({ minerCoinbase: clientOpts.minerCoinbase !== undefined - ? Address.fromString(clientOpts.minerCoinbase) + ? createAddressFromString(clientOpts.minerCoinbase) : undefined, common, saveReceipts: clientOpts.enableMetaDB, diff --git a/packages/client/test/sim/simutils.ts b/packages/client/test/sim/simutils.ts index 2ddba64f10..cdd3479dc7 100644 --- a/packages/client/test/sim/simutils.ts +++ b/packages/client/test/sim/simutils.ts @@ -2,13 +2,13 @@ import { executionPayloadFromBeaconPayload } from '@ethereumjs/block' import { createBlockchain } from '@ethereumjs/blockchain' import { create1559FeeMarketTx, create4844BlobTx } from '@ethereumjs/tx' import { - Address, BIGINT_1, blobsToCommitments, blobsToProofs, bytesToHex, bytesToUtf8, commitmentsToVersionedHashes, + createAddressFromPrivateKey, getBlobs, randomBytes, } from '@ethereumjs/util' @@ -323,7 +323,7 @@ export const runBlobTx = async ( const proofs = blobsToProofs(kzg, blobs, commitments) const hashes = commitmentsToVersionedHashes(commitments) - const sender = Address.fromPrivateKey(pkey) + const sender = createAddressFromPrivateKey(pkey) const txData: TxData[TransactionType.BlobEIP4844] = { to, data: '0x', @@ -395,7 +395,7 @@ export const createBlobTxs = async ( const txns = [] for (let x = startNonce; x <= startNonce + numTxs; x++) { - const sender = Address.fromPrivateKey(pkey) + const sender = createAddressFromPrivateKey(pkey) const txData = { from: sender.toString(), ...txMeta, diff --git a/packages/client/test/sim/snapsync.spec.ts b/packages/client/test/sim/snapsync.spec.ts index 89ae5e2422..dfd5719af1 100644 --- a/packages/client/test/sim/snapsync.spec.ts +++ b/packages/client/test/sim/snapsync.spec.ts @@ -1,7 +1,7 @@ import { createCommonFromGethGenesis } from '@ethereumjs/common' import { - Address, bytesToHex, + createAddressFromString, hexToBytes, parseGethGenesisState, privateToAddress, @@ -217,7 +217,7 @@ describe('simple mainnet test run', async () => { } for (const addressString of Object.keys(customGenesisState)) { - const address = Address.fromString(addressString) + const address = createAddressFromString(addressString) const account = await stateManager?.getAccount(address) assert.equal( account?.balance, diff --git a/packages/client/test/sim/txGenerator.ts b/packages/client/test/sim/txGenerator.ts index bb1225d710..9fd4d2dde3 100644 --- a/packages/client/test/sim/txGenerator.ts +++ b/packages/client/test/sim/txGenerator.ts @@ -1,10 +1,10 @@ // Adapted from - https://github.com/Inphi/eip4844-interop/blob/master/blob_tx_generator/blob.js import { create4844BlobTx } from '@ethereumjs/tx' import { - Address, blobsToCommitments, bytesToHex, commitmentsToVersionedHashes, + createAddressFromPrivateKey, hexToBytes, randomBytes, } from '@ethereumjs/util' @@ -24,7 +24,7 @@ const MAX_USEFUL_BYTES_PER_TX = USEFUL_BYTES_PER_BLOB * MAX_BLOBS_PER_TX - 1 const BLOB_SIZE = BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB const pkey = hexToBytes('0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8') -const sender = Address.fromPrivateKey(pkey) +const sender = createAddressFromPrivateKey(pkey) const kzg = await loadKZG() @@ -100,7 +100,7 @@ async function run(data: any) { const commitments = blobsToCommitments(kzg, blobs) const hashes = commitmentsToVersionedHashes(commitments) - const account = Address.fromPrivateKey(randomBytes(32)) + const account = createAddressFromPrivateKey(randomBytes(32)) const txData: TxData[TransactionType.BlobEIP4844] = { to: account.toString(), data: '0x', diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index cf954832e2..093339bd10 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -10,6 +10,7 @@ import { MAX_INTEGER, bigIntToBytes, bytesToUnprefixedHex, + createZeroAddress, equalsBytes, generateAddress, generateAddress2, @@ -716,14 +717,14 @@ export class EVM implements EVMInterface { message: Message, opts: InterpreterOpts = {}, ): Promise { - let contract = await this.stateManager.getAccount(message.to ?? Address.zero()) + let contract = await this.stateManager.getAccount(message.to ?? createZeroAddress()) if (!contract) { contract = new Account() } const env = { - address: message.to ?? Address.zero(), - caller: message.caller ?? Address.zero(), + address: message.to ?? createZeroAddress(), + caller: message.caller ?? createZeroAddress(), callData: message.data ?? Uint8Array.from([0]), callValue: message.value ?? BIGINT_0, code: message.code as Uint8Array, @@ -731,7 +732,7 @@ export class EVM implements EVMInterface { isCreate: message.isCreate ?? false, depth: message.depth ?? 0, gasPrice: this._tx!.gasPrice, - origin: this._tx!.origin ?? message.caller ?? Address.zero(), + origin: this._tx!.origin ?? message.caller ?? createZeroAddress(), block: this._block ?? defaultBlock(), contract, codeAddress: message.codeAddress, @@ -814,9 +815,9 @@ export class EVM implements EVMInterface { this._block = opts.block ?? defaultBlock() this._tx = { gasPrice: opts.gasPrice ?? BIGINT_0, - origin: opts.origin ?? opts.caller ?? Address.zero(), + origin: opts.origin ?? opts.caller ?? createZeroAddress(), } - const caller = opts.caller ?? Address.zero() + const caller = opts.caller ?? createZeroAddress() const value = opts.value ?? BIGINT_0 if (opts.skipBalance === true) { @@ -952,14 +953,14 @@ export class EVM implements EVMInterface { this._tx = { gasPrice: opts.gasPrice ?? BIGINT_0, - origin: opts.origin ?? opts.caller ?? Address.zero(), + origin: opts.origin ?? opts.caller ?? createZeroAddress(), } const message = new Message({ code: opts.code, data: opts.data, gasLimit: opts.gasLimit ?? BigInt(0xffffff), - to: opts.to ?? Address.zero(), + to: opts.to ?? createZeroAddress(), caller: opts.caller, value: opts.value, depth: opts.depth, @@ -1148,8 +1149,8 @@ export function defaultBlock(): Block { return { header: { number: BIGINT_0, - cliqueSigner: () => Address.zero(), - coinbase: Address.zero(), + cliqueSigner: () => createZeroAddress(), + coinbase: createZeroAddress(), timestamp: BIGINT_0, difficulty: BIGINT_0, prevRandao: zeros(32), diff --git a/packages/evm/src/message.ts b/packages/evm/src/message.ts index 7730fec394..ccc758f2d1 100644 --- a/packages/evm/src/message.ts +++ b/packages/evm/src/message.ts @@ -1,13 +1,13 @@ -import { Address, BIGINT_0 } from '@ethereumjs/util' +import { BIGINT_0, createZeroAddress } from '@ethereumjs/util' import type { PrecompileFunc } from './precompiles/index.js' import type { EOFEnv } from './types.js' import type { AccessWitnessInterface } from '@ethereumjs/common' -import type { PrefixedHexString } from '@ethereumjs/util' +import type { Address, PrefixedHexString } from '@ethereumjs/util' const defaults = { value: BIGINT_0, - caller: Address.zero(), + caller: createZeroAddress(), data: new Uint8Array(0), depth: 0, isStatic: false, diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 8b8fc1fde0..d20b18faa0 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -41,7 +41,7 @@ import { EOFBYTES, EOFHASH, isEOF } from '../eof/util.js' import { ERROR } from '../exceptions.js' import { - addresstoBytes, + createAddressFromStackBigInt, describeLocation, exponentiation, fromTwos, @@ -428,7 +428,7 @@ export const handlers: Map = new Map([ 0x31, async function (runState) { const addressBigInt = runState.stack.pop() - const address = new Address(addresstoBytes(addressBigInt)) + const address = createAddressFromStackBigInt(addressBigInt) const balance = await runState.interpreter.getExternalBalance(address) runState.stack.push(balance) }, @@ -522,7 +522,7 @@ export const handlers: Map = new Map([ 0x3b, async function (runState) { const addressBigInt = runState.stack.pop() - const address = new Address(addresstoBytes(addressBigInt)) + const address = createAddressFromStackBigInt(addressBigInt) // EOF check const code = await runState.stateManager.getCode(address) if (isEOF(code)) { @@ -532,7 +532,7 @@ export const handlers: Map = new Map([ } const size = BigInt( - await runState.stateManager.getCodeSize(new Address(addresstoBytes(addressBigInt))), + await runState.stateManager.getCodeSize(createAddressFromStackBigInt(addressBigInt)), ) runState.stack.push(size) @@ -545,7 +545,7 @@ export const handlers: Map = new Map([ const [addressBigInt, memOffset, codeOffset, dataLength] = runState.stack.popN(4) if (dataLength !== BIGINT_0) { - let code = await runState.stateManager.getCode(new Address(addresstoBytes(addressBigInt))) + let code = await runState.stateManager.getCode(createAddressFromStackBigInt(addressBigInt)) if (isEOF(code)) { // In legacy code, the target code is treated as to be "EOFBYTES" code @@ -564,7 +564,7 @@ export const handlers: Map = new Map([ 0x3f, async function (runState) { const addressBigInt = runState.stack.pop() - const address = new Address(addresstoBytes(addressBigInt)) + const address = createAddressFromStackBigInt(addressBigInt) // EOF check const code = await runState.stateManager.getCode(address) @@ -1419,7 +1419,7 @@ export const handlers: Map = new Map([ async function (runState: RunState, common: Common) { const [_currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.popN(7) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) let data = new Uint8Array(0) if (inLength !== BIGINT_0) { @@ -1447,7 +1447,7 @@ export const handlers: Map = new Map([ async function (runState: RunState, common: Common) { const [_currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.popN(7) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) let gasLimit = runState.messageGasLimit! if (value !== BIGINT_0) { @@ -1476,7 +1476,7 @@ export const handlers: Map = new Map([ const value = runState.interpreter.getCallValue() const [_currentGasLimit, toAddr, inOffset, inLength, outOffset, outLength] = runState.stack.popN(6) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) let data = new Uint8Array(0) if (inLength !== BIGINT_0) { @@ -1580,7 +1580,7 @@ export const handlers: Map = new Map([ const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = runState.stack.popN(7) - const toAddress = new Address(addresstoBytes(addr)) + const toAddress = createAddressFromStackBigInt(addr) const gasLimit = runState.messageGasLimit! runState.messageGasLimit = undefined @@ -1625,7 +1625,7 @@ export const handlers: Map = new Map([ return } - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) let data = new Uint8Array(0) if (inLength !== BIGINT_0) { @@ -1660,7 +1660,7 @@ export const handlers: Map = new Map([ return } - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) const code = await runState.stateManager.getCode(toAddress) @@ -1687,7 +1687,7 @@ export const handlers: Map = new Map([ const value = BIGINT_0 const [_currentGasLimit, toAddr, inOffset, inLength, outOffset, outLength] = runState.stack.popN(6) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) const gasLimit = runState.messageGasLimit! runState.messageGasLimit = undefined @@ -1724,7 +1724,7 @@ export const handlers: Map = new Map([ return } - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) let data = new Uint8Array(0) if (inLength !== BIGINT_0) { @@ -1766,7 +1766,7 @@ export const handlers: Map = new Map([ 0xff, async function (runState) { const selfdestructToAddressBigInt = runState.stack.pop() - const selfdestructToAddress = new Address(addresstoBytes(selfdestructToAddressBigInt)) + const selfdestructToAddress = createAddressFromStackBigInt(selfdestructToAddressBigInt) return runState.interpreter.selfDestruct(selfdestructToAddress) }, ], diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index 81cfae362c..6f8cd64252 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -1,7 +1,6 @@ import { Hardfork } from '@ethereumjs/common' import { Account, - Address, BIGINT_0, BIGINT_1, BIGINT_3, @@ -24,7 +23,7 @@ import { updateSstoreGasEIP1283 } from './EIP1283.js' import { updateSstoreGasEIP2200 } from './EIP2200.js' import { accessAddressEIP2929, accessStorageEIP2929 } from './EIP2929.js' import { - addresstoBytes, + createAddressFromStackBigInt, divCeil, maxCallGas, setLengthLeftStorage, @@ -91,12 +90,11 @@ export const dynamicGasHandlers: Map { - const address = addresstoBytes(runState.stack.peek()[0]) + const address = createAddressFromStackBigInt(runState.stack.peek()[0]) let charge2929Gas = true if (common.isActivatedEIP(6800)) { - const balanceAddress = new Address(address) const coldAccessGas = runState.env.accessWitness!.touchAddressOnReadAndComputeGas( - balanceAddress, + address, 0, VERKLE_BALANCE_LEAF_KEY, ) @@ -106,7 +104,7 @@ export const dynamicGasHandlers: Map { - const addressBytes = addresstoBytes(runState.stack.peek()[0]) - const address = new Address(addressBytes) + const address = createAddressFromStackBigInt(runState.stack.peek()[0]) let charge2929Gas = true if ( @@ -183,7 +180,7 @@ export const dynamicGasHandlers: Map { const [addressBigInt, memOffset, _codeOffset, dataLength] = runState.stack.peek(4) - const addressBytes = addresstoBytes(addressBigInt) - const address = new Address(addressBytes) + const address = createAddressFromStackBigInt(addressBigInt) gas += subMemUsage(runState, memOffset, dataLength, common) @@ -222,7 +218,7 @@ export const dynamicGasHandlers: Map { - const address = addresstoBytes(runState.stack.peek()[0]) + const address = createAddressFromStackBigInt(runState.stack.peek()[0]) let charge2929Gas = true if (common.isActivatedEIP(6800)) { - const codeAddress = new Address(address) - let coldAccessGas = BIGINT_0 coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas( - codeAddress, + address, 0, VERKLE_CODE_HASH_LEAF_KEY, ) @@ -289,7 +283,7 @@ export const dynamicGasHandlers: Map { const [currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.peek(7) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) if (runState.interpreter.isStatic() && value !== BIGINT_0) { trap(ERROR.STATIC_STATE_CHANGE) @@ -641,7 +635,7 @@ export const dynamicGasHandlers: Map { const [currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.peek(7) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) gas += subMemUsage(runState, inOffset, inLength, common) gas += subMemUsage(runState, outOffset, outLength, common) @@ -658,7 +652,12 @@ export const dynamicGasHandlers: Map { const [currentGasLimit, toAddr, inOffset, inLength, outOffset, outLength] = runState.stack.peek(6) - const toAddress = new Address(addresstoBytes(toAddr)) + const toAddress = createAddressFromStackBigInt(toAddr) gas += subMemUsage(runState, inOffset, inLength, common) gas += subMemUsage(runState, outOffset, outLength, common) @@ -714,7 +713,12 @@ export const dynamicGasHandlers: Map } const res = await evm.runCall(runCallArgs) - const address = Address.fromString(bytesToHex(res.execResult.returnValue.slice(12))) + const address = createAddressFromString(bytesToHex(res.execResult.returnValue.slice(12))) const code = await evm.stateManager.getCode(address) assert.equal( diff --git a/packages/evm/test/customPrecompiles.spec.ts b/packages/evm/test/customPrecompiles.spec.ts index ef73bb7efa..7829d6e670 100644 --- a/packages/evm/test/customPrecompiles.spec.ts +++ b/packages/evm/test/customPrecompiles.spec.ts @@ -1,4 +1,4 @@ -import { Address, hexToBytes, utf8ToBytes } from '@ethereumjs/util' +import { Address, createZeroAddress, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { type PrecompileInput, createEVM } from '../src/index.js' @@ -30,13 +30,13 @@ describe('EVM -> custom precompiles', () => { const EVMOverride = await createEVM({ customPrecompiles: [ { - address: Address.zero(), + address: createZeroAddress(), function: customPrecompileNoInput, }, ], }) const result = await EVMOverride.runCall({ - to: Address.zero(), + to: createZeroAddress(), gasLimit: BigInt(30000), data: utf8ToBytes(''), caller: sender, diff --git a/packages/evm/test/eips/eip-3860.spec.ts b/packages/evm/test/eips/eip-3860.spec.ts index 09992f364a..2d4ff7c17f 100644 --- a/packages/evm/test/eips/eip-3860.spec.ts +++ b/packages/evm/test/eips/eip-3860.spec.ts @@ -1,5 +1,12 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, concatBytes, equalsBytes, hexToBytes, privateToAddress } from '@ethereumjs/util' +import { + Address, + concatBytes, + createAddressFromString, + equalsBytes, + hexToBytes, + privateToAddress, +} from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { createEVM } from '../../src/index.js' @@ -53,14 +60,14 @@ describe('EIP 3860 tests', () => { hardfork: Hardfork.London, eips: [], }) - const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const caller = createAddressFromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') const evm = await createEVM({ common: commonWith3860, }) const evmWithout3860 = await createEVM({ common: commonWithout3860, }) - const contractFactory = Address.fromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const contractFactory = createAddressFromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') const contractAccount = await evm.stateManager.getAccount(contractFactory) await evm.stateManager.putAccount(contractFactory, contractAccount!) await evmWithout3860.stateManager.putAccount(contractFactory, contractAccount!) @@ -97,14 +104,14 @@ describe('EIP 3860 tests', () => { hardfork: Hardfork.London, eips: [], }) - const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const caller = createAddressFromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') const evm = await createEVM({ common: commonWith3860, }) const evmWithout3860 = await createEVM({ common: commonWithout3860, }) - const contractFactory = Address.fromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const contractFactory = createAddressFromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') const contractAccount = await evm.stateManager.getAccount(contractFactory) await evm.stateManager.putAccount(contractFactory, contractAccount!) await evmWithout3860.stateManager.putAccount(contractFactory, contractAccount!) @@ -167,7 +174,7 @@ describe('EIP 3860 tests', () => { hardfork: Hardfork.London, eips: [3860], }) - const caller = Address.fromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const caller = createAddressFromString('0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b') for (const code of ['F0', 'F5']) { const evm = await createEVM({ common: commonWith3860, @@ -178,7 +185,7 @@ describe('EIP 3860 tests', () => { common: commonWith3860, allowUnlimitedInitCodeSize: false, }) - const contractFactory = Address.fromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') + const contractFactory = createAddressFromString('0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b') const contractAccount = await evm.stateManager.getAccount(contractFactory) await evm.stateManager.putAccount(contractFactory, contractAccount!) await evmDisabled.stateManager.putAccount(contractFactory, contractAccount!) diff --git a/packages/evm/test/precompiles/09-blake2f.spec.ts b/packages/evm/test/precompiles/09-blake2f.spec.ts index 21a1390896..516e00c200 100644 --- a/packages/evm/test/precompiles/09-blake2f.spec.ts +++ b/packages/evm/test/precompiles/09-blake2f.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { assert, beforeAll, describe, it } from 'vitest' import { createEVM, getActivePrecompiles } from '../../src/index.js' @@ -125,7 +125,7 @@ describe('Precompiles: BLAKE2F', () => { } it('should also work on non-zero aligned inputs', async () => { - const addr = Address.zero() + const addr = createZeroAddress() // Blake2f calldata from https://etherscan.io/tx/0x4f2e13a0a3f14033630ab2b8cdad09d316826375f761ded5b31253bb42e0a476 // (This tx calls into Blake2f multiple times, but one of them is taken) const calldata = diff --git a/packages/evm/test/precompiles/eip-2537-bls.spec.ts b/packages/evm/test/precompiles/eip-2537-bls.spec.ts index 138eeeacfe..87344f39b2 100644 --- a/packages/evm/test/precompiles/eip-2537-bls.spec.ts +++ b/packages/evm/test/precompiles/eip-2537-bls.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { Address, bytesToHex, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { readFileSync, readdirSync } from 'fs' import * as mcl from 'mcl-wasm' import { assert, describe, it } from 'vitest' @@ -111,7 +111,7 @@ describe('EIP-2537 BLS precompile availability tests', () => { for (const address of precompiles) { const to = new Address(hexToBytes(address)) const result = await evm.runCall({ - caller: Address.zero(), + caller: createZeroAddress(), gasLimit: BigInt(0xffffffffff), to, value: BigInt(0), diff --git a/packages/evm/test/precompiles/hardfork.spec.ts b/packages/evm/test/precompiles/hardfork.spec.ts index 1b46c97f94..91f91853b1 100644 --- a/packages/evm/test/precompiles/hardfork.spec.ts +++ b/packages/evm/test/precompiles/hardfork.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, hexToBytes } from '@ethereumjs/util' +import { Address, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { createEVM, getActivePrecompiles } from '../../src/index.js' @@ -24,7 +24,7 @@ describe('Precompiles: hardfork availability', () => { common: commonByzantium, }) let result = await evm.runCall({ - caller: Address.zero(), + caller: createZeroAddress(), gasLimit: BigInt(0xffffffffff), to: ECPAIR_Address, value: BigInt(0), @@ -45,7 +45,7 @@ describe('Precompiles: hardfork availability', () => { common: commonPetersburg, }) result = await evm.runCall({ - caller: Address.zero(), + caller: createZeroAddress(), gasLimit: BigInt(0xffffffffff), to: ECPAIR_Address, value: BigInt(0), @@ -68,7 +68,7 @@ describe('Precompiles: hardfork availability', () => { }) result = await evm.runCall({ - caller: Address.zero(), + caller: createZeroAddress(), gasLimit: BigInt(0xffffffffff), to: ECPAIR_Address, value: BigInt(0), diff --git a/packages/evm/test/runCall.spec.ts b/packages/evm/test/runCall.spec.ts index 0e59c6633c..e9d310f944 100644 --- a/packages/evm/test/runCall.spec.ts +++ b/packages/evm/test/runCall.spec.ts @@ -6,6 +6,9 @@ import { bytesToBigInt, bytesToHex, concatBytes, + createAddressFromPrivateKey, + createAddressFromString, + createZeroAddress, hexToBytes, padToEven, unpadBytes, @@ -459,7 +462,7 @@ describe('RunCall tests', () => { // setup the call arguments const runCallArgs = { - to: Address.zero(), + to: createZeroAddress(), value: BigInt(-10), } @@ -480,12 +483,12 @@ describe('RunCall tests', () => { // runCall against a contract to reach `_reduceSenderBalance` const contractCode = hexToBytes('0x00') // 00: STOP - const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') + const contractAddress = createAddressFromString('0x000000000000000000000000636F6E7472616374') await evm.stateManager.putCode(contractAddress, contractCode) const senderKey = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) - const sender = Address.fromPrivateKey(senderKey) + const sender = createAddressFromPrivateKey(senderKey) const runCallArgs = { gasLimit: BigInt(21000), @@ -615,7 +618,7 @@ describe('RunCall tests', () => { const evm = await createEVM({ common }) const contractCode = hexToBytes('0x600060405200') // PUSH 0 PUSH 40 MSTORE STOP - const contractAddress = Address.fromString('0x000000000000000000000000636F6E7472616374') + const contractAddress = createAddressFromString('0x000000000000000000000000636F6E7472616374') await evm.stateManager.putCode(contractAddress, contractCode) const runCallArgs = { @@ -708,7 +711,7 @@ describe('RunCall tests', () => { * PUSH2 0x1a90 // Note: this is the gas available in the new call(code) frame, this value does not matter * CALLCODE/CALL */ - const callCodeAddress = Address.fromString('0x000000000000000000000000000000000000aaaa') + const callCodeAddress = createAddressFromString('0x000000000000000000000000000000000000aaaa') const callCode = hexToBytes(`0x6000600060006000600161AACC611a90${opcode}`) const gasLimit = gas.toString(16).padStart(4, '0') @@ -726,7 +729,7 @@ describe('RunCall tests', () => { * PUSH1 0x00 * SSTORE */ - const callerAddress = Address.fromString('0x000000000000000000000000000000000000aaab') + const callerAddress = createAddressFromString('0x000000000000000000000000000000000000aaab') const callerCode = hexToBytes(`0x60008080808061AAAA61${gasLimit}f1600055`) await evm.stateManager.putAccount(callCodeAddress, new Account()) diff --git a/packages/evm/test/runCode.spec.ts b/packages/evm/test/runCode.spec.ts index 00eafbb573..821626a339 100644 --- a/packages/evm/test/runCode.spec.ts +++ b/packages/evm/test/runCode.spec.ts @@ -1,4 +1,4 @@ -import { Account, Address, hexToBytes } from '@ethereumjs/util' +import { Account, createAddressFromString, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { createEVM } from '../src/index.js' @@ -82,7 +82,7 @@ describe('VM.runCode: interpreter', () => { // does not exist, then if SSTORE/SLOAD is used, the runCode will immediately fail because StateManager now throws // TODO: is this behavior which we should fix? (Either in StateManager OR in runCode where we load the account first, // then re-put the account after (if account === undefined put empty account, such that the account exists)) - const address = Address.fromString(`0x${'00'.repeat(20)}`) + const address = createAddressFromString(`0x${'00'.repeat(20)}`) await evm.stateManager.putAccount(address, new Account()) evm.stateManager.putStorage = (..._args) => { throw new Error('Test') diff --git a/packages/evm/test/transientStorage.spec.ts b/packages/evm/test/transientStorage.spec.ts index 94a29cd8fa..acf90275c1 100644 --- a/packages/evm/test/transientStorage.spec.ts +++ b/packages/evm/test/transientStorage.spec.ts @@ -1,4 +1,4 @@ -import { Address } from '@ethereumjs/util' +import { createAddressFromString } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { TransientStorage } from '../src/transientStorage.js' @@ -7,7 +7,7 @@ describe('Transient Storage', () => { it('should set and get storage', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value = new Uint8Array(32).fill(0x99) @@ -19,7 +19,7 @@ describe('Transient Storage', () => { it('should return bytes32(0) if there is no key set', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value = new Uint8Array(32).fill(0x11) @@ -36,7 +36,7 @@ describe('Transient Storage', () => { it('should revert', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value = new Uint8Array(32).fill(0x99) @@ -58,7 +58,7 @@ describe('Transient Storage', () => { it('should commit', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value = new Uint8Array(32).fill(0x99) @@ -74,7 +74,7 @@ describe('Transient Storage', () => { it('should fail with wrong size key/value', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') assert.throws(() => { transientStorage.put(address, new Uint8Array(10), new Uint8Array(1)) @@ -88,14 +88,14 @@ describe('Transient Storage', () => { it('keys are stringified', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value = new Uint8Array(32).fill(0x99) transientStorage.put(address, key, value) assert.deepEqual( transientStorage.get( - Address.fromString('0xff00000000000000000000000000000000000002'), + createAddressFromString('0xff00000000000000000000000000000000000002'), new Uint8Array(32).fill(0xff), ), value, @@ -105,7 +105,7 @@ describe('Transient Storage', () => { it('revert applies changes in correct order', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value1 = new Uint8Array(32).fill(0x01) const value2 = new Uint8Array(32).fill(0x02) @@ -123,7 +123,7 @@ describe('Transient Storage', () => { it('nested reverts', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value0 = new Uint8Array(32).fill(0x00) const value1 = new Uint8Array(32).fill(0x01) @@ -153,7 +153,7 @@ describe('Transient Storage', () => { it('commit batches changes into next revert', () => { const transientStorage = new TransientStorage() - const address = Address.fromString('0xff00000000000000000000000000000000000002') + const address = createAddressFromString('0xff00000000000000000000000000000000000002') const key = new Uint8Array(32).fill(0xff) const value1 = new Uint8Array(32).fill(0x01) const value2 = new Uint8Array(32).fill(0x02) diff --git a/packages/statemanager/examples/rpcStateManager.ts b/packages/statemanager/examples/rpcStateManager.ts index f711f2804b..24a2a2217c 100644 --- a/packages/statemanager/examples/rpcStateManager.ts +++ b/packages/statemanager/examples/rpcStateManager.ts @@ -1,11 +1,11 @@ import { RPCStateManager } from '@ethereumjs/statemanager' -import { Address } from '@ethereumjs/util' +import { createAddressFromString } from '@ethereumjs/util' const main = async () => { try { const provider = 'https://path.to.my.provider.com' const stateManager = new RPCStateManager({ provider, blockTag: 500000n }) - const vitalikDotEth = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') + const vitalikDotEth = createAddressFromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') const account = await stateManager.getAccount(vitalikDotEth) console.log('Vitalik has a current ETH balance of ', account?.balance) } catch (e) { diff --git a/packages/statemanager/examples/simple.ts b/packages/statemanager/examples/simple.ts index 308897ce95..5686606ba8 100644 --- a/packages/statemanager/examples/simple.ts +++ b/packages/statemanager/examples/simple.ts @@ -1,10 +1,10 @@ -import { Account, Address, randomBytes } from '@ethereumjs/util' +import { Account, createAddressFromPrivateKey, randomBytes } from '@ethereumjs/util' import { SimpleStateManager } from '../src/index.js' const main = async () => { const sm = new SimpleStateManager() - const address = Address.fromPrivateKey(randomBytes(32)) + const address = createAddressFromPrivateKey(randomBytes(32)) const account = new Account(0n, 0xfffffn) await sm.putAccount(address, account) console.log(await sm.getAccount(address)) diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 50aad47542..79c75a34f7 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -3,7 +3,6 @@ import { RLP } from '@ethereumjs/rlp' import { Trie, createTrieFromProof, verifyTrieProof } from '@ethereumjs/trie' import { Account, - Address, KECCAK256_NULL, KECCAK256_NULL_S, KECCAK256_RLP, @@ -14,6 +13,7 @@ import { concatBytes, createAccount, createAccountFromRLP, + createAddressFromString, equalsBytes, hexToBytes, setLengthLeft, @@ -43,7 +43,7 @@ import type { StorageDump, StorageRange, } from '@ethereumjs/common' -import type { DB, PrefixedHexString } from '@ethereumjs/util' +import type { Address, DB, PrefixedHexString } from '@ethereumjs/util' import type { Debugger } from 'debug' /** @@ -562,7 +562,7 @@ export class DefaultStateManager implements StateManagerInterface { if (!this._codeCacheSettings.deactivate) { const items = this._codeCache!.flush() for (const item of items) { - const addr = Address.fromString(`0x${item[0]}`) + const addr = createAddressFromString(`0x${item[0]}`) const code = item[1].code if (code === undefined) { @@ -584,7 +584,7 @@ export class DefaultStateManager implements StateManagerInterface { if (!this._storageCacheSettings.deactivate) { const items = this._storageCache!.flush() for (const item of items) { - const address = Address.fromString(`0x${item[0]}`) + const address = createAddressFromString(`0x${item[0]}`) const keyHex = item[1] const keyBytes = unprefixedHexToBytes(keyHex) const value = item[2] @@ -687,7 +687,7 @@ export class DefaultStateManager implements StateManagerInterface { { useKeyHashing: true }, )) const sm = new DefaultStateManager({ ...opts, trie }) - const address = Address.fromString(proof[0].address) + const address = createAddressFromString(proof[0].address) await sm.addStorageProof(proof[0].storageProof, proof[0].storageHash, address, safe) for (let i = 1; i < proof.length; i++) { const proofItem = proof[i] @@ -740,7 +740,7 @@ export class DefaultStateManager implements StateManagerInterface { await this.addStorageProof( proof[i].storageProof, proof[i].storageHash, - Address.fromString(proof[i].address), + createAddressFromString(proof[i].address), safe, ) } @@ -940,7 +940,7 @@ export class DefaultStateManager implements StateManagerInterface { } const addresses = Object.keys(initState) for (const address of addresses) { - const addr = Address.fromString(address) + const addr = createAddressFromString(address) const state = initState[address] if (!Array.isArray(state)) { // Prior format: address -> balance diff --git a/packages/statemanager/test/proofStateManager.spec.ts b/packages/statemanager/test/proofStateManager.spec.ts index 41c02a7333..3a1e2bef2e 100644 --- a/packages/statemanager/test/proofStateManager.spec.ts +++ b/packages/statemanager/test/proofStateManager.spec.ts @@ -4,6 +4,9 @@ import { Address, bytesToHex, bytesToUnprefixedHex, + createAddressFromPrivateKey, + createAddressFromString, + createZeroAddress, equalsBytes, hexToBytes, randomBytes, @@ -23,7 +26,7 @@ import type { PrefixedHexString } from '@ethereumjs/util' describe('ProofStateManager', () => { it(`should return quantity-encoded RPC representation`, async () => { - const address = Address.zero() + const address = createZeroAddress() const key = zeros(32) const stateManager = new DefaultStateManager() @@ -33,7 +36,7 @@ describe('ProofStateManager', () => { }) it(`should correctly return the right storage root / account root`, async () => { - const address = Address.zero() + const address = createZeroAddress() const key = zeros(32) const stateManager = new DefaultStateManager() @@ -47,7 +50,7 @@ describe('ProofStateManager', () => { }) it(`should return quantity-encoded RPC representation for existing accounts`, async () => { - const address = Address.zero() + const address = createZeroAddress() const key = zeros(32) const stateManager = new DefaultStateManager() @@ -75,7 +78,7 @@ describe('ProofStateManager', () => { }) it(`should get and verify EIP 1178 proofs`, async () => { - const address = Address.zero() + const address = createZeroAddress() const key = zeros(32) const value = hexToBytes('0x0000aabb00') const code = hexToBytes('0x6000') @@ -97,7 +100,9 @@ describe('ProofStateManager', () => { const proof = await stateManager.getProof(address, [key]) assert.ok(await stateManager.verifyProof(proof)) - const nonExistenceProof = await stateManager.getProof(Address.fromPrivateKey(randomBytes(32))) + const nonExistenceProof = await stateManager.getProof( + createAddressFromPrivateKey(randomBytes(32)), + ) assert.equal( await stateManager.verifyProof(nonExistenceProof), true, @@ -110,7 +115,7 @@ describe('ProofStateManager', () => { // Block: 11098094 (hash 0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146) // Account: 0xc626553e7c821d0f8308c28d56c60e3c15f8d55a // Storage slots: empty list - const address = Address.fromString('0xc626553e7c821d0f8308c28d56c60e3c15f8d55a') + const address = createAddressFromString('0xc626553e7c821d0f8308c28d56c60e3c15f8d55a') const trie = await createTrie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB @@ -134,7 +139,7 @@ describe('ProofStateManager', () => { // Block: 11098094 (hash 0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146) // Account: 0x68268f12253f69f66b188c95b8106b2f847859fc (this account does not exist) // Storage slots: empty list - const address = Address.fromString('0x68268f12253f69f66b188c95b8106b2f847859fc') + const address = createAddressFromString('0x68268f12253f69f66b188c95b8106b2f847859fc') const trie = new Trie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB @@ -158,7 +163,7 @@ describe('ProofStateManager', () => { // eth.getProof("0x2D80502854FC7304c3E3457084DE549f5016B73f", ["0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1ca", "0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1cb"], 11098094) // Note: the first slot has a value, but the second slot is empty // Note: block hash 0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146 - const address = Address.fromString('0x2D80502854FC7304c3E3457084DE549f5016B73f') + const address = createAddressFromString('0x2D80502854FC7304c3E3457084DE549f5016B73f') const trie = new Trie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB @@ -196,7 +201,7 @@ describe('ProofStateManager', () => { // eth.getProof("0x2D80502854FC7304c3E3457084DE549f5016B73f", ["0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1ca", "0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1cb"], 11098094) // Note: the first slot has a value, but the second slot is empty // Note: block hash 0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146 - const address = Address.fromString('0x2D80502854FC7304c3E3457084DE549f5016B73f') + const address = createAddressFromString('0x2D80502854FC7304c3E3457084DE549f5016B73f') const trie = new Trie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB @@ -262,7 +267,7 @@ describe('ProofStateManager', () => { // eth.getProof("0x2D80502854FC7304c3E3457084DE549f5016B73f", ["0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1ca", "0x1e8bf26b05059b66f11b6e0c5b9fe941f81181d6cc9f2af65ccee86e95cea1cb"], 11098094) // Note: the first slot has a value, but the second slot is empty // Note: block hash 0x1d9ea6981b8093a2b63f22f74426ceb6ba1acae3fddd7831442bbeba3fa4f146 - const address = Address.fromString('0x68268f12253f69f66b188c95b8106b2f847859fc') + const address = createAddressFromString('0x68268f12253f69f66b188c95b8106b2f847859fc') const trie = new Trie({ useKeyHashing: true }) const stateManager = new DefaultStateManager({ trie }) // Dump all the account proof data in the DB diff --git a/packages/statemanager/test/rpcStateManager.spec.ts b/packages/statemanager/test/rpcStateManager.spec.ts index d4a4f1f03f..354356bf6c 100644 --- a/packages/statemanager/test/rpcStateManager.spec.ts +++ b/packages/statemanager/test/rpcStateManager.spec.ts @@ -8,6 +8,7 @@ import { bytesToHex, bytesToUnprefixedHex, createAccountFromRLP, + createAddressFromString, equalsBytes, hexToBytes, setLengthLeft, @@ -78,7 +79,7 @@ describe('RPC State Manager initialization tests', async () => { describe('RPC State Manager API tests', () => { it('should work', async () => { const state = new RPCStateManager({ provider, blockTag: 1n }) - const vitalikDotEth = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') + const vitalikDotEth = createAddressFromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') const account = await state.getAccount(vitalikDotEth) assert.ok(account!.nonce > 0n, 'Vitalik.eth returned a valid nonce') @@ -91,13 +92,15 @@ describe('RPC State Manager API tests', () => { assert.ok(retrievedVitalikAccount.nonce > 0n, 'Vitalik.eth is stored in cache') const doesThisAccountExist = await state.accountExists( - Address.fromString('0xccAfdD642118E5536024675e776d32413728DD07'), + createAddressFromString('0xccAfdD642118E5536024675e776d32413728DD07'), ) assert.ok(!doesThisAccountExist, 'getAccount returns undefined for non-existent account') assert.ok(state.getAccount(vitalikDotEth) !== undefined, 'vitalik.eth does exist') - const UNIerc20ContractAddress = Address.fromString('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') + const UNIerc20ContractAddress = createAddressFromString( + '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', + ) const UNIContractCode = await state.getCode(UNIerc20ContractAddress) assert.ok(UNIContractCode.length > 0, 'was able to retrieve UNI contract code') @@ -160,7 +163,7 @@ describe('RPC State Manager API tests', () => { ) try { - await state.getAccount(Address.fromString('0x9Cef824A8f4b3Dc6B7389933E52e47F010488Fc8')) + await state.getAccount(createAddressFromString('0x9Cef824A8f4b3Dc6B7389933E52e47F010488Fc8')) } catch (err) { assert.ok(true, 'calls getAccountFromProvider for non-cached account') } @@ -238,7 +241,7 @@ describe('runTx custom transaction test', () => { const state = new RPCStateManager({ provider, blockTag: 1n }) const vm = await VM.create({ common, stateManager: state }) // TODO fix the type DefaultStateManager back to StateManagerInterface in VM - const vitalikDotEth = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') + const vitalikDotEth = createAddressFromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') const privateKey = hexToBytes( '0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', ) @@ -323,7 +326,7 @@ describe('blockchain', () => const code = '0x600143034060005260206000F3' const contractAddress = new Address(hexToBytes('0x00000000000000000000000000000000000000ff')) - const caller = Address.fromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') + const caller = createAddressFromString('0xd8da6bf26964af9d7eed9e03e53415d37aa96045') await evm.stateManager.setStateRoot( hexToBytes('0xf8506f559699a58a4724df4fcf2ad4fd242d20324db541823f128f5974feb6c7'), ) diff --git a/packages/statemanager/test/stateManager.code.spec.ts b/packages/statemanager/test/stateManager.code.spec.ts index db47c19a03..ee7dc802ac 100644 --- a/packages/statemanager/test/stateManager.code.spec.ts +++ b/packages/statemanager/test/stateManager.code.spec.ts @@ -1,4 +1,10 @@ -import { Address, createAccount, equalsBytes, hexToBytes } from '@ethereumjs/util' +import { + Address, + createAccount, + createZeroAddress, + equalsBytes, + hexToBytes, +} from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { DefaultStateManager } from '../src/index.js' @@ -18,7 +24,7 @@ describe('StateManager -> Code', () => { This test is mostly an example of why a code prefix is necessary I an address, we put two storage values. The preimage of the (storage trie) root hash is known This preimage is used as codeHash - + NOTE: Currently, the only problem which this code prefix fixes, is putting 0x80 as contract code -> This hashes to the empty trie node hash (0x80 = RLP([])), so keccak256(0x80) = empty trie node hash -> Therefore, each empty state trie now points to 0x80, which is not a valid trie node, which crashes @ethereumjs/trie @@ -151,7 +157,7 @@ describe('StateManager -> Code', () => { it('putCode with empty code on existing address should correctly propagate', async () => { const stateManager = new DefaultStateManager() - const address = Address.zero() + const address = createZeroAddress() await stateManager.putCode(address, new Uint8Array([1])) await stateManager.putCode(address, new Uint8Array()) const account = await stateManager.getAccount(address) diff --git a/packages/statemanager/test/stateManager.spec.ts b/packages/statemanager/test/stateManager.spec.ts index 585fa1654e..1744973e3b 100644 --- a/packages/statemanager/test/stateManager.spec.ts +++ b/packages/statemanager/test/stateManager.spec.ts @@ -1,9 +1,11 @@ import { Trie, createTrie, createTrieFromProof } from '@ethereumjs/trie' import { Account, - Address, KECCAK256_RLP, bigIntToBytes, + createAddressFromPrivateKey, + createAddressFromString, + createZeroAddress, equalsBytes, hexToBytes, intToBytes, @@ -44,7 +46,7 @@ describe('StateManager -> General', () => { it(`should clear contract storage`, async () => { const sm = new DefaultStateManager() - const contractAddress = Address.fromString('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') + const contractAddress = createAddressFromString('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984') const contractCode = Uint8Array.from([0, 1, 2, 3]) const storageKey = setLengthLeft(bigIntToBytes(2n), 32) const storedData = utf8ToBytes('abcd') @@ -142,9 +144,9 @@ describe('StateManager -> General', () => { const address2Str = '0x2'.padEnd(42, '0') const address3Str = '0x3'.padEnd(42, '0') - const address1 = Address.fromString(address1Str) - const address2 = Address.fromString(address2Str) - const address3 = Address.fromString(address3Str) + const address1 = createAddressFromString(address1Str) + const address2 = createAddressFromString(address2Str) + const address3 = createAddressFromString(address3Str) const key1 = setLengthLeft(new Uint8Array([1]), 32) const key2 = setLengthLeft(new Uint8Array([2]), 32) @@ -184,7 +186,7 @@ describe('StateManager -> General', () => { const stateManager = new DefaultStateManager() for (const [addressStr, entry] of Object.entries(stateSetup)) { - const address = Address.fromString(addressStr) + const address = createAddressFromString(addressStr) const account = new Account(entry.nonce, entry.balance) await stateManager.putAccount(address, account) await stateManager.putCode(address, entry.code) @@ -267,8 +269,8 @@ describe('StateManager -> General', () => { await postVerify(newPartialStateManager2) const zeroAddressNonce = BigInt(100) - await stateManager.putAccount(Address.zero(), new Account(zeroAddressNonce)) - const zeroAddressProof = await stateManager.getProof(Address.zero()) + await stateManager.putAccount(createZeroAddress(), new Account(zeroAddressNonce)) + const zeroAddressProof = await stateManager.getProof(createZeroAddress()) try { await DefaultStateManager.fromProof([proof1, zeroAddressProof], true) @@ -279,11 +281,11 @@ describe('StateManager -> General', () => { await newPartialStateManager2.addProofData(zeroAddressProof) - let zeroAccount = await newPartialStateManager2.getAccount(Address.zero()) + let zeroAccount = await newPartialStateManager2.getAccount(createZeroAddress()) assert.ok(zeroAccount === undefined) await newPartialStateManager2.setStateRoot(await stateManager.getStateRoot()) - zeroAccount = await newPartialStateManager2.getAccount(Address.zero()) + zeroAccount = await newPartialStateManager2.getAccount(createZeroAddress()) assert.ok(zeroAccount!.nonce === zeroAddressNonce) }) it.skipIf(isBrowser() === true)( @@ -293,8 +295,8 @@ describe('StateManager -> General', () => { const sm = new DefaultStateManager({ trie }) const pk = hexToBytes('0x9f12aab647a25a81f821a5a0beec3330cd057b2346af4fb09d7a807e896701ea') const pk2 = hexToBytes('0x8724f27e2ce3714af01af3220478849db68a03c0f84edf1721d73d9a6139ad1c') - const address = Address.fromPrivateKey(pk) - const address2 = Address.fromPrivateKey(pk2) + const address = createAddressFromPrivateKey(pk) + const address2 = createAddressFromPrivateKey(pk2) const account = new Account() const account2 = new Account(undefined, 100n) await sm.putAccount(address, account) diff --git a/packages/statemanager/test/stateManager.storage.spec.ts b/packages/statemanager/test/stateManager.storage.spec.ts index 40d8113348..ed65a30f8f 100644 --- a/packages/statemanager/test/stateManager.storage.spec.ts +++ b/packages/statemanager/test/stateManager.storage.spec.ts @@ -2,6 +2,7 @@ import { Address, bytesToHex, concatBytes, + createZeroAddress, equalsBytes, hexToBytes, unpadBytes, @@ -72,7 +73,7 @@ describe('StateManager -> Storage', () => { it(`should throw on storage values larger than 32 bytes`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) - const address = Address.zero() + const address = createZeroAddress() const account = createAccountWithDefaults() await stateManager.putAccount(address, account) @@ -88,7 +89,7 @@ describe('StateManager -> Storage', () => { it(`should strip zeros of storage values`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) - const address = Address.zero() + const address = createZeroAddress() const account = createAccountWithDefaults() await stateManager.putAccount(address, account) @@ -109,7 +110,7 @@ describe('StateManager -> Storage', () => { }) it(`should delete storage values which only consist of zero bytes`, async () => { - const address = Address.zero() + const address = createZeroAddress() const key = zeros(32) const startValue = hexToBytes('0x01') @@ -138,7 +139,7 @@ describe('StateManager -> Storage', () => { it(`should not strip trailing zeros`, async () => { const stateManager = new DefaultStateManager({ prefixStorageTrieKeys, storageCacheOpts }) - const address = Address.zero() + const address = createZeroAddress() const account = createAccountWithDefaults() await stateManager.putAccount(address, account) diff --git a/packages/statemanager/test/statelessVerkleStateManager.spec.ts b/packages/statemanager/test/statelessVerkleStateManager.spec.ts index da1588b4e1..8f8f74df82 100644 --- a/packages/statemanager/test/statelessVerkleStateManager.spec.ts +++ b/packages/statemanager/test/statelessVerkleStateManager.spec.ts @@ -7,6 +7,7 @@ import { bytesToBigInt, bytesToHex, createAccount, + createAddressFromString, getVerkleKey, getVerkleStem, hexToBytes, @@ -54,7 +55,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { stateManager.initVerkleExecutionWitness(block.header.number, block.executionWitness) const account = await stateManager.getAccount( - Address.fromString('0x6177843db3138ae69679a54b95cf345ed759450d'), + createAddressFromString('0x6177843db3138ae69679a54b95cf345ed759450d'), ) assert.equal(account!.balance, 288610978528114322n, 'should have correct balance') @@ -117,7 +118,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { const stateManager = new StatelessVerkleStateManager({ common, verkleCrypto }) stateManager.initVerkleExecutionWitness(block.header.number, block.executionWitness) - const address = Address.fromString('0x6177843db3138ae69679a54b95cf345ed759450d') + const address = createAddressFromString('0x6177843db3138ae69679a54b95cf345ed759450d') const stem = getVerkleStem(stateManager.verkleCrypto, address, 0n) const balanceKey = getVerkleKey(stem, VerkleLeafType.Balance) @@ -175,7 +176,7 @@ describe('StatelessVerkleStateManager: Kaustinen Verkle Block', () => { const stateManager = new StatelessVerkleStateManager({ common, verkleCrypto }) stateManager.initVerkleExecutionWitness(block.header.number, block.executionWitness) - const contractAddress = Address.fromString('0x4242424242424242424242424242424242424242') + const contractAddress = createAddressFromString('0x4242424242424242424242424242424242424242') const storageKey = '0x0000000000000000000000000000000000000000000000000000000000000022' const storageValue = '0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b' await stateManager.putStorage(contractAddress, hexToBytes(storageKey), hexToBytes(storageValue)) diff --git a/packages/tx/examples/custom-chain-tx.ts b/packages/tx/examples/custom-chain-tx.ts index 8d111ff918..e982712b79 100644 --- a/packages/tx/examples/custom-chain-tx.ts +++ b/packages/tx/examples/custom-chain-tx.ts @@ -1,6 +1,6 @@ import { createCustomCommon } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, hexToBytes } from '@ethereumjs/util' +import { createAddressFromPrivateKey, hexToBytes } from '@ethereumjs/util' // In this example we create a transaction for a custom network. @@ -35,7 +35,7 @@ const tx = createLegacyTx( const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109') const signedTx = tx.sign(privateKey) -const address = Address.fromPrivateKey(privateKey) +const address = createAddressFromPrivateKey(privateKey) if (signedTx.isValid() && signedTx.getSenderAddress().equals(address)) { console.log('Valid signature') diff --git a/packages/tx/examples/l2tx.ts b/packages/tx/examples/l2tx.ts index 15977fb777..05bcbbd0d5 100644 --- a/packages/tx/examples/l2tx.ts +++ b/packages/tx/examples/l2tx.ts @@ -1,9 +1,9 @@ import { CustomChain, createCustomCommon } from '@ethereumjs/common' import { createLegacyTx } from '@ethereumjs/tx' -import { Address, bytesToHex, hexToBytes } from '@ethereumjs/util' +import { bytesToHex, createAddressFromString, hexToBytes } from '@ethereumjs/util' const pk = hexToBytes('0x076247989df60a82f6e86e58104368676096f84e60972282ee00d4673a2bc9b9') -const to = Address.fromString('0x256e8f0ba532ad83a0debde7501669511a41a1f3') +const to = createAddressFromString('0x256e8f0ba532ad83a0debde7501669511a41a1f3') const common = createCustomCommon(CustomChain.xDaiChain) const txData = { diff --git a/packages/tx/test/eip3860.spec.ts b/packages/tx/test/eip3860.spec.ts index dfcc728476..c008d9c3bc 100644 --- a/packages/tx/test/eip3860.spec.ts +++ b/packages/tx/test/eip3860.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address } from '@ethereumjs/util' +import { createZeroAddress } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { TransactionType, createTxFromTxData, paramsTx } from '../src/index.js' @@ -18,7 +18,7 @@ const txTypes = [ TransactionType.FeeMarketEIP1559, //TransactionType.BlobEIP4844, // Explicitly commented out: BlobEIP4844 txs cannot create contracts ] -const addressZero = Address.zero() +const addressZero = createZeroAddress() describe('[EIP3860 tests]', () => { it(`Should instantiate create txs with MAX_INITCODE_SIZE`, () => { diff --git a/packages/tx/test/eip4844.spec.ts b/packages/tx/test/eip4844.spec.ts index d7e8c4d363..9db5d7c447 100644 --- a/packages/tx/test/eip4844.spec.ts +++ b/packages/tx/test/eip4844.spec.ts @@ -1,11 +1,11 @@ import { Hardfork, createCommonFromGethGenesis } from '@ethereumjs/common' import { - Address, blobsToCommitments, blobsToProofs, bytesToHex, commitmentsToVersionedHashes, concatBytes, + createZeroAddress, ecsign, equalsBytes, getBlobs, @@ -46,7 +46,7 @@ describe('EIP4844 addSignature tests', () => { const privateKey = pk const tx = create4844BlobTx( { - to: Address.zero(), + to: createZeroAddress(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, { common }, @@ -61,7 +61,7 @@ describe('EIP4844 addSignature tests', () => { const privKey = pk const tx = create4844BlobTx( { - to: Address.zero(), + to: createZeroAddress(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, { common }, @@ -80,7 +80,7 @@ describe('EIP4844 addSignature tests', () => { const privKey = pk const tx = create4844BlobTx( { - to: Address.zero(), + to: createZeroAddress(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, { common }, @@ -111,7 +111,7 @@ describe('EIP4844 constructor tests - valid scenarios', () => { type: 0x03, blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], maxFeePerBlobGas: 1n, - to: Address.zero(), + to: createZeroAddress(), } const tx = create4844BlobTx(txData, { common }) assert.equal(tx.type, 3, 'successfully instantiated a blob transaction from txData') @@ -220,7 +220,7 @@ describe('EIP4844 constructor tests - invalid scenarios', () => { const baseTxData = { type: 0x03, maxFeePerBlobGas: 1n, - to: Address.zero(), + to: createZeroAddress(), } const shortVersionHash = { blobVersionedHashes: [concatBytes(new Uint8Array([3]), randomBytes(3))], @@ -560,7 +560,7 @@ describe('hash() and signature verification', () => { storageKeys: ['0x0000000000000000000000000000000000000000000000000000000000000000'], }, ], - to: Address.zero(), + to: createZeroAddress(), }, { common }, ) @@ -593,7 +593,7 @@ it('getEffectivePriorityFee()', async () => { { maxFeePerGas: 10, maxPriorityFeePerGas: 8, - to: Address.zero(), + to: createZeroAddress(), blobVersionedHashes: [concatBytes(new Uint8Array([1]), randomBytes(31))], }, { common }, diff --git a/packages/tx/test/eip7702.spec.ts b/packages/tx/test/eip7702.spec.ts index 47222ce5c4..9ef52a6a19 100644 --- a/packages/tx/test/eip7702.spec.ts +++ b/packages/tx/test/eip7702.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, hexToBytes, privateToAddress } from '@ethereumjs/util' +import { createAddressFromPrivateKey, createZeroAddress, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { create7702EOACodeTx } from '../src/index.js' @@ -8,8 +8,8 @@ import type { PrefixedHexString } from '@ethereumjs/util' const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Cancun, eips: [7702] }) -const pkey = hexToBytes('0x' + '20'.repeat(32)) -const addr = new Address(privateToAddress(pkey)) +const pkey = hexToBytes(`0x${'20'.repeat(32)}`) +const addr = createAddressFromPrivateKey(pkey) const ones32 = `0x${'01'.repeat(32)}` as PrefixedHexString @@ -24,7 +24,7 @@ describe('[EOACodeEIP7702Transaction]', () => { authorizationList: [], chainId: 1, gasLimit: 100000, - to: Address.zero(), + to: createZeroAddress(), data: new Uint8Array(1), }, { common }, diff --git a/packages/util/examples/address.ts b/packages/util/examples/address.ts index 86362e4d44..853004f109 100644 --- a/packages/util/examples/address.ts +++ b/packages/util/examples/address.ts @@ -1,4 +1,4 @@ -import { Address } from '@ethereumjs/util' +import { createAddressFromString } from '@ethereumjs/util' -const address = Address.fromString('0x2f015c60e0be116b1f0cd534704db9c92118fb6a') +const address = createAddressFromString('0x2f015c60e0be116b1f0cd534704db9c92118fb6a') console.log(`Ethereum address ${address.toString()} created`) diff --git a/packages/util/examples/browser.html b/packages/util/examples/browser.html index 6d8fa69162..1f7436a9db 100644 --- a/packages/util/examples/browser.html +++ b/packages/util/examples/browser.html @@ -4,12 +4,12 @@ EthereumJS Browser Examples @@ -38,4 +38,4 @@

Interactive CLI

- \ No newline at end of file + diff --git a/packages/util/src/address.ts b/packages/util/src/address.ts index 2cb37d498e..795052e436 100644 --- a/packages/util/src/address.ts +++ b/packages/util/src/address.ts @@ -11,6 +11,7 @@ import { bytesToHex, equalsBytes, hexToBytes, + setLengthLeft, zeros, } from './bytes.js' import { BIGINT_0 } from './constants.js' @@ -30,76 +31,6 @@ export class Address { this.bytes = bytes } - /** - * Returns the zero address. - */ - static zero(): Address { - return new Address(zeros(20)) - } - - /** - * Returns an Address object from a hex-encoded string. - * @param str - Hex-encoded address - */ - static fromString(str: string): Address { - if (!isValidAddress(str)) { - throw new Error(`Invalid address input=${str}`) - } - return new Address(hexToBytes(str)) - } - - /** - * Returns an address for a given public key. - * @param pubKey The two points of an uncompressed key - */ - static fromPublicKey(pubKey: Uint8Array): Address { - if (!(pubKey instanceof Uint8Array)) { - throw new Error('Public key should be Uint8Array') - } - const bytes = pubToAddress(pubKey) - return new Address(bytes) - } - - /** - * Returns an address for a given private key. - * @param privateKey A private key must be 256 bits wide - */ - static fromPrivateKey(privateKey: Uint8Array): Address { - if (!(privateKey instanceof Uint8Array)) { - throw new Error('Private key should be Uint8Array') - } - const bytes = privateToAddress(privateKey) - return new Address(bytes) - } - - /** - * Generates an address for a newly created contract. - * @param from The address which is creating this new address - * @param nonce The nonce of the from account - */ - static generate(from: Address, nonce: bigint): Address { - if (typeof nonce !== 'bigint') { - throw new Error('Expected nonce to be a bigint') - } - return new Address(generateAddress(from.bytes, bigIntToBytes(nonce))) - } - - /** - * Generates an address for a contract created using CREATE2. - * @param from The address which is creating this new address - * @param salt A salt - * @param initCode The init code of the contract being created - */ - static generate2(from: Address, salt: Uint8Array, initCode: Uint8Array): Address { - if (!(salt instanceof Uint8Array)) { - throw new Error('Expected salt to be a Uint8Array') - } - if (!(initCode instanceof Uint8Array)) { - throw new Error('Expected initCode to be a Uint8Array') - } - return new Address(generateAddress2(from.bytes, salt, initCode)) - } - /** * Is address equal to another. */ @@ -111,7 +42,7 @@ export class Address { * Is address zero. */ isZero(): boolean { - return this.equals(Address.zero()) + return this.equals(new Address(zeros(20))) } /** @@ -139,3 +70,89 @@ export class Address { return new Uint8Array(this.bytes) } } + +/** + * Returns the zero address. + */ +export function createZeroAddress(): Address { + return new Address(zeros(20)) +} + +/** + * Returns an Address object from a bigint address (they are stored as bigints on the stack) + * @param value The bigint address + */ +export function createAddressFromBigInt(value: bigint): Address { + const bytes = bigIntToBytes(value) + if (bytes.length > 20) { + throw new Error(`Invalid address, too long: ${bytes.length}`) + } + return new Address(setLengthLeft(bytes, 20)) +} + +/** + * Returns an Address object from a hex-encoded string. + * @param str - Hex-encoded address + */ +export function createAddressFromString(str: string): Address { + if (!isValidAddress(str)) { + throw new Error(`Invalid address input=${str}`) + } + return new Address(hexToBytes(str)) +} + +/** + * Returns an address for a given public key. + * @param pubKey The two points of an uncompressed key + */ +export function createAddressFromPublicKey(pubKey: Uint8Array): Address { + if (!(pubKey instanceof Uint8Array)) { + throw new Error('Public key should be Uint8Array') + } + const bytes = pubToAddress(pubKey) + return new Address(bytes) +} + +/** + * Returns an address for a given private key. + * @param privateKey A private key must be 256 bits wide + */ +export function createAddressFromPrivateKey(privateKey: Uint8Array): Address { + if (!(privateKey instanceof Uint8Array)) { + throw new Error('Private key should be Uint8Array') + } + const bytes = privateToAddress(privateKey) + return new Address(bytes) +} + +/** + * Generates an address for a newly created contract. + * @param from The address which is creating this new address + * @param nonce The nonce of the from account + */ +export function createContractAddress(from: Address, nonce: bigint): Address { + if (typeof nonce !== 'bigint') { + throw new Error('Expected nonce to be a bigint') + } + return new Address(generateAddress(from.bytes, bigIntToBytes(nonce))) +} + +/** + * Generates an address for a contract created using CREATE2. + * @param from The address which is creating this new address + * @param salt A salt + * @param initCode The init code of the contract being created + */ +export function createContractAddress2( + from: Address, + salt: Uint8Array, + initCode: Uint8Array, +): Address { + if (!(salt instanceof Uint8Array)) { + throw new Error('Expected salt to be a Uint8Array') + } + if (!(initCode instanceof Uint8Array)) { + throw new Error('Expected initCode to be a Uint8Array') + } + return new Address(generateAddress2(from.bytes, salt, initCode)) +} diff --git a/packages/util/test/address.spec.ts b/packages/util/test/address.spec.ts index 05e57fa3e2..a0c3238db8 100644 --- a/packages/util/test/address.spec.ts +++ b/packages/util/test/address.spec.ts @@ -1,6 +1,18 @@ import { assert, describe, it } from 'vitest' -import { Address, equalsBytes, hexToBytes, toBytes } from '../src/index.js' +import { + Address, + createAddressFromBigInt, + createAddressFromPrivateKey, + createAddressFromPublicKey, + createAddressFromString, + createContractAddress, + createContractAddress2, + createZeroAddress, + equalsBytes, + hexToBytes, + toBytes, +} from '../src/index.js' import eip1014Testdata from './testdata/eip1014Examples.json' @@ -11,37 +23,48 @@ describe('Address', () => { it('should validate address length', () => { const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a11' - assert.throws(() => Address.fromString(str)) + assert.throws(() => createAddressFromString(str)) const shortStr = '0x2f015c60e0be116b1f0cd534704db9c92118fb' - assert.throws(() => Address.fromString(shortStr)) + assert.throws(() => createAddressFromString(shortStr)) const buf = toBytes(str) assert.throws(() => new Address(buf)) }) it('should generate a zero address', () => { - const addr = Address.zero() + const addr = createZeroAddress() assert.deepEqual(addr.bytes, toBytes(ZERO_ADDR_S)) assert.equal(addr.toString(), ZERO_ADDR_S) }) it('should instantiate address from zero address string', () => { - const addr = Address.fromString(ZERO_ADDR_S) + const addr = createAddressFromString(ZERO_ADDR_S) assert.deepEqual(addr.toString(), ZERO_ADDR_S) assert.ok(addr.isZero()) }) it('should detect non-zero address', () => { const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const addr = Address.fromString(str) + const addr = createAddressFromString(str) assert.notOk(addr.isZero()) }) + it('should create an address from a bigint', () => { + const addr = createAddressFromBigInt(BigInt(0)) + assert.ok(addr.isZero()) + const addr2 = createAddressFromBigInt(BigInt(1)) + assert.notOk(addr2.isZero()) + }) + + it('should throw if bigint is too long', () => { + assert.throws(() => createAddressFromBigInt(BigInt(2) ** BigInt(160))) + }) + it('should instantiate from public key', () => { const pubKey = hexToBytes( '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae7441e1d', ) const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const addr = Address.fromPublicKey(pubKey) + const addr = createAddressFromPublicKey(pubKey) assert.equal(addr.toString(), str) }) @@ -49,30 +72,30 @@ describe('Address', () => { const pubKey = hexToBytes( '0x3a443d8381a6798a70c6ff9304bdc8cb0163c23211d11628fae52ef9e0dca11a001cf066d56a8156fc201cd5df8a36ef694eecd258903fca7086c1fae744', ) - assert.throws(() => Address.fromPublicKey(pubKey)) + assert.throws(() => createAddressFromPublicKey(pubKey)) }) it('should instantiate from private key', () => { // prettier-ignore const privateKey = Uint8Array.from([234, 84, 189, 197, 45, 22, 63, 136, 201, 58, 176, 97, 87, 130, 207, 113, 138, 46, 251, 158, 81, 167, 152, 154, 171, 27, 8, 6, 126, 156, 28, 95]) const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const addr = Address.fromPrivateKey(privateKey) + const addr = createAddressFromPrivateKey(privateKey) assert.equal(addr.toString(), str) }) it('should generate address for created contract', () => { - const from = Address.fromString('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') - const addr = Address.generate(from, BigInt(14)) + const from = createAddressFromString('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') + const addr = createContractAddress(from, BigInt(14)) assert.equal(addr.toString(), '0xd658a4b8247c14868f3c512fa5cbb6e458e4a989') - const addr2 = Address.generate(from, BigInt(0)) + const addr2 = createContractAddress(from, BigInt(0)) assert.equal(addr2.toString(), '0xbfa69ba91385206bfdd2d8b9c1a5d6c10097a85b') }) it('should provide correct precompile check', () => { - const precompile = Address.fromString('0x0000000000000000000000000000000000000009') + const precompile = createAddressFromString('0x0000000000000000000000000000000000000009') assert.isTrue(precompile.isPrecompileOrSystemAddress(), 'should detect precompile address') - const nonPrecompile = Address.fromString('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') + const nonPrecompile = createAddressFromString('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') assert.isFalse( nonPrecompile.isPrecompileOrSystemAddress(), 'should detect non-precompile address', @@ -82,8 +105,8 @@ describe('Address', () => { it('should generate address for CREATE2', () => { for (const testdata of eip1014Testdata) { const { address, salt, initCode, result } = testdata - const from = Address.fromString(address) - const addr = Address.generate2( + const from = createAddressFromString(address) + const addr = createContractAddress2( from, hexToBytes(salt as PrefixedHexString), hexToBytes(initCode as PrefixedHexString), @@ -94,7 +117,7 @@ describe('Address', () => { it('should provide a Uint8Array that does not mutate the original address', () => { const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const address = Address.fromString(str) + const address = createAddressFromString(str) const addressBytes = address.toBytes() addressBytes.fill(0) assert.equal(address.toString(), str) @@ -102,19 +125,19 @@ describe('Address', () => { it('should compare equality properly', () => { const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const address1 = Address.fromString(str) + const address1 = createAddressFromString(str) const address2 = new Address(hexToBytes(str)) assert.ok(address1.equals(address2)) assert.ok(equalsBytes(address1.bytes, address2.bytes)) const str2 = '0xcd4EC7b66fbc029C116BA9Ffb3e59351c20B5B06' - const address3 = Address.fromString(str2) + const address3 = createAddressFromString(str2) assert.ok(!address1.equals(address3)) - const address3LowerCase = Address.fromString(str2.toLowerCase()) + const address3LowerCase = createAddressFromString(str2.toLowerCase()) assert.ok(address3.equals(address3LowerCase)) - const address4 = Address.zero() + const address4 = createZeroAddress() assert.ok(!address1.equals(address4)) }) }) diff --git a/packages/util/test/bytes.spec.ts b/packages/util/test/bytes.spec.ts index f08ce15ea3..cf031f98af 100644 --- a/packages/util/test/bytes.spec.ts +++ b/packages/util/test/bytes.spec.ts @@ -1,7 +1,6 @@ import { assert, describe, it } from 'vitest' import { - Address, addHexPrefix, bigIntToAddressBytes, bigIntToBytes, @@ -10,6 +9,7 @@ import { bytesToBigInt, bytesToHex, bytesToInt, + createAddressFromString, equalsBytes, fromSigned, hexToBytes, @@ -262,7 +262,7 @@ describe('toBytes', () => { it('should convert a TransformabletoBytes like the Address class (i.e. provides a toBytes method)', () => { const str = '0x2f015c60e0be116b1f0cd534704db9c92118fb6a' - const address = Address.fromString(str) + const address = createAddressFromString(str) const addressBytes = toBytes(address) assert.deepEqual(addressBytes, address.toBytes()) }) @@ -423,10 +423,10 @@ describe('bigIntToAddressBytes', () => { for (const [addressHex, addressBigInt, isSafe] of testCases) { it('should correctly convert', () => { - const addressHexFromBigInt = bytesToHex(bigIntToAddressBytes(addressBigInt, false)) + const addressHexFromBigInt = bytesToHex(bigIntToAddressBytes(addressBigInt as bigint, false)) assert.equal(addressHex, addressHexFromBigInt, `should correctly convert ${addressBigInt}`) if (isSafe === false) { - assert.throw(() => bigIntToAddressBytes(addressBigInt)) + assert.throw(() => bigIntToAddressBytes(addressBigInt as bigint)) } }) } diff --git a/packages/util/test/verkle.spec.ts b/packages/util/test/verkle.spec.ts index 8eed055405..8fef2d35bb 100644 --- a/packages/util/test/verkle.spec.ts +++ b/packages/util/test/verkle.spec.ts @@ -3,12 +3,12 @@ import { assert, beforeAll, describe, it } from 'vitest' import * as verkleBlockJSON from '../../statemanager/test/testdata/verkleKaustinen6Block72.json' import { - Address, type VerkleCrypto, type VerkleExecutionWitness, VerkleLeafType, bytesToHex, concatBytes, + createAddressFromString, getVerkleKey, getVerkleStem, hexToBytes, @@ -27,7 +27,10 @@ describe('Verkle cryptographic helpers', () => { // Empty address assert.equal( bytesToHex( - getVerkleStem(verkle, Address.fromString('0x0000000000000000000000000000000000000000')), + getVerkleStem( + verkle, + createAddressFromString('0x0000000000000000000000000000000000000000'), + ), ), '0x1a100684fd68185060405f3f160e4bb6e034194336b547bdae323f888d5332', ) @@ -35,7 +38,10 @@ describe('Verkle cryptographic helpers', () => { // Non-empty address assert.equal( bytesToHex( - getVerkleStem(verkle, Address.fromString('0x71562b71999873DB5b286dF957af199Ec94617f7')), + getVerkleStem( + verkle, + createAddressFromString('0x71562b71999873DB5b286dF957af199Ec94617f7'), + ), ), '0x1540dfad7755b40be0768c6aa0a5096fbf0215e0e8cf354dd928a178346466', ) diff --git a/packages/vm/examples/browser.html b/packages/vm/examples/browser.html index 0173d56d77..dabeeedc98 100644 --- a/packages/vm/examples/browser.html +++ b/packages/vm/examples/browser.html @@ -4,7 +4,7 @@ EthereumJS Browser Examples