From e418c176a91f35fbe36cb06528a6b96aed152c4f Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sat, 27 Apr 2024 19:25:04 -0700 Subject: [PATCH] monorepo: revert and adjust some prefixedHexTypes (#3382) --- packages/block/src/block.ts | 13 +- packages/block/src/types.ts | 168 +++++++++--------- .../client/src/rpc/modules/engine/engine.ts | 31 +++- .../src/rpc/modules/engine/util/newPayload.ts | 6 +- .../client/test/net/peer/rlpxpeer.spec.ts | 2 +- packages/client/test/sync/txpool.spec.ts | 2 +- packages/common/src/types.ts | 22 +-- packages/util/src/bytes.ts | 2 + packages/util/test/types.spec.ts | 1 - .../EIPs/eip-3540-evm-object-format.spec.ts | 4 +- packages/vm/test/api/runBlock.spec.ts | 4 +- 11 files changed, 141 insertions(+), 114 deletions(-) diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 3f1fb972e3..27c2340455 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -41,7 +41,7 @@ import type { TxOptions, TypedTransaction, } from '@ethereumjs/tx' -import type { EthersProvider, WithdrawalBytes } from '@ethereumjs/util' +import type { EthersProvider, PrefixedHexString, WithdrawalBytes } from '@ethereumjs/util' /** * An object that represents the block. @@ -340,9 +340,12 @@ export class Block { const txs = [] for (const [index, serializedTx] of transactions.entries()) { try { - const tx = TransactionFactory.fromSerializedData(hexToBytes(serializedTx), { - common: opts?.common, - }) + const tx = TransactionFactory.fromSerializedData( + hexToBytes(serializedTx as PrefixedHexString), + { + common: opts?.common, + } + ) txs.push(tx) } catch (error) { const validationError = `Invalid tx at index ${index}: ${error}` @@ -380,7 +383,7 @@ export class Block { throw Error('Missing executionWitness for EIP-6800 activated executionPayload') } // Verify blockHash matches payload - if (!equalsBytes(block.hash(), hexToBytes(payload.blockHash))) { + if (!equalsBytes(block.hash(), hexToBytes(payload.blockHash as PrefixedHexString))) { const validationError = `Invalid blockHash, expected: ${ payload.blockHash }, received: ${bytesToHex(block.hash())}` diff --git a/packages/block/src/types.ts b/packages/block/src/types.ts index b2a50b104e..26d36bc864 100644 --- a/packages/block/src/types.ts +++ b/packages/block/src/types.ts @@ -115,27 +115,28 @@ export interface VerkleExecutionWitness { /** * A block header's data. */ +// TODO: Deprecate the string type and only keep BytesLike/AddressLike/BigIntLike export interface HeaderData { - 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 + 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 } /** @@ -197,59 +198,61 @@ 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 - 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 + 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 } /* * 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 // the block number. null when pending block. - hash: PrefixedHexString // hash of the block. null when pending 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. null when pending block. - sha3Uncles: PrefixedHexString // SHA3 of the uncles data in the block. - logsBloom: PrefixedHexString // the bloom filter for the logs of the block. null when pending 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 + 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 withdrawals?: Array // If EIP-4895 is enabled for this block, array of withdrawals - 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 + 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 executionWitness?: VerkleExecutionWitness | null // If Verkle is enabled for this block } @@ -261,25 +264,26 @@ export type WithdrawalV1 = { } // Note: all these strings are 0x-prefixed +// TODO: Remove the string type and only keep PrefixedHexString export type ExecutionPayload = { - 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, + 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, withdrawals?: WithdrawalV1[] // Array of withdrawal objects - blobGasUsed?: PrefixedHexString // QUANTITY, 64 Bits - excessBlobGas?: PrefixedHexString // QUANTITY, 64 Bits - parentBeaconBlockRoot?: PrefixedHexString // QUANTITY, 64 Bits + blobGasUsed?: PrefixedHexString | string // QUANTITY, 64 Bits + excessBlobGas?: PrefixedHexString | string // QUANTITY, 64 Bits + parentBeaconBlockRoot?: PrefixedHexString | string // QUANTITY, 64 Bits // VerkleExecutionWitness is already a hex serialized object executionWitness?: VerkleExecutionWitness | null // QUANTITY, 64 Bits, null implies not available } diff --git a/packages/client/src/rpc/modules/engine/engine.ts b/packages/client/src/rpc/modules/engine/engine.ts index f5926d899e..4c853d0c5e 100644 --- a/packages/client/src/rpc/modules/engine/engine.ts +++ b/packages/client/src/rpc/modules/engine/engine.ts @@ -69,6 +69,7 @@ import type { TransitionConfigurationV1, } from './types.js' import type { Block, ExecutionPayload } from '@ethereumjs/block' +import type { PrefixedHexString } from '@ethereumjs/util' import type { VM } from '@ethereumjs/vm' const zeroBlockHash = zeros(32) @@ -369,7 +370,11 @@ export class Engine { if (!response) { const validationError = `Error assembling block from payload during initialization` this.config.logger.debug(validationError) - const latestValidHash = await validHash(hexToBytes(parentHash), this.chain, this.chainCache) + const latestValidHash = await validHash( + hexToBytes(parentHash as PrefixedHexString), + this.chain, + this.chainCache + ) response = { status: Status.INVALID, latestValidHash, validationError } } // skip marking the block invalid as this is more of a data issue from CL @@ -390,14 +395,22 @@ export class Engine { // if there was a validation error return invalid if (validationError !== null) { this.config.logger.debug(validationError) - const latestValidHash = await validHash(hexToBytes(parentHash), this.chain, this.chainCache) + const latestValidHash = await validHash( + hexToBytes(parentHash as PrefixedHexString), + this.chain, + this.chainCache + ) const response = { status: Status.INVALID, latestValidHash, validationError } // skip marking the block invalid as this is more of a data issue from CL return response } } else if (blobVersionedHashes !== undefined && blobVersionedHashes !== null) { const validationError = `Invalid blobVersionedHashes before EIP-4844 is activated` - const latestValidHash = await validHash(hexToBytes(parentHash), this.chain, this.chainCache) + const latestValidHash = await validHash( + hexToBytes(parentHash as PrefixedHexString), + this.chain, + this.chainCache + ) const response = { status: Status.INVALID, latestValidHash, validationError } // skip marking the block invalid as this is more of a data issue from CL return response @@ -423,9 +436,9 @@ export class Engine { * to run basic validations based on parent */ const parent = - (await this.skeleton.getBlockByHash(hexToBytes(parentHash), true)) ?? + (await this.skeleton.getBlockByHash(hexToBytes(parentHash as PrefixedHexString), true)) ?? this.remoteBlocks.get(parentHash.slice(2)) ?? - (await this.chain.getBlock(hexToBytes(parentHash))) + (await this.chain.getBlock(hexToBytes(parentHash as PrefixedHexString))) // Validations with parent if (!parent.common.gteHardfork(Hardfork.Paris)) { @@ -454,7 +467,7 @@ export class Engine { } catch (error: any) { const validationError = `Invalid 4844 transactions: ${error}` const latestValidHash = await validHash( - hexToBytes(parentHash), + hexToBytes(parentHash as PrefixedHexString), this.chain, this.chainCache ) @@ -469,7 +482,7 @@ export class Engine { */ const executedParentExists = this.executedBlocks.get(parentHash.slice(2)) ?? - (await validExecutedChainBlock(hexToBytes(parentHash), this.chain)) + (await validExecutedChainBlock(hexToBytes(parentHash as PrefixedHexString), this.chain)) // If the parent is not executed throw an error, it will be caught and return SYNCING or ACCEPTED. if (!executedParentExists) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) @@ -575,11 +588,11 @@ export class Engine { // some pre-executed stateroot can be sent const executedBlockExists = this.executedBlocks.get(blockHash.slice(2)) ?? - (await validExecutedChainBlock(hexToBytes(blockHash), this.chain)) + (await validExecutedChainBlock(hexToBytes(blockHash as PrefixedHexString), this.chain)) if (executedBlockExists) { const response = { status: Status.VALID, - latestValidHash: blockHash, + latestValidHash: blockHash as PrefixedHexString, validationError: null, } return response diff --git a/packages/client/src/rpc/modules/engine/util/newPayload.ts b/packages/client/src/rpc/modules/engine/util/newPayload.ts index e257d2562e..6e15109515 100644 --- a/packages/client/src/rpc/modules/engine/util/newPayload.ts +++ b/packages/client/src/rpc/modules/engine/util/newPayload.ts @@ -41,7 +41,11 @@ export const assembleBlock = async ( } catch (error) { const validationError = `Error assembling block from payload: ${error}` config.logger.error(validationError) - const latestValidHash = await validHash(hexToBytes(payload.parentHash), chain, chainCache) + const latestValidHash = await validHash( + hexToBytes(payload.parentHash as PrefixedHexString), + chain, + chainCache + ) const response = { status: `${error}`.includes('Invalid blockHash') ? Status.INVALID_BLOCK_HASH : Status.INVALID, latestValidHash, diff --git a/packages/client/test/net/peer/rlpxpeer.spec.ts b/packages/client/test/net/peer/rlpxpeer.spec.ts index 4e11d980e2..e664039871 100644 --- a/packages/client/test/net/peer/rlpxpeer.spec.ts +++ b/packages/client/test/net/peer/rlpxpeer.spec.ts @@ -20,7 +20,7 @@ describe('[RlpxPeer]', async () => { } }) - const { RlpxPeer } = await import('../../../src/net/peer/rlpxpeer') + const { RlpxPeer } = await import('../../../src/net/peer/rlpxpeer.js') it('should initialize correctly', async () => { const config = new Config({ accountCache: 10000, storageCache: 1000 }) diff --git a/packages/client/test/sync/txpool.spec.ts b/packages/client/test/sync/txpool.spec.ts index 263264c85b..17c14f97e5 100644 --- a/packages/client/test/sync/txpool.spec.ts +++ b/packages/client/test/sync/txpool.spec.ts @@ -20,7 +20,7 @@ import { getLogger } from '../../src/logging.js' import { PeerPool } from '../../src/net/peerpool.js' import { TxPool } from '../../src/service/txpool.js' -import type { PrometheusMetrics } from '../../src/types' +import type { PrometheusMetrics } from '../../src/types.js' let prometheusMetrics: PrometheusMetrics | undefined diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 1cb7263a73..18456ee825 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -40,14 +40,15 @@ export interface ChainConfig { consensus: ConsensusConfig } +// TODO: Remove the string type and only keep PrefixedHexString export interface GenesisBlockConfig { - timestamp?: PrefixedHexString - gasLimit: number | PrefixedHexString - difficulty: number | PrefixedHexString - nonce: PrefixedHexString - extraData: PrefixedHexString - baseFeePerGas?: PrefixedHexString - excessBlobGas?: PrefixedHexString + timestamp?: PrefixedHexString | string + gasLimit: number | PrefixedHexString | string + difficulty: number | PrefixedHexString | string + nonce: PrefixedHexString | string + extraData: PrefixedHexString | string + baseFeePerGas?: PrefixedHexString | string + excessBlobGas?: PrefixedHexString | string } export interface HardforkTransitionConfig { @@ -157,10 +158,11 @@ export interface GethConfigOpts extends BaseOpts { mergeForkIdPostMerge?: boolean } +// TODO: Deprecate the string type and only keep BigIntLike export interface HardforkByOpts { - blockNumber?: BigIntLike - timestamp?: BigIntLike - td?: BigIntLike + blockNumber?: BigIntLike | string + timestamp?: BigIntLike | string + td?: BigIntLike | string } type ParamDict = { diff --git a/packages/util/src/bytes.ts b/packages/util/src/bytes.ts index 8405280300..28ddbda90e 100644 --- a/packages/util/src/bytes.ts +++ b/packages/util/src/bytes.ts @@ -266,8 +266,10 @@ export const unpadHex = (a: PrefixedHexString): PrefixedHexString => { return `0x${stripZeros(stripHexPrefix(a))}` } +// TODO: remove the string type from this function (only keep PrefixedHexString) export type ToBytesInputTypes = | PrefixedHexString + | string | number | bigint | Uint8Array diff --git a/packages/util/test/types.spec.ts b/packages/util/test/types.spec.ts index 6711d4bd1f..38a4adf3d8 100644 --- a/packages/util/test/types.spec.ts +++ b/packages/util/test/types.spec.ts @@ -94,7 +94,6 @@ describe('toType', () => { assert.deepEqual(result, toBytes(num)) assert.throws(() => { - // @ts-expect-error toType('1', TypeOutput.Number) }, /^A string must be provided with a 0x-prefix, given: 1$/) }) 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 index f5fefd1dfd..5100ececc9 100644 --- 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 @@ -150,11 +150,11 @@ const create2offset = '15' const CREATE2Deploy = `0x600060${create2offset}380360${create2offset}60003960${create2offset}380360006000F500` function deployCreateCode(initcode: string): PrefixedHexString { - return `${CREATEDeploy}${initcode}` + return `${CREATEDeploy}${initcode}` as PrefixedHexString } function deployCreate2Code(initcode: string): PrefixedHexString { - return `${CREATE2Deploy}${initcode}` + return `${CREATE2Deploy}${initcode}` as PrefixedHexString } describe('ensure invalid EOF initcode in EIP-3540 does not consume all gas', () => { diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index deaec2f569..cdb20bac54 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -461,11 +461,11 @@ describe('runBlock() -> tx types', async () => { const blockRlp = hexToBytes(testData.blocks[0].rlp as PrefixedHexString) const block = Block.fromRLPSerializedBlock(blockRlp, { common, freeze: false }) - //@e transactions + //@ts-ignore read-only property block.transactions = transactions if (transactions.some((t) => t.supports(Capability.EIP1559FeeMarket))) { - // @e read-only property + // @ts-ignore read-only property block.header.baseFeePerGas = BigInt(7) }