diff --git a/packages/vm/lib/evm/opcodes/codes.ts b/packages/vm/lib/evm/opcodes/codes.ts index ad8692dee3..e0d98bec37 100644 --- a/packages/vm/lib/evm/opcodes/codes.ts +++ b/packages/vm/lib/evm/opcodes/codes.ts @@ -240,12 +240,15 @@ const hardforkOpcodes = [ 0x47: { name: 'SELFBALANCE', isAsync: false }, // EIP 1884 }, }, +] + +const eipOpcodes = [ { - hardforkName: 'berlin', + eip: 2315, opcodes: { - 0x5c: { name: 'BEGINSUB', isAsync: false }, // EIP 2315 - 0x5d: { name: 'RETURNSUB', isAsync: false }, // EIP 2315 - 0x5e: { name: 'JUMPSUB', isAsync: false }, // EIP 2315 + 0x5c: { name: 'BEGINSUB', isAsync: false }, + 0x5d: { name: 'RETURNSUB', isAsync: false }, + 0x5e: { name: 'JUMPSUB', isAsync: false }, }, }, ] @@ -288,6 +291,11 @@ export function getOpcodesForHF(common: Common): OpcodeList { opcodeBuilder = { ...opcodeBuilder, ...hardforkOpcodes[fork].opcodes } } } + for (const eipOps of eipOpcodes) { + if (common.isActivatedEIP(eipOps.eip)) { + opcodeBuilder = { ...opcodeBuilder, ...eipOps.opcodes } + } + } /* eslint-disable-next-line no-restricted-syntax */ for (const key in opcodeBuilder) { diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 181c1e4262..8d9dc30680 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -40,8 +40,9 @@ export interface VMOpts { * * ### Supported EIPs * + * - [EIP-2315](https://eips.ethereum.org/EIPS/eip-2315) - VM simple subroutines * - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) (`experimental`) - BLS12-381 precompiles - * - [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) (`experimental`) - Gas cost increases for state access opcodes + * - [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) - Gas cost increases for state access opcodes * * *Annotations:* * @@ -163,7 +164,7 @@ export default class VM extends AsyncEventEmitter { if (opts.common) { //EIPs - const supportedEIPs = [2537, 2565, 2718, 2929, 2930] + const supportedEIPs = [2315, 2537, 2565, 2718, 2929, 2930] for (const eip of opts.common.eips()) { if (!supportedEIPs.includes(eip)) { throw new Error(`${eip} is not supported by the VM`) diff --git a/packages/vm/tests/api/opcodes.spec.ts b/packages/vm/tests/api/opcodes.spec.ts index c63588d3a3..d48be50c77 100644 --- a/packages/vm/tests/api/opcodes.spec.ts +++ b/packages/vm/tests/api/opcodes.spec.ts @@ -4,6 +4,7 @@ import VM from '../../lib' tape('VM -> getActiveOpcodes()', (t) => { const CHAINID = 0x46 //istanbul opcode + const BEGINSUB = 0x5c // EIP-2315 opcode t.test('should not expose opcodes from a follow-up HF (istanbul -> petersburg)', (st) => { const common = new Common({ chain: 'mainnet', hardfork: 'petersburg' }) @@ -36,6 +37,26 @@ tape('VM -> getActiveOpcodes()', (t) => { st.end() }) + t.test('should expose opcodes when EIP is active', (st) => { + let common = new Common({ chain: 'mainnet', hardfork: 'istanbul', eips: [2315] }) + let vm = new VM({ common }) + st.equal( + vm.getActiveOpcodes().get(BEGINSUB)!.name, + 'BEGINSUB', + 'EIP-2315 opcode BEGINSUB exposed (EIP-2315 activated)' + ) + + common = new Common({ chain: 'mainnet', hardfork: 'istanbul' }) + vm = new VM({ common }) + st.equal( + vm.getActiveOpcodes().get(BEGINSUB), + undefined, + 'EIP-2315 opcode BEGINSUB not exposed (EIP-2315 not activated)' + ) + + st.end() + }) + t.test('should update opcodes on a hardfork change', async (st) => { const common = new Common({ chain: 'mainnet', hardfork: 'istanbul' }) const vm = new VM({ common })