UNPKG

hardhat

Version:

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

124 lines (110 loc) 4.11 kB
import { HardforkHistoryConfig } from "../../types/config"; import { HARDHAT_NETWORK_SUPPORTED_HARDFORKS } from "../constants"; import { assertHardhatInvariant } from "../core/errors"; import { InternalError } from "../core/providers/errors"; /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */ export enum HardforkName { FRONTIER = "chainstart", HOMESTEAD = "homestead", DAO = "dao", TANGERINE_WHISTLE = "tangerineWhistle", SPURIOUS_DRAGON = "spuriousDragon", BYZANTIUM = "byzantium", CONSTANTINOPLE = "constantinople", PETERSBURG = "petersburg", ISTANBUL = "istanbul", MUIR_GLACIER = "muirGlacier", BERLIN = "berlin", LONDON = "london", ARROW_GLACIER = "arrowGlacier", GRAY_GLACIER = "grayGlacier", MERGE = "merge", SHANGHAI = "shanghai", CANCUN = "cancun", } const HARDFORKS_ORDER: HardforkName[] = [ HardforkName.FRONTIER, HardforkName.HOMESTEAD, HardforkName.DAO, HardforkName.TANGERINE_WHISTLE, HardforkName.SPURIOUS_DRAGON, HardforkName.BYZANTIUM, HardforkName.CONSTANTINOPLE, HardforkName.PETERSBURG, HardforkName.ISTANBUL, HardforkName.MUIR_GLACIER, HardforkName.BERLIN, HardforkName.LONDON, HardforkName.ARROW_GLACIER, HardforkName.GRAY_GLACIER, HardforkName.MERGE, HardforkName.SHANGHAI, HardforkName.CANCUN, ]; export function getHardforkName(name: string): HardforkName { const hardforkName = Object.values(HardforkName)[ Object.values<string>(HardforkName).indexOf(name) ]; assertHardhatInvariant( hardforkName !== undefined, `Invalid harfork name ${name}` ); return hardforkName; } /** * Check if `hardforkA` is greater than or equal to `hardforkB`, * that is, if it includes all its changes. */ export function hardforkGte( hardforkA: HardforkName, hardforkB: HardforkName ): boolean { // This function should not load any ethereumjs library, as it's used during // the Hardhat initialization, and that would make it too slow. const indexA = HARDFORKS_ORDER.lastIndexOf(hardforkA); const indexB = HARDFORKS_ORDER.lastIndexOf(hardforkB); return indexA >= indexB; } export function selectHardfork( forkBlockNumber: bigint | undefined, currentHardfork: string, hardforkActivations: HardforkHistoryConfig | undefined, blockNumber: bigint ): string { if (forkBlockNumber === undefined || blockNumber > forkBlockNumber) { return currentHardfork; } if (hardforkActivations === undefined || hardforkActivations.size === 0) { throw new InternalError( `No known hardfork for execution on historical block ${blockNumber.toString()} (relative to fork block number ${forkBlockNumber}). The node was not configured with a hardfork activation history. See http://hardhat.org/custom-hardfork-history` ); } /** search this._hardforkActivations for the highest block number that * isn't higher than blockNumber, and then return that found block number's * associated hardfork name. */ const hardforkHistory: Array<[name: string, block: number]> = Array.from( hardforkActivations.entries() ); const [hardfork, activationBlock] = hardforkHistory.reduce( ([highestHardfork, highestBlock], [thisHardfork, thisBlock]) => thisBlock > highestBlock && thisBlock <= blockNumber ? [thisHardfork, thisBlock] : [highestHardfork, highestBlock] ); if (hardfork === undefined || blockNumber < activationBlock) { throw new InternalError( `Could not find a hardfork to run for block ${blockNumber.toString()}, after having looked for one in the hardfork activation history, which was: ${JSON.stringify( hardforkHistory )}. For more information, see https://hardhat.org/hardhat-network/reference/#config` ); } if (!HARDHAT_NETWORK_SUPPORTED_HARDFORKS.includes(hardfork)) { throw new InternalError( `Tried to run a call or transaction in the context of a block whose hardfork is "${hardfork}", but Hardhat Network only supports the following hardforks: ${HARDHAT_NETWORK_SUPPORTED_HARDFORKS.join( ", " )}` ); } return hardfork; }