diff --git a/packages/hardhat-core/package.json b/packages/hardhat-core/package.json index 340138a0d3..3ab6506f6b 100644 --- a/packages/hardhat-core/package.json +++ b/packages/hardhat-core/package.json @@ -100,7 +100,7 @@ "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.7.0", + "@nomicfoundation/edr": "^0.8.0", "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-tx": "5.0.4", "@nomicfoundation/ethereumjs-util": "9.0.4", diff --git a/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts b/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts index e4b73c977f..af24271f9f 100644 --- a/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts +++ b/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts @@ -12,13 +12,14 @@ import type { Response, SubscriptionEvent, HttpHeader, + TracingConfigWithBuffers, } from "@nomicfoundation/edr"; +import { l1GenesisState, l1HardforkFromString } from "@nomicfoundation/edr"; import { Common } from "@nomicfoundation/ethereumjs-common"; import picocolors from "picocolors"; import debug from "debug"; import { EventEmitter } from "events"; import fsExtra from "fs-extra"; -import semver from "semver"; import { requireNapiRsModule } from "../../../common/napi-rs"; import { @@ -33,7 +34,6 @@ import { import { isErrorResponse } from "../../core/providers/http"; import { getHardforkName } from "../../util/hardforks"; import { ConsoleLogger } from "../stack-traces/consoleLogger"; -import { FIRST_SOLC_VERSION_SUPPORTED } from "../stack-traces/constants"; import { encodeSolidityStackTrace } from "../stack-traces/solidity-errors"; import { SolidityStackTrace } from "../stack-traces/solidity-stack-trace"; @@ -67,14 +67,19 @@ export const DEFAULT_COINBASE = "0xc014ba5ec014ba5ec014ba5ec014ba5ec014ba5e"; let _globalEdrContext: EdrContext | undefined; // Lazy initialize the global EDR context. -export function getGlobalEdrContext(): EdrContext { - const { EdrContext } = requireNapiRsModule( - "@nomicfoundation/edr" - ) as typeof import("@nomicfoundation/edr"); +export async function getGlobalEdrContext(): Promise { + const { EdrContext, GENERIC_CHAIN_TYPE, genericChainProviderFactory } = + requireNapiRsModule( + "@nomicfoundation/edr" + ) as typeof import("@nomicfoundation/edr"); if (_globalEdrContext === undefined) { // Only one is allowed to exist _globalEdrContext = new EdrContext(); + await _globalEdrContext.registerProviderFactory( + GENERIC_CHAIN_TYPE, + genericChainProviderFactory() + ); } return _globalEdrContext; @@ -165,9 +170,9 @@ export class EdrProviderWrapper public static async create( config: HardhatNetworkProviderConfig, loggerConfig: LoggerConfig, - tracingConfig?: TracingConfig + tracingConfig?: TracingConfigWithBuffers ): Promise { - const { Provider } = requireNapiRsModule( + const { GENERIC_CHAIN_TYPE } = requireNapiRsModule( "@nomicfoundation/edr" ) as typeof import("@nomicfoundation/edr"); @@ -213,8 +218,16 @@ export class EdrProviderWrapper const hardforkName = getHardforkName(config.hardfork); - const provider = await Provider.withConfig( - getGlobalEdrContext(), + const genesisState = + fork !== undefined + ? [] + : l1GenesisState( + l1HardforkFromString(ethereumsjsHardforkToEdrSpecId(hardforkName)) + ); + + const context = await getGlobalEdrContext(); + const provider = await context.createProvider( + GENERIC_CHAIN_TYPE, { allowBlocksWithSameTimestamp: config.allowBlocksWithSameTimestamp ?? false, @@ -243,13 +256,8 @@ export class EdrProviderWrapper coinbase: Buffer.from(coinbase.slice(2), "hex"), enableRip7212: config.enableRip7212, fork, + genesisState, hardfork: ethereumsjsHardforkToEdrSpecId(hardforkName), - genesisAccounts: config.genesisAccounts.map((account) => { - return { - secretKey: account.privateKey, - balance: BigInt(account.balance), - }; - }), initialDate, initialBaseFeePerGas: config.initialBaseFeePerGas !== undefined @@ -264,6 +272,12 @@ export class EdrProviderWrapper }, }, networkId: BigInt(config.networkId), + ownedAccounts: config.genesisAccounts.map((account) => { + return { + secretKey: account.privateKey, + balance: BigInt(account.balance), + }; + }), }, { enable: loggerConfig.enabled, @@ -276,10 +290,12 @@ export class EdrProviderWrapper } }, }, - tracingConfig ?? {}, - (event: SubscriptionEvent) => { - eventAdapter.emit("ethEvent", event); - } + { + subscriptionCallback: (event: SubscriptionEvent) => { + eventAdapter.emit("ethEvent", event); + }, + }, + tracingConfig ?? {} ); const minimalEthereumJsNode = { @@ -437,18 +453,20 @@ export class EdrProviderWrapper } // temporarily added to make smock work with HH+EDR - private _setCallOverrideCallback(callback: CallOverrideCallback) { + private async _setCallOverrideCallback( + callback: CallOverrideCallback + ): Promise { this._callOverrideCallback = callback; - this._provider.setCallOverrideCallback( + await this._provider.setCallOverrideCallback( async (address: Buffer, data: Buffer) => { return this._callOverrideCallback?.(address, data); } ); } - private _setVerboseTracing(enabled: boolean) { - this._provider.setVerboseTracing(enabled); + private async _setVerboseTracing(enabled: boolean): Promise { + await this._provider.setVerboseTracing(enabled); } private _ethEventListener(event: SubscriptionEvent) { @@ -506,19 +524,14 @@ export async function createHardhatNetworkProvider( async function makeTracingConfig( artifacts: Artifacts | undefined -): Promise { +): Promise { if (artifacts !== undefined) { - const buildInfos = []; - const buildInfoFiles = await artifacts.getBuildInfoPaths(); try { - for (const buildInfoFile of buildInfoFiles) { - const buildInfo = await fsExtra.readJson(buildInfoFile); - if (semver.gte(buildInfo.solcVersion, FIRST_SOLC_VERSION_SUPPORTED)) { - buildInfos.push(buildInfo); - } - } + const buildInfos = await Promise.all( + buildInfoFiles.map((filePath) => fsExtra.readFile(filePath)) + ); return { buildInfos, diff --git a/packages/hardhat-core/src/internal/hardhat-network/provider/utils/convertToEdr.ts b/packages/hardhat-core/src/internal/hardhat-network/provider/utils/convertToEdr.ts index a955ef1225..702b9e9ca9 100644 --- a/packages/hardhat-core/src/internal/hardhat-network/provider/utils/convertToEdr.ts +++ b/packages/hardhat-core/src/internal/hardhat-network/provider/utils/convertToEdr.ts @@ -1,11 +1,28 @@ -import type { - SpecId, - MineOrdering, - IntervalRange, - DebugTraceResult, - TracingMessage, - TracingMessageResult, - TracingStep, +import { + type SpecId, + type MineOrdering, + type IntervalRange, + type DebugTraceResult, + type TracingMessage, + type TracingMessageResult, + type TracingStep, + FRONTIER, + HOMESTEAD, + DAO_FORK, + TANGERINE, + SPURIOUS_DRAGON, + BYZANTIUM, + CONSTANTINOPLE, + PETERSBURG, + ISTANBUL, + MUIR_GLACIER, + BERLIN, + LONDON, + ARROW_GLACIER, + GRAY_GLACIER, + MERGE, + SHANGHAI, + CANCUN, } from "@nomicfoundation/edr"; import { Address } from "@nomicfoundation/ethereumjs-util"; @@ -21,46 +38,42 @@ import { /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */ -export function ethereumsjsHardforkToEdrSpecId(hardfork: HardforkName): SpecId { - const { SpecId } = requireNapiRsModule( - "@nomicfoundation/edr" - ) as typeof import("@nomicfoundation/edr"); - +export function ethereumsjsHardforkToEdrSpecId(hardfork: HardforkName): string { switch (hardfork) { case HardforkName.FRONTIER: - return SpecId.Frontier; + return FRONTIER; case HardforkName.HOMESTEAD: - return SpecId.Homestead; + return HOMESTEAD; case HardforkName.DAO: - return SpecId.DaoFork; + return DAO_FORK; case HardforkName.TANGERINE_WHISTLE: - return SpecId.Tangerine; + return TANGERINE; case HardforkName.SPURIOUS_DRAGON: - return SpecId.SpuriousDragon; + return SPURIOUS_DRAGON; case HardforkName.BYZANTIUM: - return SpecId.Byzantium; + return BYZANTIUM; case HardforkName.CONSTANTINOPLE: - return SpecId.Constantinople; + return CONSTANTINOPLE; case HardforkName.PETERSBURG: - return SpecId.Petersburg; + return PETERSBURG; case HardforkName.ISTANBUL: - return SpecId.Istanbul; + return ISTANBUL; case HardforkName.MUIR_GLACIER: - return SpecId.MuirGlacier; + return MUIR_GLACIER; case HardforkName.BERLIN: - return SpecId.Berlin; + return BERLIN; case HardforkName.LONDON: - return SpecId.London; + return LONDON; case HardforkName.ARROW_GLACIER: - return SpecId.ArrowGlacier; + return ARROW_GLACIER; case HardforkName.GRAY_GLACIER: - return SpecId.GrayGlacier; + return GRAY_GLACIER; case HardforkName.MERGE: - return SpecId.Merge; + return MERGE; case HardforkName.SHANGHAI: - return SpecId.Shanghai; + return SHANGHAI; case HardforkName.CANCUN: - return SpecId.Cancun; + return CANCUN; default: const _exhaustiveCheck: never = hardfork; throw new Error( diff --git a/packages/hardhat-core/src/internal/hardhat-network/stack-traces/constants.ts b/packages/hardhat-core/src/internal/hardhat-network/stack-traces/constants.ts index 6b1f64bdc2..837258c63f 100644 --- a/packages/hardhat-core/src/internal/hardhat-network/stack-traces/constants.ts +++ b/packages/hardhat-core/src/internal/hardhat-network/stack-traces/constants.ts @@ -1,2 +1 @@ export const SUPPORTED_SOLIDITY_VERSION_RANGE = "<=0.8.28"; -export const FIRST_SOLC_VERSION_SUPPORTED = "0.5.1";