UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

199 lines • 8.47 kB
import { GasEstimationMode, GasReportExecutionStatus, l1HardforkToString, MineOrdering, opHardforkToString, } from "@nomicfoundation/edr"; import { min } from "@nomicfoundation/hardhat-utils/bigint"; import { GENERIC_CHAIN_TYPE, L1_CHAIN_TYPE, OPTIMISM_CHAIN_TYPE, } from "../../../../constants.js"; import { FixedValueConfigurationVariable } from "../../../../core/configuration-variables.js"; import { derivePrivateKeys } from "../../accounts/derive-private-keys.js"; import { getPrivateKey } from "../../accounts/get-private-key.js"; import { DEFAULT_EDR_NETWORK_BALANCE, EDR_NETWORK_DEFAULT_PRIVATE_KEYS, EIP_7825_TRANSACTION_GAS_CAP, EIP_8037_MAX_TRANSACTION_GAS_LIMIT, isDefaultEdrNetworkHDAccountsConfig, } from "../edr-constants.js"; import { hardforkGte, L1HardforkName } from "../types/hardfork.js"; import { getHardforkName, getL1HardforkName, getOpHardforkName, } from "./hardfork.js"; /** * Returns Hardhat's name for an EDR hardfork. */ export function edrL1HardforkToHardhatL1HardforkName(hardfork) { return getL1HardforkName(l1HardforkToString(hardfork)); } /** * Returns Hardhat's name for an EDR OP hardfork. See * {@link edrL1HardforkToHardhatL1HardforkName}. */ export function edrOpHardforkToHardhatOpHardforkName(hardfork) { return getOpHardforkName(opHardforkToString(hardfork)); } export function hardhatMiningIntervalToEdrMiningInterval(config) { if (typeof config === "number") { // Is interval mining disabled? if (config === 0) { return undefined; } else { return BigInt(config); } } else { return { min: BigInt(Math.max(1, config[0])), max: BigInt(Math.max(1, config[1])), }; } } export function hardhatMempoolOrderToEdrMineOrdering(mempoolOrder) { switch (mempoolOrder) { case "fifo": return MineOrdering.Fifo; case "priority": return MineOrdering.Priority; } } export function hardhatGasEstimationModeToEdrGasEstimationMode(gasEstimationMode) { switch (gasEstimationMode) { case "topLevelSuccess": return GasEstimationMode.TopLevelSuccess; case "noInternalOutOfGas": return GasEstimationMode.NoInternalOutOfGas; } } export async function hardhatAccountsToEdrOwnedAccounts(accounts) { const normalizedAccounts = await normalizeEdrNetworkAccountsConfig(accounts); const accountPromises = normalizedAccounts.map(async (account) => ({ secretKey: await getPrivateKey(account.privateKey), balance: account.balance, })); return await Promise.all(accountPromises); } export async function normalizeEdrNetworkAccountsConfig(accounts) { if (Array.isArray(accounts)) { return accounts; } const isDefaultConfig = await isDefaultEdrNetworkHDAccountsConfig(accounts); const derivedPrivateKeys = isDefaultConfig ? EDR_NETWORK_DEFAULT_PRIVATE_KEYS : await derivePrivateKeys(await accounts.mnemonic.get(), accounts.path, accounts.initialIndex, accounts.count, await accounts.passphrase.get()); return derivedPrivateKeys.map((privateKey) => ({ privateKey: new FixedValueConfigurationVariable(privateKey), balance: accounts.accountsBalance ?? DEFAULT_EDR_NETWORK_BALANCE, })); } export function hardhatChainDescriptorsToEdrChainOverrides(chainDescriptors, chainType) { return (Array.from(chainDescriptors) // Skip chain descriptors that don't match the expected chain type .filter(([_, descriptor]) => { if (chainType === GENERIC_CHAIN_TYPE) { // When "generic" is requested, include both "generic" and "l1" chains return (descriptor.chainType === GENERIC_CHAIN_TYPE || descriptor.chainType === L1_CHAIN_TYPE); } return descriptor.chainType === chainType; }) .map(([chainId, descriptor]) => { const chainOverride = { chainId, name: descriptor.name, }; if (descriptor.hardforkHistory !== undefined) { chainOverride.hardforkActivationOverrides = Array.from(descriptor.hardforkHistory).map(([hardfork, { blockNumber, timestamp }]) => ({ condition: blockNumber !== undefined ? { blockNumber: BigInt(blockNumber) } : { timestamp: BigInt(timestamp) }, hardfork: getHardforkName(hardfork, descriptor.chainType), })); } return chainOverride; })); } export async function hardhatForkingConfigToEdrForkConfig(forkingConfig, chainDescriptors, chainType) { let fork; if (forkingConfig !== undefined && forkingConfig.enabled === true) { const httpHeaders = forkingConfig.httpHeaders !== undefined ? Object.entries(forkingConfig.httpHeaders).map(([name, value]) => ({ name, value, })) : undefined; fork = { blockNumber: forkingConfig.blockNumber, cacheDir: forkingConfig.cacheDir, chainOverrides: hardhatChainDescriptorsToEdrChainOverrides(chainDescriptors, chainType), httpHeaders, url: await forkingConfig.url.getUrl(), }; } return fork; } /** * Resolves the default transaction gas limit used by RPC call and * transaction requests that omit a `gas` field. This includes * `eth_estimateGas`: when the request doesn't specify `gas`, EDR uses this * value as the upper bound of the estimation, so it should be the most gas a * transaction can use. * * From L1's Amsterdam hardfork onwards, EIP-8037 limits `transactionGasCap` * to execution gas, and a transaction can use up to the minimum of the block * gas limit or 2^32 - 1, no matter what `transactionGasCap` is. * * Before Amsterdam, when `transactionGasCap` is a bigint, that value wins. * When it is `false`, the per-transaction cap is disabled and the block gas * limit is used. When it is undefined, the hardfork-specific default applies: * from L1's Osaka hardfork onwards, the EIP-7825 transaction gas cap of * 16,777,216; otherwise the block gas limit. */ export function resolveDefaultTransactionGasLimit(params) { const { chainType, hardfork, blockGasLimit, transactionGasCap } = params; if (chainType !== OPTIMISM_CHAIN_TYPE && hardforkGte(hardfork, L1HardforkName.AMSTERDAM, chainType)) { return min(blockGasLimit, EIP_8037_MAX_TRANSACTION_GAS_LIMIT); } if (typeof transactionGasCap === "bigint") { return transactionGasCap; } if (transactionGasCap === false) { return blockGasLimit; } // TODO: OP UPGRADE 19 - update OP to also set a default transaction gas once enabled if (chainType === OPTIMISM_CHAIN_TYPE) { return blockGasLimit; } if (hardforkGte(hardfork, L1HardforkName.OSAKA, chainType)) { return EIP_7825_TRANSACTION_GAS_CAP; } return blockGasLimit; } /** * Converts EDR's nested GasReport structure into a flat array of gas entries. * Filters out reverted transactions. */ export function edrGasReportToHardhatGasMeasurements(gasReport, excludedContractFqns = []) { const gasMeasurements = []; for (const [contractFqn, data] of Object.entries(gasReport.contracts)) { if (excludedContractFqns.includes(contractFqn)) { continue; } // Process deployments for (const deployment of data.deployments) { if (deployment.status === GasReportExecutionStatus.Success) { gasMeasurements.push({ contractFqn, type: "deployment", gas: Number(deployment.gas), runtimeSize: Number(deployment.runtimeSize), }); } } // Process function calls for (const [functionSig, calls] of Object.entries(data.functions)) { for (const call of calls) { if (call.status === GasReportExecutionStatus.Success) { gasMeasurements.push({ contractFqn, type: "function", functionSig, gas: Number(call.gas), proxyChain: call.proxyChain, }); } } } } return gasMeasurements; } //# sourceMappingURL=convert-to-edr.js.map