diff --git a/packages/ethereum/ethereum/src/api.ts b/packages/ethereum/ethereum/src/api.ts index cbf027e690..6e1d2c7523 100644 --- a/packages/ethereum/ethereum/src/api.ts +++ b/packages/ethereum/ethereum/src/api.ts @@ -924,6 +924,7 @@ export default class EthereumApi implements Api { const vm = await blockchain.createVmFromStateTrie( blockchain.trie.shallowCopy(false), options.chain.allowUnlimitedContractSize, + options.chain.allowUnlimitedInitCodeSize, false ); return vm; diff --git a/packages/ethereum/ethereum/src/blockchain.ts b/packages/ethereum/ethereum/src/blockchain.ts index fde4cc44d3..ee7edb4a5f 100644 --- a/packages/ethereum/ethereum/src/blockchain.ts +++ b/packages/ethereum/ethereum/src/blockchain.ts @@ -79,7 +79,6 @@ import { dumpTrieStorageDetails } from "./helpers/storage-range-at"; import { GanacheStateManager } from "./state-manager"; import { TrieDB } from "./trie-db"; import { Trie } from "@ethereumjs/trie"; -import { removeEIP3860InitCodeSizeLimitCheck } from "./helpers/common-helpers"; import { Journal } from "@ethereumjs/evm/dist/cjs/journal"; const mclInitPromise = mcl.init(mcl.BLS12_381).then(() => { @@ -253,10 +252,6 @@ export default class Blockchain extends Emittery { options.chain.networkId, options.chain.hardfork ); - - if (options.chain.allowUnlimitedInitCodeSize) { - removeEIP3860InitCodeSizeLimitCheck(common); - } } this.isPostParis = this.common.gteHardfork("paris"); @@ -302,6 +297,7 @@ export default class Blockchain extends Emittery { this.vm = await this.createVmFromStateTrie( this.trie, options.chain.allowUnlimitedContractSize, + options.chain.allowUnlimitedInitCodeSize, true ); @@ -678,6 +674,7 @@ export default class Blockchain extends Emittery { createVmFromStateTrie = async ( stateTrie: GanacheTrie | ForkTrie, allowUnlimitedContractSize: boolean, + allowUnlimitedInitCodeSize: boolean, activatePrecompile: boolean, common?: Common ) => { @@ -710,6 +707,7 @@ export default class Blockchain extends Emittery { const evm = new EVM({ common, allowUnlimitedContractSize, + allowUnlimitedInitCodeSize, stateManager, blockchain }); @@ -1143,6 +1141,7 @@ export default class Blockchain extends Emittery { const vm = await this.createVmFromStateTrie( stateTrie, options.chain.allowUnlimitedContractSize, + options.chain.allowUnlimitedInitCodeSize, false, // precompiles have already been initialized in the stateTrie common ); @@ -1274,10 +1273,12 @@ export default class Blockchain extends Emittery { }) : new GanacheStateManager({ trie, prefixCodeHashes: false }); + const { allowUnlimitedContractSize, allowUnlimitedInitCodeSize } = + this.#options.chain; const evm = new EVM({ common, - allowUnlimitedContractSize: - this.#options.chain.allowUnlimitedContractSize, + allowUnlimitedContractSize, + allowUnlimitedInitCodeSize, stateManager, blockchain }); @@ -1312,7 +1313,7 @@ export default class Blockchain extends Emittery { this.emit("ganache:vm:tx:before", { context: transactionEventContext }); - await vm.runTx({ + const g = vm.runTx({ skipHardForkValidation: true, skipNonce: true, skipBalance: true, @@ -1320,6 +1321,7 @@ export default class Blockchain extends Emittery { tx, block: block as any }); + await g; this.emit("ganache:vm:tx:after", { context: transactionEventContext }); @@ -1646,13 +1648,11 @@ export default class Blockchain extends Emittery { if (!rawAccount) { throw new Error(`account ${contractAddress} doesn't exist`); } + const [, , stateRoot] = decode(Buffer.from(rawAccount)); let storageTrie: Trie; if (txIndex === 0) { // there are no transactions to run, so let's just grab what we need // from the last block's trie - const [, , stateRoot] = decode( - Buffer.from(rawAccount) - ); trie.setContext( stateRoot, contractAddressBuffer, @@ -1670,7 +1670,10 @@ export default class Blockchain extends Emittery { // run every transaction in that block prior to the requested transaction const vm = await this.#createFastForwardVm(txIndex, trie, newBlock); - storageTrie = await vm.stateManager.getStorageTrie(contractAddressBuffer); + storageTrie = await vm.stateManager.getStorageTrie( + contractAddressBuffer, + await vm.stateManager.getStateRoot() + ); } return await dumpTrieStorageDetails( diff --git a/packages/ethereum/ethereum/src/forking/fork.ts b/packages/ethereum/ethereum/src/forking/fork.ts index e389b88a46..6e16de3de2 100644 --- a/packages/ethereum/ethereum/src/forking/fork.ts +++ b/packages/ethereum/ethereum/src/forking/fork.ts @@ -12,7 +12,6 @@ import BlockManager from "../data-managers/block-manager"; import { ProviderHandler } from "./handlers/provider-handler"; import { PersistentCache } from "./persistent-cache/persistent-cache"; import { URL } from "url"; -import { removeEIP3860InitCodeSizeLimitCheck } from "../helpers/common-helpers"; async function fetchChainId(fork: Fork) { const chainIdHex = await fork.request("eth_chainId", []); @@ -128,9 +127,7 @@ export class Fork { }, { baseChain: KNOWN_CHAINIDS.has(chainId) ? chainId : 1 } ); - if (this.#options.chain.allowUnlimitedInitCodeSize) { - removeEIP3860InitCodeSizeLimitCheck(this.common); - } + // disable listeners to common since we don't actually cause any `emit`s, // but other EVM parts to listen and will make node complain about too // many listeners. @@ -327,9 +324,6 @@ export class Fork { { baseChain: 1 } ); } - if (this.#options.chain.allowUnlimitedInitCodeSize) { - removeEIP3860InitCodeSizeLimitCheck(forkCommon); - } return forkCommon; } else { return common; diff --git a/packages/ethereum/ethereum/src/helpers/common-helpers.ts b/packages/ethereum/ethereum/src/helpers/common-helpers.ts index 1b3393514e..7ee0b4a0f7 100644 --- a/packages/ethereum/ethereum/src/helpers/common-helpers.ts +++ b/packages/ethereum/ethereum/src/helpers/common-helpers.ts @@ -1,27 +1,5 @@ import type { Common } from "@ethereumjs/common"; -/** - * Effectively removes the 3860 InitCode Size Limit check by increasing the init - * code size to Number.MAX_SAFE_INTEGER. - * - * This number works because an initcode can practically never be that large - * (approx 9 PetaBytes!). - * - * @param common - * @returns - */ -export function removeEIP3860InitCodeSizeLimitCheck(common: Common) { - // this is a hack until EJS ships `allowUnlimitedInitCodeSize` option https://github.com/ethereumjs/ethereumjs-monorepo/issues/2588 - return changeCommonParamValue( - common, - 3860, - "vm", - "maxInitCodeSize", - // we'd use Infinity if we could, but that's not a valid BigInt - BigInt(Number.MAX_SAFE_INTEGER) - ); -} - export function changeCommonParamValue( common: Common, eip: number, diff --git a/packages/ethereum/ethereum/src/state-manager.ts b/packages/ethereum/ethereum/src/state-manager.ts index 1d917c7008..4ca135efb3 100644 --- a/packages/ethereum/ethereum/src/state-manager.ts +++ b/packages/ethereum/ethereum/src/state-manager.ts @@ -1,19 +1,18 @@ -import { - DefaultStateManager, - DefaultStateManagerOpts -} from "@ethereumjs/statemanager"; +import { DefaultStateManager } from "@ethereumjs/statemanager"; import { Trie } from "@ethereumjs/trie"; -import { KECCAK256_RLP } from "@ethereumjs/util"; export class GanacheStateManager extends DefaultStateManager { - async getStorageTrie(address: Buffer): Promise { - return await (this as any)._getStorageTrie( + async getStorageTrie( + address: Buffer, + storageRoot: Uint8Array + ): Promise { + return await super._getStorageTrie( { bytes: address - }, + } as any, { - storageRoot: KECCAK256_RLP - } + storageRoot + } as any ); } } diff --git a/packages/ethereum/ethereum/tests/api/eth/call.test.ts b/packages/ethereum/ethereum/tests/api/eth/call.test.ts index cb940ce6af..4471c6fdd0 100644 --- a/packages/ethereum/ethereum/tests/api/eth/call.test.ts +++ b/packages/ethereum/ethereum/tests/api/eth/call.test.ts @@ -994,6 +994,7 @@ describe("api", () => { trie, false, false, + false, blockchain.common ); const fromState = await vm.stateManager.getAccount(vmFromAddress);