UNPKG

@ethereumjs/vm

Version:
108 lines 4.37 kB
import { createEVM } from '@ethereumjs/evm'; import { EventEmitter } from 'eventemitter3'; import { createVM } from "./constructors.js"; import { paramsVM } from "./params.js"; /** * The VM is a state transition machine that executes EVM bytecode and updates the state. * It can be used to execute transactions, blocks, individual transactions, or snippets of EVM bytecode. * * A VM can be created with the constructor method: * * - {@link createVM} */ export class VM { /** * Instantiates a new {@link VM} Object. * * @deprecated The direct usage of this constructor is discouraged since * non-finalized async initialization might lead to side effects. Please * use the async {@link createVM} constructor instead (same API). * @param opts */ constructor(opts = {}) { this._isInitialized = false; /** * VM is run in DEBUG mode (default: false) * Taken from DEBUG environment variable * * Safeguards on debug() calls are added for * performance reasons to avoid string literal evaluation * @hidden */ this.DEBUG = false; this.common = opts.common; this.common.updateParams(opts.params ?? paramsVM); this.stateManager = opts.stateManager; this.blockchain = opts.blockchain; this.evm = opts.evm; this.events = new EventEmitter(); this._emit = async (topic, data) => { const listeners = this.events.listeners(topic); for (const listener of listeners) { if (listener.length === 2) { await new Promise((resolve) => { listener(data, resolve); }); } else { listener(data); } } }; this._opts = opts; this._setHardfork = opts.setHardfork ?? false; // Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables // Additional window check is to prevent vite browser bundling (and potentially other) to break this.DEBUG = typeof window === 'undefined' ? (process?.env?.DEBUG?.includes('ethjs') ?? false) : false; } /** * Returns a copy of the {@link VM} instance. * * Note that the returned copy will share the same db as the original for the blockchain and the statemanager. * * Associated caches will be deleted and caches will be re-initialized for a more short-term focused * usage, being less memory intense (the statemanager caches will switch to using an ORDERED_MAP cache * data structure more suitable for short-term usage, the trie node LRU cache will not be activated at all). * To fine-tune this behavior (if the shallow-copy-returned object has a longer life span e.g.) you can set * the `downlevelCaches` option to `false`. * * @param downlevelCaches Downlevel (so: adopted for short-term usage) associated state caches (default: true) */ async shallowCopy(downlevelCaches = true) { const common = this.common.copy(); common.setHardfork(this.common.hardfork()); const blockchain = this.blockchain.shallowCopy(); const stateManager = this.stateManager.shallowCopy(downlevelCaches); const evmOpts = { ...this.evm._optsCached, common: this._opts.evmOpts?.common?.copy() ?? common, blockchain: this._opts.evmOpts?.blockchain?.shallowCopy() ?? blockchain, stateManager: this._opts.evmOpts?.stateManager?.shallowCopy(downlevelCaches) ?? stateManager, }; const evmCopy = await createEVM(evmOpts); // TODO fixme (should copy the EVMInterface, not default EVM) return createVM({ stateManager, blockchain: this.blockchain, common, evm: evmCopy, setHardfork: this._setHardfork, profilerOpts: this._opts.profilerOpts, }); } /** * Return a compact error string representation of the object */ errorStr() { let hf = ''; try { hf = this.common.hardfork(); } catch { hf = 'error'; } const errorStr = `vm hf=${hf}`; return errorStr; } } //# sourceMappingURL=vm.js.map