Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ Feat: Upgrade to ethereumjs alpha.1 #1486

Open
wants to merge 9 commits into
base: 11-01-_recycle_feat_reset_storage_slot_if_more_than_one_is_found
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extensions/viem/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"@tevm/node": "workspace:^"
},
"devDependencies": {
"@ethereumjs/util": "^9.1.0",
"@ethereumjs/util": "^10.0.0-alpha.1",
"@tevm/actions": "workspace:^",
"@tevm/client-types": "workspace:^",
"@tevm/common": "workspace:^",
Expand Down
8 changes: 4 additions & 4 deletions packages/actions/src/Contract/createScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,18 @@ export const createScript = async (client, code, deployedBytecode, to) => {
const dataFee = (() => {
let out = 0n
for (const entry of hexToBytes(code) ?? []) {
out += vm.common.ethjsCommon.param('gasPrices', entry === 0 ? 'txDataZero' : 'txDataNonZero')
out += vm.common.vmConfig.param('gasPrices', entry === 0 ? 'txDataZero' : 'txDataNonZero')
}
return out
})()
const baseFee = (() => {
let out = dataFee
const txFee = vm.common.ethjsCommon.param('gasPrices', 'tx')
const txFee = vm.common.vmConfig.param('gasPrices', 'tx')
if (txFee) {
out += txFee
}
if (vm.common.ethjsCommon.gteHardfork('homestead')) {
const txCreationFee = vm.common.ethjsCommon.param('gasPrices', 'txCreation')
if (vm.common.vmConfig.gteHardfork('homestead')) {
const txCreationFee = vm.common.vmConfig.param('gasPrices', 'txCreation')
if (txCreationFee) {
out += txCreationFee
}
Expand Down
12 changes: 6 additions & 6 deletions packages/actions/src/CreateTransaction/createTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { maybeThrowOnFail } from '../internal/maybeThrowOnFail.js'

// TODO tevm_call should optionally take a signature too
// When it takes a real signature (like in case of eth.sendRawTransaction) we should
// use FeeMarketEIP1559Transaction rather than Impersonated
// use FeeMarket1559Transaction rather than Impersonated
const requireSig = false

/**
Expand Down Expand Up @@ -47,20 +47,20 @@ export const createTransaction = (client, defaultThrowOnFail = true) => {
const dataFee = (() => {
let out = 0n
for (const entry of evmInput.data ?? []) {
out += vm.common.ethjsCommon.param('gasPrices', entry === 0 ? 'txDataZero' : 'txDataNonZero')
out += vm.common.vmConfig.param('gasPrices', entry === 0 ? 'txDataZero' : 'txDataNonZero')
}
return out
})()

const baseFee = (() => {
let out = dataFee
const txFee = vm.common.ethjsCommon.param('gasPrices', 'tx')
const txFee = vm.common.vmConfig.param('gasPrices', 'tx')
if (txFee) {
out += txFee
}
const isCreation = (evmInput.to?.bytes.length ?? 0) === 0
if (vm.common.ethjsCommon.gteHardfork('homestead') && isCreation) {
const txCreationFee = vm.common.ethjsCommon.param('gasPrices', 'txCreation')
if (vm.common.vmConfig.gteHardfork('homestead') && isCreation) {
const txCreationFee = vm.common.vmConfig.param('gasPrices', 'txCreation')
if (txCreationFee) {
out += txCreationFee
}
Expand Down Expand Up @@ -109,7 +109,7 @@ export const createTransaction = (client, defaultThrowOnFail = true) => {
},
{
allowUnlimitedInitCodeSize: false,
common: vm.common.ethjsCommon,
common: vm.common.vmConfig,
// we don't want to freeze because there is a hack to set tx.hash when building a block
freeze: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const debugTraceTransactionJsonRpcProcedure = (client) => {
skipBlockGasLimitValidation: true,
tx: await TransactionFactory.fromRPC(tx, {
freeze: false,
common: vmClone.common.ethjsCommon,
common: vmClone.common.vmConfig,
allowUnlimitedInitCodeSize: true,
}),
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { hexToBytes, hexToNumber } from '@tevm/utils'
import { txToJsonRpcTx } from '../utils/txToJsonRpcTx.js'
import { txToJSONRPCTx } from '../utils/txToJSONRPCTx.js'

/**
* Request handler for eth_getTransactionByBlockHashAndIndex JSON-RPC requests.
Expand All @@ -25,7 +25,7 @@ export const ethGetTransactionByBlockHashAndIndexJsonRpcProcedure = (client) =>
}
return {
method: request.method,
result: txToJsonRpcTx(tx, block, txIndex),
result: txToJSONRPCTx(tx, block, txIndex),
jsonrpc: '2.0',
...(request.id ? { id: request.id } : {}),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { hexToBigInt, hexToNumber } from '@tevm/utils'
import { txToJsonRpcTx } from '../utils/txToJsonRpcTx.js'
import { txToJSONRPCTx } from '../utils/txToJSONRPCTx.js'

/**
* Request handler for eth_getTransactionByBlockNumberAndIndex JSON-RPC requests.
Expand Down Expand Up @@ -42,7 +42,7 @@ export const ethGetTransactionByBlockNumberAndIndexJsonRpcProcedure = (client) =
}
return {
method: request.method,
result: txToJsonRpcTx(tx, block, txIndex),
result: txToJSONRPCTx(tx, block, txIndex),
jsonrpc: '2.0',
...(request.id ? { id: request.id } : {}),
}
Expand Down
4 changes: 2 additions & 2 deletions packages/actions/src/eth/ethGetTransactionByHashProcedure.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createJsonRpcFetcher } from '@tevm/jsonrpc'
import { hexToBytes } from '@tevm/utils'
import { txToJsonRpcTx } from '../utils/txToJsonRpcTx.js'
import { txToJSONRPCTx } from '../utils/txToJSONRPCTx.js'

/**
* Request handler for eth_getTransactionByHash JSON-RPC requests.
Expand Down Expand Up @@ -62,7 +62,7 @@ export const ethGetTransactionByHashJsonRpcProcedure = (client) => {
}
return {
method: request.method,
result: txToJsonRpcTx(tx, block, txIndex),
result: txToJSONRPCTx(tx, block, txIndex),
jsonrpc: '2.0',
...(request.id ? { id: request.id } : {}),
}
Expand Down
2 changes: 1 addition & 1 deletion packages/actions/src/eth/ethGetTransactionReceipt.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const ethGetTransactionReceiptHandler = (client) => async (params) => {
? /** @type any*/ (tx).maxPriorityFeePerGas
: /** @type any*/ (tx).maxFeePerGas - (block.header.baseFeePerGas ?? 0n) + (block.header.baseFeePerGas ?? 0n)

vm.common.ethjsCommon.setHardfork(tx.common.hardfork())
vm.common.vmConfig.setHardfork(tx.common.hardfork())
await vm.stateManager.setStateRoot(parentBlock.header.stateRoot)
// Run tx through copied vm to get tx gasUsed and createdAddress
const runBlockResult = await vm.runBlock({
Expand Down
8 changes: 4 additions & 4 deletions packages/actions/src/eth/ethSendRawTransaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('ethSendRawTransactionHandler', () => {
data: '0x',
type: 2,
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const signedTx = tx.sign(hexToBytes(PREFUNDED_PRIVATE_KEYS[0]))
Expand Down Expand Up @@ -62,7 +62,7 @@ describe('ethSendRawTransactionHandler', () => {
data: '0x',
type: 0,
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const signedTx = tx.sign(hexToBytes(PREFUNDED_PRIVATE_KEYS[0]))
Expand Down Expand Up @@ -94,7 +94,7 @@ describe('ethSendRawTransactionHandler', () => {
data: '0x',
type: 2,
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const serializedTx = tx.serialize()
Expand Down Expand Up @@ -141,7 +141,7 @@ describe('ethSendRawTransactionHandler', () => {
kzgCommitments: [mockKZGCommitment1, mockKZGCommitment2],
kzgProofs: [new Uint8Array(48).fill(1), new Uint8Array(48).fill(2)],
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const signedTx = blobTx.sign(hexToBytes(PREFUNDED_PRIVATE_KEYS[0]))
Expand Down
8 changes: 4 additions & 4 deletions packages/actions/src/eth/ethSendRawTransactionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ const getTx = (vm, txBuf) => {
case txType.ACCESS_LIST:
case txType.EIP1559:
return TransactionFactory.fromSerializedData(txBuf, {
common: vm.common.ethjsCommon,
common: vm.common.vmConfig,
freeze: false,
})
case txType.BLOB: {
const tx = BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txBuf, {
common: vm.common.ethjsCommon,
common: vm.common.vmConfig,
freeze: false,
})
const blobGasLimit = vm.common.ethjsCommon.param('gasConfig', 'maxblobGasPerBlock')
const blobGasPerBlob = vm.common.ethjsCommon.param('gasConfig', 'blobGasPerBlob')
const blobGasLimit = vm.common.vmConfig.param('gasConfig', 'maxblobGasPerBlock')
const blobGasPerBlob = vm.common.vmConfig.param('gasConfig', 'blobGasPerBlob')

const blobCount = BigInt(tx.blobs?.length ?? 0)
const blobGas = blobCount * blobGasPerBlob
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('ethSendRawTransactionJsonRpcProcedure', () => {
data: '0x',
type: 2,
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const signedTx = tx.sign(hexToBytes(PREFUNDED_PRIVATE_KEYS[0]))
Expand Down Expand Up @@ -52,7 +52,7 @@ describe('ethSendRawTransactionJsonRpcProcedure', () => {
data: '0x',
type: 0,
},
{ common: tevmDefault.ethjsCommon },
{ common: tevmDefault.vmConfig },
)

const signedTx = tx.sign(hexToBytes(PREFUNDED_PRIVATE_KEYS[0]))
Expand Down
4 changes: 2 additions & 2 deletions packages/actions/src/eth/ethSendRawTransactionProcedure.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const ethSendRawTransactionJsonRpcProcedure = (client) => {
// Blob Transactions sent over RPC are expected to be in Network Wrapper format
const tx =
txBuf[0] === 0x03
? BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txBuf, { common: vm.common.ethjsCommon })
: TransactionFactory.fromSerializedData(txBuf, { common: vm.common.ethjsCommon })
? BlobEIP4844Transaction.fromSerializedBlobTxNetworkWrapper(txBuf, { common: vm.common.vmConfig })
: TransactionFactory.fromSerializedData(txBuf, { common: vm.common.vmConfig })
if (!tx.isSigned()) {
const err = new InvalidParamsError('Transaction must be signed!')
return {
Expand Down
4 changes: 2 additions & 2 deletions packages/actions/src/eth/ethSendTransactionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const ethSendTransactionHandler = (client) => async (params) => {
const impersonatedAccount = client.getImpersonatedAccount()
if (!tx.isSigned() && impersonatedAccount !== undefined) {
/**
* @type {import("@tevm/tx").FeeMarketEIP1559Transaction & {impersonatedAddress: import('@tevm/utils').EthjsAddress} }
* @type {import("@tevm/tx").FeeMarket1559Transaction & {impersonatedAddress: import('@tevm/utils').EthjsAddress} }
**/
const impersonatedTx = /** @type {any}*/ (tx)
impersonatedTx.impersonatedAddress = createAddress(impersonatedAccount)
Expand All @@ -31,7 +31,7 @@ export const ethSendTransactionHandler = (client) => async (params) => {
'Raw Transaction is not signed. Consider calling impersonate endpoint. In future versions unsigned transactions will be rejected.',
)
/**
* @type {import("@tevm/tx").FeeMarketEIP1559Transaction & {impersonatedAddress: EthjsAddress} }
* @type {import("@tevm/tx").FeeMarket1559Transaction & {impersonatedAddress: EthjsAddress} }
**/
const impersonatedTx = /** @type {any}*/ (tx)
impersonatedTx.impersonatedAddress = createAddress(
Expand Down
2 changes: 1 addition & 1 deletion packages/actions/src/internal/evmInputToImpersonatedTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const evmInputToImpersonatedTx = (client) => {
},
{
allowUnlimitedInitCodeSize: false,
common: vm.common.ethjsCommon,
common: vm.common.vmConfig,
// we don't want to freeze because there is a hack to set tx.hash when building a block
freeze: false,
},
Expand Down
4 changes: 2 additions & 2 deletions packages/actions/src/utils/blockToJsonRpcBlock.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { bytesToHex, numberToHex, toBytes } from '@tevm/utils'
import { txToJsonRpcTx } from './txToJsonRpcTx.js'
import { txToJSONRPCTx } from './txToJSONRPCTx.js'

/**
* @param {import('@tevm/block').Block} block
Expand All @@ -10,7 +10,7 @@ export const blockToJsonRpcBlock = async (block, includeTransactions) => {
const json = block.toJSON()
const header = /** @type {import('@tevm/block').JsonHeader}*/ (json.header)
const transactions = block.transactions.map((tx, txIndex) =>
includeTransactions ? txToJsonRpcTx(tx, block, txIndex) : bytesToHex(tx.hash()),
includeTransactions ? txToJSONRPCTx(tx, block, txIndex) : bytesToHex(tx.hash()),
)

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/actions/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export * from './SerializeToJson.js'
export * from './blockToJsonRpcBlock.js'
export * from './generateRandomId.js'
export * from './parseBlockTag.js'
export * from './txToJsonRpcTx.js'
export * from './txToJSONRPCTx.js'
2 changes: 1 addition & 1 deletion packages/actions/src/utils/txToJsonRpcTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { bytesToHex, numberToHex } from '@tevm/utils'
* @param {number} [txIndex]
* @returns {import('../common/TransactionResult.js').TransactionResult}
*/
export const txToJsonRpcTx = (tx, block, txIndex) => {
export const txToJSONRPCTx = (tx, block, txIndex) => {
const txJSON = tx.toJSON()
// TODO make this typing less janky
return /** @type any*/ ({
Expand Down
10 changes: 5 additions & 5 deletions packages/actions/src/utils/txToJsonRpcTx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { getBlockFromRpc } from '@tevm/blockchain'
import { optimism } from '@tevm/common'
import { createTevmNode } from '@tevm/node'
import { transports } from '@tevm/test-utils'
import { FeeMarketEIP1559Transaction } from '@tevm/tx'
import { FeeMarket1559Transaction } from '@tevm/tx'
import { EthjsAddress } from '@tevm/utils'
import { describe, expect, it } from 'vitest'
import { txToJsonRpcTx } from './txToJsonRpcTx.js'
import { txToJSONRPCTx } from './txToJSONRPCTx.js'

describe(txToJsonRpcTx.name, () => {
describe(txToJSONRPCTx.name, () => {
it('should work', async () => {
const tx = new FeeMarketEIP1559Transaction({
const tx = new FeeMarket1559Transaction({
to: EthjsAddress.fromString(`0x${'a'.repeat(40)}`),
data: Uint8Array.from([1, 2, 3]),
value: 100n,
Expand All @@ -31,6 +31,6 @@ describe(txToJsonRpcTx.name, () => {
{ blockTag: 121960766n, transport: transports.optimism },
vm.common,
)
expect(txToJsonRpcTx(tx, block, 0)).toMatchSnapshot()
expect(txToJSONRPCTx(tx, block, 0)).toMatchSnapshot()
})
})
4 changes: 2 additions & 2 deletions packages/address/src/create2ContractAddress.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { create2ContractAddress } from './create2ContractAddress.js'

describe('create2ContractAddress', () => {
it('should create a valid contract address using CREATE2', () => {
const from = EthjsAddress.fromString(`0x${'11'.repeat(20)}`)
const from = new EthjsAddress(hexToBytes(`0x${'11'.repeat(20)}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Remaining instances of EthjsAddress.fromString found.

Multiple files still utilize EthjsAddress.fromString, indicating that the update is not fully applied. Please ensure all instances are refactored to maintain consistency.

🔗 Analysis chain

LGTM! Verify similar changes across the codebase.

The update to the EthjsAddress instantiation looks good. It uses the constructor directly with hexToBytes, which is a more straightforward approach.

To ensure consistency, let's verify if similar changes have been made throughout the codebase:


Action Required: Update the search command to correctly target TypeScript files.


Action Required: Update the search command to target .ts and .tsx files using glob patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of EthjsAddress.fromString
# Expect: No results, indicating all instances have been updated

rg --type typescript "EthjsAddress\.fromString"

Length of output: 84


Script:

#!/bin/bash
# Description: Check for any remaining instances of EthjsAddress.fromString in .ts and .tsx files
# Expect: No results, indicating all instances have been updated

rg "EthjsAddress\.fromString" --type-add 'ts:*.{ts,tsx}' -t ts -t tsx

Length of output: 99


Script:

#!/bin/bash
# Description: Check for any remaining instances of EthjsAddress.fromString in .ts and .tsx files
# Expect: No results, indicating all instances have been updated

rg "EthjsAddress\.fromString" --glob "*.ts" --glob "*.tsx"

Length of output: 15386

const salt = `0x${'00'.repeat(32)}` as const
const code = `0x${'60'.repeat(10)}` as const
const expectedAddress = keccak256(
Expand All @@ -21,7 +21,7 @@ describe('create2ContractAddress', () => {
})

it('should throw InvalidSaltError if salt is not 32 bytes', () => {
const from = EthjsAddress.fromString(`0x${'11'.repeat(20)}`)
const from = new EthjsAddress(hexToBytes(`0x${'11'.repeat(20)}`))
const invalidSalt = `0x${'00'.repeat(16)}` as const
const code = `0x${'60'.repeat(10)}` as const

Expand Down
8 changes: 4 additions & 4 deletions packages/address/src/createContractAddress.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { InvalidAddressError } from '@tevm/errors'
import { EthjsAddress, keccak256, toRlp } from '@tevm/utils'
import { numberToBytes } from 'viem'
import { keccak256, toRlp } from '@tevm/utils'
import { hexToBytes, numberToBytes } from 'viem'
import { describe, expect, it } from 'vitest'
import { Address } from './Address.js'
import { createContractAddress } from './createContractAddress.js'

describe('createContractAddress', () => {
it('should create a valid contract address with nonce 0', () => {
const from = EthjsAddress.fromString(`0x${'11'.repeat(20)}`)
const from = new Address(hexToBytes(`0x${'11'.repeat(20)}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Inconsistent Address Implementation Detected

While the update to use new Address(hexToBytes(...)) in createContractAddress.spec.ts is correct, multiple instances of EthjsAddress remain throughout the codebase. This inconsistency could lead to potential confusion and errors.

Areas to Address:

  • Migration Plan: Develop a strategy to systematically replace EthjsAddress with the new Address constructor across all packages.
  • Code Review: Ensure that future updates adhere to the new address implementation to maintain consistency.
  • Testing: Update existing tests to reflect the changes and verify that all address-related functionalities remain intact.
🔗 Analysis chain

LGTM: Address creation updated correctly.

The from address creation has been properly updated to use the new Address constructor with hexToBytes. This change is consistent with the updated imports and maintains the test's original intent.

To ensure consistency across the codebase, let's verify the usage of this new address creation pattern:


To address the issue with unrecognized file types, let's search for .ts and .tsx files directly:


To ensure all instances of EthjsAddress have been appropriately updated, let's identify their exact locations and contexts:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of new Address creation pattern across the codebase.

# Test: Search for new Address creation pattern
rg --type typescript 'new Address\(hexToBytes\(' packages/

# Test: Search for any remaining usage of EthjsAddress
rg --type typescript 'EthjsAddress' packages/

Length of output: 176


Script:

#!/bin/bash
# Description: Verify the usage of new Address creation pattern across the codebase by searching .ts and .tsx files.

# Test: Search for new Address creation pattern in .ts and .tsx files
rg 'new Address\(hexToBytes\(' --glob '*.ts' --glob '*.tsx' packages/

# Test: Search for any remaining usage of EthjsAddress in .ts and .tsx files
rg 'EthjsAddress' --glob '*.ts' --glob '*.tsx' packages/

Length of output: 27517


Script:

#!/bin/bash
# Description: Locate all instances of EthjsAddress and determine their contexts.

# Search for EthjsAddress usages in .ts and .tsx files
rg 'EthjsAddress' --glob '*.ts' --glob '*.tsx' packages/

Length of output: 27126

const nonce = 0n
const expectedAddress = keccak256(toRlp([from.bytes, Uint8Array.from([])]), 'bytes').subarray(-20)

Expand All @@ -18,7 +18,7 @@ describe('createContractAddress', () => {
})

it('should create a valid contract address with a non-zero nonce', () => {
const from = EthjsAddress.fromString(`0x${'22'.repeat(20)}`)
const from = new Address(hexToBytes(`0x${'22'.repeat(20)}`))
const nonce = 1n
const expectedAddress = keccak256(toRlp([from.bytes, numberToBytes(nonce)]), 'bytes').subarray(-20)

Expand Down
Loading
Loading