From 2719643be1d38590e1d79326b677131360984ca3 Mon Sep 17 00:00:00 2001
From: emersonmacro <77563348+emersonmacro@users.noreply.github.com>
Date: Fri, 21 Jan 2022 00:07:14 -0800
Subject: [PATCH] Common, VM: Remove unused HF options from Common, move
 supportedHardforks to VM (#1649)

* common: remove onlySupported and onlyActive hf options

* vm: move supportedHardforks option from common

* common: remove supportedHardforks option

* common: update README for supportedHardforks removal

* vm: update README for supportedHardforks addition

* common: cleanup in src/index.ts

* vm: refactor supportedHardforks per PR feedback

* common: remove _chooseHardfork method per PR feedback

* vm: updated README per PR feedback

* vm: supportedHardforks local variable, switch to enum
---
 packages/common/README.md               |  12 ---
 packages/common/src/index.ts            | 122 ++++--------------------
 packages/common/tests/chains.spec.ts    |  25 -----
 packages/common/tests/hardforks.spec.ts |  50 +---------
 packages/common/tests/params.spec.ts    |  23 +----
 packages/vm/src/index.ts                |  44 +++++----
 packages/vm/tests/api/index.spec.ts     |  20 ++++
 7 files changed, 70 insertions(+), 226 deletions(-)

diff --git a/packages/common/README.md b/packages/common/README.md
index 1f35569138..1b060262a6 100644
--- a/packages/common/README.md
+++ b/packages/common/README.md
@@ -48,18 +48,6 @@ c.genesis().hash // 0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1
 c.bootstrapNodes() // Array with current nodes
 ```
 
-If the initializing library only supports a certain range of `hardforks` you can use the `supportedHardforks` option to restrict hardfork access on the `Common` instance:
-
-```typescript
-const c = new Common({
-  chain: 'ropsten',
-  supportedHardforks: ['byzantium', 'constantinople', 'petersburg'],
-})
-```
-
-This will e.g. throw an error when a param is requested for an unsupported hardfork and
-like this prevents unpredicted behaviour.
-
 For an improved developer experience, there are `Chain` and `Hardfork` enums available:
 
 ```typescript
diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts
index 98e4386a25..d3e988380f 100644
--- a/packages/common/src/index.ts
+++ b/packages/common/src/index.ts
@@ -102,10 +102,6 @@ interface BaseOpts {
    * Default: Hardfork.Istanbul
    */
   hardfork?: string | Hardfork
-  /**
-   * Limit parameter returns to the given hardforks
-   */
-  supportedHardforks?: Array<string | Hardfork>
   /**
    * Selected EIPs which can be activated, please use an array for instantiation
    * (e.g. `eips: [ 2537, ]`)
@@ -162,13 +158,6 @@ export interface CustomCommonOpts extends BaseOpts {
   baseChain?: string | number | Chain | BN
 }
 
-interface hardforkOptions {
-  /** optional, only allow supported HFs (default: false) */
-  onlySupported?: boolean
-  /** optional, only active HFs (default: false) */
-  onlyActive?: boolean
-}
-
 /**
  * Common class to access chain and hardfork parameters and to provide
  * a unified and shared view on the network and hardfork state.
@@ -182,7 +171,6 @@ export default class Common extends EventEmitter {
 
   private _chainParams: IChain
   private _hardfork: string | Hardfork
-  private _supportedHardforks: Array<string | Hardfork> = []
   private _eips: number[] = []
   private _customChains: IChain[] | [IChain, GenesisState][]
 
@@ -293,13 +281,11 @@ export default class Common extends EventEmitter {
    * chain params on.
    * @param customChainParams The custom parameters of the chain.
    * @param hardfork String identifier ('byzantium') for hardfork (optional)
-   * @param supportedHardforks Limit parameter returns to the given hardforks (optional)
    */
   static forCustomChain(
     baseChain: string | number | Chain,
     customChainParams: Partial<IChain>,
-    hardfork?: string | Hardfork,
-    supportedHardforks?: Array<string | Hardfork>
+    hardfork?: string | Hardfork
   ): Common {
     const standardChainParams = Common._getChainParams(baseChain)
 
@@ -309,7 +295,6 @@ export default class Common extends EventEmitter {
         ...customChainParams,
       },
       hardfork: hardfork,
-      supportedHardforks: supportedHardforks,
     })
   }
 
@@ -361,9 +346,6 @@ export default class Common extends EventEmitter {
       }
     }
     this._hardfork = this.DEFAULT_HARDFORK
-    if (opts.supportedHardforks) {
-      this._supportedHardforks = opts.supportedHardforks
-    }
     if (opts.hardfork) {
       this.setHardfork(opts.hardfork)
     }
@@ -416,9 +398,6 @@ export default class Common extends EventEmitter {
    * @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum
    */
   setHardfork(hardfork: string | Hardfork): void {
-    if (!this._isSupportedHardfork(hardfork)) {
-      throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`)
-    }
     let existing = false
     for (const hfChanges of HARDFORK_CHANGES) {
       if (hfChanges[0] === hardfork) {
@@ -514,20 +493,6 @@ export default class Common extends EventEmitter {
     return hardfork
   }
 
-  /**
-   * Internal helper function to choose between hardfork set and hardfork provided as param
-   * @param hardfork Hardfork given to function as a parameter
-   * @returns Hardfork chosen to be used
-   */
-  _chooseHardfork(hardfork?: string | Hardfork | null, onlySupported: boolean = true): string {
-    if (!hardfork) {
-      hardfork = this._hardfork
-    } else if (onlySupported && !this._isSupportedHardfork(hardfork)) {
-      throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`)
-    }
-    return hardfork
-  }
-
   /**
    * Internal helper function, returns the params for the given hardfork for the chain set
    * @param hardfork Hardfork name
@@ -541,22 +506,6 @@ export default class Common extends EventEmitter {
     throw new Error(`Hardfork ${hardfork} not defined for chain ${this.chainName()}`)
   }
 
-  /**
-   * Internal helper function to check if a hardfork is set to be supported by the library
-   * @param hardfork Hardfork name
-   * @returns True if hardfork is supported
-   */
-  _isSupportedHardfork(hardfork: string | Hardfork | null): boolean {
-    if (this._supportedHardforks.length > 0) {
-      for (const supportedHf of this._supportedHardforks) {
-        if (hardfork === supportedHf) return true
-      }
-    } else {
-      return true
-    }
-    return false
-  }
-
   /**
    * Sets the active EIPs
    * @param eips
@@ -615,8 +564,6 @@ export default class Common extends EventEmitter {
    * @returns The value requested or `null` if not found
    */
   paramByHardfork(topic: string, name: string, hardfork: string | Hardfork): any {
-    hardfork = this._chooseHardfork(hardfork)
-
     let value = null
     for (const hfChanges of HARDFORK_CHANGES) {
       // EIP-referencing HF file (e.g. berlin.json)
@@ -703,17 +650,11 @@ export default class Common extends EventEmitter {
    * Checks if set or provided hardfork is active on block number
    * @param hardfork Hardfork name or null (for HF set)
    * @param blockNumber
-   * @param opts Hardfork options (onlyActive unused)
    * @returns True if HF is active on block number
    */
-  hardforkIsActiveOnBlock(
-    hardfork: string | Hardfork | null,
-    blockNumber: BNLike,
-    opts: hardforkOptions = {}
-  ): boolean {
+  hardforkIsActiveOnBlock(hardfork: string | Hardfork | null, blockNumber: BNLike): boolean {
     blockNumber = toType(blockNumber, TypeOutput.BN)
-    const onlySupported = opts.onlySupported ?? false
-    hardfork = this._chooseHardfork(hardfork, onlySupported)
+    hardfork = hardfork ?? this._hardfork
     const hfBlock = this.hardforkBlockBN(hardfork)
     if (hfBlock && blockNumber.gte(hfBlock)) {
       return true
@@ -724,11 +665,10 @@ export default class Common extends EventEmitter {
   /**
    * Alias to hardforkIsActiveOnBlock when hardfork is set
    * @param blockNumber
-   * @param opts Hardfork options (onlyActive unused)
    * @returns True if HF is active on block number
    */
-  activeOnBlock(blockNumber: BNLike, opts?: hardforkOptions): boolean {
-    return this.hardforkIsActiveOnBlock(null, blockNumber, opts)
+  activeOnBlock(blockNumber: BNLike): boolean {
+    return this.hardforkIsActiveOnBlock(null, blockNumber)
   }
 
   /**
@@ -738,20 +678,9 @@ export default class Common extends EventEmitter {
    * @param opts Hardfork options
    * @returns True if HF1 gte HF2
    */
-  hardforkGteHardfork(
-    hardfork1: string | Hardfork | null,
-    hardfork2: string | Hardfork,
-    opts: hardforkOptions = {}
-  ): boolean {
-    const onlyActive = opts.onlyActive === undefined ? false : opts.onlyActive
-    hardfork1 = this._chooseHardfork(hardfork1, opts.onlySupported)
-
-    let hardforks
-    if (onlyActive) {
-      hardforks = this.activeHardforks(null, opts)
-    } else {
-      hardforks = this.hardforks()
-    }
+  hardforkGteHardfork(hardfork1: string | Hardfork | null, hardfork2: string | Hardfork): boolean {
+    hardfork1 = hardfork1 ?? this._hardfork
+    const hardforks = this.hardforks()
 
     let posHf1 = -1,
       posHf2 = -1
@@ -767,25 +696,19 @@ export default class Common extends EventEmitter {
   /**
    * Alias to hardforkGteHardfork when hardfork is set
    * @param hardfork Hardfork name
-   * @param opts Hardfork options
    * @returns True if hardfork set is greater than hardfork provided
    */
-  gteHardfork(hardfork: string | Hardfork, opts?: hardforkOptions): boolean {
-    return this.hardforkGteHardfork(null, hardfork, opts)
+  gteHardfork(hardfork: string | Hardfork): boolean {
+    return this.hardforkGteHardfork(null, hardfork)
   }
 
   /**
    * Checks if given or set hardfork is active on the chain
    * @param hardfork Hardfork name, optional if HF set
-   * @param opts Hardfork options (onlyActive unused)
    * @returns True if hardfork is active on the chain
    */
-  hardforkIsActiveOnChain(
-    hardfork?: string | Hardfork | null,
-    opts: hardforkOptions = {}
-  ): boolean {
-    const onlySupported = opts.onlySupported ?? false
-    hardfork = this._chooseHardfork(hardfork, onlySupported)
+  hardforkIsActiveOnChain(hardfork?: string | Hardfork | null): boolean {
+    hardfork = hardfork ?? this._hardfork
     for (const hf of this.hardforks()) {
       if (hf['name'] === hardfork && hf['block'] !== null) return true
     }
@@ -795,16 +718,14 @@ export default class Common extends EventEmitter {
   /**
    * Returns the active hardfork switches for the current chain
    * @param blockNumber up to block if provided, otherwise for the whole chain
-   * @param opts Hardfork options (onlyActive unused)
    * @return Array with hardfork arrays
    */
-  activeHardforks(blockNumber?: BNLike | null, opts: hardforkOptions = {}): HardforkParams[] {
+  activeHardforks(blockNumber?: BNLike | null): HardforkParams[] {
     const activeHardforks: HardforkParams[] = []
     const hfs = this.hardforks()
     for (const hf of hfs) {
       if (hf['block'] === null) continue
       if (blockNumber !== undefined && blockNumber !== null && blockNumber < hf['block']) break
-      if (opts.onlySupported && !this._isSupportedHardfork(hf['name'])) continue
 
       activeHardforks.push(hf)
     }
@@ -814,11 +735,10 @@ export default class Common extends EventEmitter {
   /**
    * Returns the latest active hardfork name for chain or block or throws if unavailable
    * @param blockNumber up to block if provided, otherwise for the whole chain
-   * @param opts Hardfork options (onlyActive unused)
    * @return Hardfork name
    */
-  activeHardfork(blockNumber?: BNLike | null, opts: hardforkOptions = {}): string {
-    const activeHardforks = this.activeHardforks(blockNumber, opts)
+  activeHardfork(blockNumber?: BNLike | null): string {
+    const activeHardforks = this.activeHardforks(blockNumber)
     if (activeHardforks.length > 0) {
       return activeHardforks[activeHardforks.length - 1]['name']
     } else {
@@ -843,7 +763,7 @@ export default class Common extends EventEmitter {
    * @returns Block number or null if unscheduled
    */
   hardforkBlockBN(hardfork?: string | Hardfork): BN | null {
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const block = this._getHardfork(hardfork)['block']
     if (block === undefined || block === null) {
       return null
@@ -857,7 +777,7 @@ export default class Common extends EventEmitter {
    * @returns Total difficulty or null if no set
    */
   hardforkTD(hardfork?: string | Hardfork): BN | null {
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const td = this._getHardfork(hardfork)['td']
     if (td === undefined || td === null) {
       return null
@@ -873,7 +793,7 @@ export default class Common extends EventEmitter {
    */
   isHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean {
     blockNumber = toType(blockNumber, TypeOutput.BN)
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const block = this.hardforkBlockBN(hardfork)
     return block ? block.eq(blockNumber) : false
   }
@@ -895,7 +815,7 @@ export default class Common extends EventEmitter {
    * @returns Block number or null if not available
    */
   nextHardforkBlockBN(hardfork?: string | Hardfork): BN | null {
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const hfBlock = this.hardforkBlockBN(hardfork)
     if (hfBlock === null) {
       return null
@@ -919,7 +839,7 @@ export default class Common extends EventEmitter {
    */
   isNextHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean {
     blockNumber = toType(blockNumber, TypeOutput.BN)
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const nextHardforkBlock = this.nextHardforkBlockBN(hardfork)
 
     return nextHardforkBlock === null ? false : nextHardforkBlock.eq(blockNumber)
@@ -963,7 +883,7 @@ export default class Common extends EventEmitter {
    * @param hardfork Hardfork name, optional if HF set
    */
   forkHash(hardfork?: string | Hardfork) {
-    hardfork = this._chooseHardfork(hardfork, false)
+    hardfork = hardfork ?? this._hardfork
     const data = this._getHardfork(hardfork)
     if (data['block'] === null && data['td'] === undefined) {
       const msg = 'No fork hash calculation possible for future hardfork'
diff --git a/packages/common/tests/chains.spec.ts b/packages/common/tests/chains.spec.ts
index 7465541ea2..dcfc596aa4 100644
--- a/packages/common/tests/chains.spec.ts
+++ b/packages/common/tests/chains.spec.ts
@@ -16,7 +16,6 @@ tape('[Common/Chains]: Initialization / Chain params', function (t: tape.Test) {
       c.DEFAULT_HARDFORK,
       'should set hardfork to hardfork set as DEFAULT_HARDFORK'
     )
-    st.equal(c._isSupportedHardfork('constantinople'), true, 'should not restrict supported HFs')
 
     c = new Common({ chain: 1 })
     st.equal(c.chainName(), 'mainnet', 'should initialize with chain Id')
@@ -37,7 +36,6 @@ tape('[Common/Chains]: Initialization / Chain params', function (t: tape.Test) {
       c.DEFAULT_HARDFORK,
       'should set hardfork to hardfork set as DEFAULT_HARDFORK'
     )
-    st.equal(c._isSupportedHardfork('constantinople'), true, 'should not restrict supported HFs')
 
     st.end()
   })
@@ -59,19 +57,6 @@ tape('[Common/Chains]: Initialization / Chain params', function (t: tape.Test) {
     }
   )
 
-  t.test('Should initialize with supportedHardforks provided', function (st: tape.Test) {
-    const c = new Common({
-      chain: 'mainnet',
-      hardfork: 'byzantium',
-      supportedHardforks: ['byzantium', 'constantinople'],
-    })
-    st.equal(c._isSupportedHardfork('byzantium'), true, 'should return true for supported HF')
-    const msg = 'should return false for unsupported HF'
-    st.equal(c._isSupportedHardfork('spuriousDragon'), false, msg)
-
-    st.end()
-  })
-
   t.test('Should handle initialization errors', function (st: tape.Test) {
     let f = function () {
       new Common({ chain: 'chainnotexisting' })
@@ -85,16 +70,6 @@ tape('[Common/Chains]: Initialization / Chain params', function (t: tape.Test) {
     msg = 'should throw an exception on non-existing hardfork'
     st.throws(f, /not supported$/, msg) // eslint-disable-line no-new
 
-    f = function () {
-      new Common({
-        chain: 'mainnet',
-        hardfork: 'spuriousDragon',
-        supportedHardforks: ['byzantium', 'constantinople'],
-      })
-    }
-    msg = 'should throw an exception on conflicting active/supported HF params'
-    st.throws(f, /supportedHardforks$/, msg) // eslint-disable-line no-new
-
     st.end()
   })
 
diff --git a/packages/common/tests/hardforks.spec.ts b/packages/common/tests/hardforks.spec.ts
index 39aea7bc90..2a6e3cb5f2 100644
--- a/packages/common/tests/hardforks.spec.ts
+++ b/packages/common/tests/hardforks.spec.ts
@@ -164,20 +164,6 @@ tape('[Common]: Hardfork logic', function (t: tape.Test) {
     msg = 'should return 4 active hardforks for Ropsten up to block 10'
     st.equal(c.activeHardforks(10).length, 4, msg)
 
-    c = new Common({
-      chain: Chain.Ropsten,
-      supportedHardforks: [Hardfork.SpuriousDragon, Hardfork.Byzantium, Hardfork.Constantinople],
-    })
-    msg = 'should return 3 active HFs when restricted to supported HFs'
-    st.equal(c.activeHardforks(null, { onlySupported: true }).length, 3, msg)
-
-    c = new Common({
-      chain: Chain.Ropsten,
-      supportedHardforks: [Hardfork.SpuriousDragon, Hardfork.Byzantium, Hardfork.Dao],
-    })
-    msg = 'should return 2 active HFs when restricted to supported HFs'
-    st.equal(c.activeHardforks(null, { onlySupported: true }).length, 2, msg)
-
     c = new Common({ chain: Chain.Mainnet })
     msg = 'should return correct number of active HFs for mainnet'
     st.equal(c.activeHardforks().length, 13, msg)
@@ -201,13 +187,6 @@ tape('[Common]: Hardfork logic', function (t: tape.Test) {
     msg = 'should return spuriousDragon as latest active HF for Ropsten for block 10'
     st.equal(c.activeHardfork(10), Hardfork.SpuriousDragon, msg)
 
-    c = new Common({
-      chain: Chain.Ropsten,
-      supportedHardforks: [Hardfork.TangerineWhistle, Hardfork.SpuriousDragon],
-    })
-    msg = 'should return spuriousDragon as latest active HF for Ropsten with limited supported HFs'
-    st.equal(c.activeHardfork(null, { onlySupported: true }), Hardfork.SpuriousDragon, msg)
-
     c = new Common({ chain: Chain.Rinkeby })
     msg = 'should return correct latest active HF for Rinkeby'
     st.equal(c.activeHardfork(), Hardfork.London, msg)
@@ -264,14 +243,8 @@ tape('[Common]: Hardfork logic', function (t: tape.Test) {
     let msg = 'Ropsten, constantinople >= byzantium (provided) -> true'
     st.equal(c.hardforkGteHardfork(Hardfork.Constantinople, Hardfork.Byzantium), true, msg)
 
-    msg = 'Ropsten, dao >= chainstart (provided), onlyActive -> false'
-    st.equal(
-      c.hardforkGteHardfork(Hardfork.Dao, Hardfork.Chainstart, {
-        onlyActive: true,
-      }),
-      false,
-      msg
-    )
+    msg = 'Ropsten, dao >= chainstart (provided) -> false'
+    st.equal(c.hardforkGteHardfork(Hardfork.Dao, Hardfork.Chainstart), false, msg)
 
     msg = 'Ropsten, byzantium >= byzantium (provided) -> true'
     st.equal(c.hardforkGteHardfork(Hardfork.Byzantium, Hardfork.Byzantium), true, msg)
@@ -286,9 +259,6 @@ tape('[Common]: Hardfork logic', function (t: tape.Test) {
     msg = 'Ropsten, byzantium (set) >= spuriousDragon -> true (alias function)'
     st.equal(c.gteHardfork(Hardfork.SpuriousDragon), true, msg)
 
-    msg = 'Ropsten, byzantium (set) >= spuriousDragon, onlyActive -> true'
-    st.equal(c.hardforkGteHardfork(null, Hardfork.SpuriousDragon, { onlyActive: true }), true, msg)
-
     msg = 'Ropsten, byzantium (set) >= byzantium -> true'
     st.equal(c.hardforkGteHardfork(null, Hardfork.Byzantium), true, msg)
 
@@ -320,26 +290,10 @@ tape('[Common]: Hardfork logic', function (t: tape.Test) {
     msg = 'should return false for a non-existing HF (provided) on Ropsten'
     st.equal(c.hardforkIsActiveOnChain('notexistinghardfork'), false, msg)
 
-    let f = function () {
-      c.hardforkIsActiveOnChain(Hardfork.SpuriousDragon, { onlySupported: true })
-    }
-    msg = 'should not throw with unsupported Hf (provided) and onlySupported set to false'
-    st.doesNotThrow(f, /unsupported hardfork$/, msg)
-
     c = new Common({ chain: Chain.Ropsten, hardfork: Hardfork.Byzantium })
     msg = 'should return true for byzantium (set) on Ropsten'
     st.equal(c.hardforkIsActiveOnChain(), true, msg)
 
-    c = new Common({
-      chain: Chain.Ropsten,
-      supportedHardforks: [Hardfork.Byzantium, Hardfork.Constantinople],
-    })
-    f = function () {
-      c.hardforkIsActiveOnChain(Hardfork.SpuriousDragon, { onlySupported: true })
-    }
-    msg = 'should throw with unsupported Hf and onlySupported set to true'
-    st.throws(f, /not set as supported in supportedHardforks$/, msg)
-
     st.end()
   })
 
diff --git a/packages/common/tests/params.spec.ts b/packages/common/tests/params.spec.ts
index 4e27a234e8..8aa81eaefc 100644
--- a/packages/common/tests/params.spec.ts
+++ b/packages/common/tests/params.spec.ts
@@ -32,34 +32,17 @@ tape('[Common]: Parameter access for param(), paramByHardfork()', function (t: t
   })
 
   t.test('Error cases for param(), paramByHardfork()', function (st: tape.Test) {
-    let c = new Common({ chain: Chain.Mainnet })
+    const c = new Common({ chain: Chain.Mainnet })
 
-    let f = function () {
+    const f = function () {
       c.paramByHardfork('gasPrizes', 'ecAdd', 'byzantium')
     }
-    let msg = 'Should throw when called with non-existing topic'
+    const msg = 'Should throw when called with non-existing topic'
     st.throws(f, /Topic gasPrizes not defined$/, msg)
 
     c.setHardfork(Hardfork.Byzantium)
     st.equal(c.param('gasPrices', 'ecAdd'), 500, 'Should return correct value for HF set in class')
 
-    c = new Common({
-      chain: Chain.Mainnet,
-      hardfork: Hardfork.Byzantium,
-      supportedHardforks: [Hardfork.Byzantium, Hardfork.Constantinople],
-    })
-    f = function () {
-      c.paramByHardfork('gasPrices', 'expByte', 'spuriousDragon')
-    }
-    msg = 'Should throw when calling param() with an unsupported hardfork'
-    st.throws(f, /supportedHardforks$/, msg)
-
-    f = function () {
-      c.paramByBlock('gasPrices', 'expByte', 0)
-    }
-    msg = 'Should throw when calling paramByBlock() with an unsupported hardfork'
-    st.throws(f, /supportedHardforks$/, msg)
-
     st.end()
   })
 
diff --git a/packages/vm/src/index.ts b/packages/vm/src/index.ts
index 00168b970f..5fdf648a46 100644
--- a/packages/vm/src/index.ts
+++ b/packages/vm/src/index.ts
@@ -1,7 +1,7 @@
 import { SecureTrie as Trie } from 'merkle-patricia-tree'
 import { Account, Address, BNLike } from 'ethereumjs-util'
 import Blockchain from '@ethereumjs/blockchain'
-import Common, { Chain } from '@ethereumjs/common'
+import Common, { Chain, Hardfork } from '@ethereumjs/common'
 import { StateManager, DefaultStateManager } from './state/index'
 import { default as runCode, RunCodeOpts } from './runCode'
 import { default as runCall, RunCallOpts } from './runCall'
@@ -205,30 +205,34 @@ export default class VM extends AsyncEventEmitter {
       this._common = opts.common
     } else {
       const DEFAULT_CHAIN = Chain.Mainnet
-      const supportedHardforks = [
-        'chainstart',
-        'homestead',
-        'dao',
-        'tangerineWhistle',
-        'spuriousDragon',
-        'byzantium',
-        'constantinople',
-        'petersburg',
-        'istanbul',
-        'muirGlacier',
-        'berlin',
-        'arrowGlacier',
-      ]
-
-      this._common = new Common({
-        chain: DEFAULT_CHAIN,
-        supportedHardforks,
-      })
+
+      this._common = new Common({ chain: DEFAULT_CHAIN })
     }
     this._common.on('hardforkChanged', () => {
       this._opcodes = getOpcodesForHF(this._common)
     })
 
+    const supportedHardforks = [
+      Hardfork.Chainstart,
+      Hardfork.Homestead,
+      Hardfork.Dao,
+      Hardfork.TangerineWhistle,
+      Hardfork.SpuriousDragon,
+      Hardfork.Byzantium,
+      Hardfork.Constantinople,
+      Hardfork.Petersburg,
+      Hardfork.Istanbul,
+      Hardfork.MuirGlacier,
+      Hardfork.Berlin,
+      Hardfork.London,
+      Hardfork.ArrowGlacier,
+    ]
+    if (!supportedHardforks.includes(this._common.hardfork() as Hardfork)) {
+      throw new Error(
+        `Hardfork ${this._common.hardfork()} not set as supported in supportedHardforks`
+      )
+    }
+
     // Set list of opcodes based on HF
     // TODO: make this EIP-friendly
     this._opcodes = getOpcodesForHF(this._common)
diff --git a/packages/vm/tests/api/index.spec.ts b/packages/vm/tests/api/index.spec.ts
index 82252c52bc..17f55173cc 100644
--- a/packages/vm/tests/api/index.spec.ts
+++ b/packages/vm/tests/api/index.spec.ts
@@ -66,6 +66,26 @@ tape('VM -> basic instantiation / boolean switches', (t) => {
   })
 })
 
+tape('VM -> supportedHardforks', (t) => {
+  t.test('should throw when common is set to an unsupported hardfork', async (st) => {
+    const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Merge })
+    try {
+      await VM.create({ common })
+      st.fail('should have failed for unsupported hardfork')
+    } catch (e: any) {
+      st.ok(e.message.includes('supportedHardforks'))
+    }
+    st.end()
+  })
+
+  t.test('should succeed when common is set to a supported hardfork', async (st) => {
+    const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium })
+    const vm = await VM.create({ common })
+    st.equal(vm._common.hardfork(), Hardfork.Byzantium)
+    st.end()
+  })
+})
+
 tape('VM -> common (chain, HFs, EIPs)', (t) => {
   t.test('should accept a common object as option', async (st) => {
     const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul })