diff --git a/libs/remix-simulator/src/VmProxy.ts b/libs/remix-simulator/src/VmProxy.ts index a2015d6296..e30357510e 100644 --- a/libs/remix-simulator/src/VmProxy.ts +++ b/libs/remix-simulator/src/VmProxy.ts @@ -7,13 +7,14 @@ import { toChecksumAddress, BN, keccak, bufferToHex, Address, toBuffer } from 'e import utils from 'web3-utils' import { ethers } from 'ethers' import { VMContext } from './vm-context' +import type { StateManager } from '@ethereumjs/statemanager' import type { InterpreterStep } from '@ethereumjs/evm/dist/interpreter' -import type { AfterTxEvent } from '@ethereumjs/vm' +import type { AfterTxEvent, VM } from '@ethereumjs/vm' import type { TypedTransaction } from '@ethereumjs/tx' export class VmProxy { vmContext: VMContext - vm + vm: VM vmTraces txs txsReceipt @@ -41,9 +42,11 @@ export class VmProxy { utils txsMapBlock blocks + stateCopy: StateManager constructor (vmContext: VMContext) { this.vmContext = vmContext + this.stateCopy this.vm = null this.vmTraces = {} this.txs = {} @@ -107,6 +110,7 @@ export class VmProxy { } async txWillProcess (data: TypedTransaction) { + this.stateCopy = await this.vm.stateManager.copy() this.incr++ this.processingHash = bufferToHex(data.hash()) this.vmTraces[this.processingHash] = { @@ -132,7 +136,7 @@ export class VmProxy { this.storageCache['after_' + this.processingHash] = {} if (data.to) { try { - const storage = await this.vm.stateManager.dumpStorage(data.to) + const storage = await this.stateCopy.dumpStorage(data.to) this.storageCache[this.processingHash][tx['to']] = storage } catch (e) { console.log(e) @@ -195,6 +199,7 @@ export class VmProxy { this.processingIndex = null this.processingAddress = null this.previousDepth = 0 + this.stateCopy = null } async pushTrace (data: InterpreterStep) { @@ -257,7 +262,7 @@ export class VmProxy { if (!this.storageCache[this.processingHash][this.processingAddress]) { ((processingHash, processingAddress, self) => { const account = Address.fromString(processingAddress) - self.vm.stateManager.dumpStorage(account).then((storage) => { + self.stateCopy.dumpStorage(account).then((storage) => { self.storageCache[processingHash][processingAddress] = storage }).catch(console.log) })(this.processingHash, this.processingAddress, this) diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index 959ec28521..0aa055f83f 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -6,20 +6,37 @@ const { LogsManager } = execution import { VmProxy } from './VmProxy' import { VM } from '@ethereumjs/vm' import { Common } from '@ethereumjs/common' +import { Trie } from '@ethereumjs/trie' import { DefaultStateManager } from '@ethereumjs/statemanager' import { StorageDump } from '@ethereumjs/statemanager/dist/interface' import { Block } from '@ethereumjs/block' import { Transaction } from '@ethereumjs/tx' import { bigIntToHex } from '@ethereumjs/util' +/** + * Options for constructing a {@link StateManager}. + */ +export interface DefaultStateManagerOpts { + /** + * A {@link Trie} instance + */ + trie?: Trie + /** + * Option to prefix codehashes in the database. This defaults to `true`. + * If this is disabled, note that it is possible to corrupt the trie, by deploying code + * which code is equal to the preimage of a trie-node. + * E.g. by putting the code `0x80` into the empty trie, will lead to a corrupted trie. + */ + prefixCodeHashes?: boolean +} + /* extend vm state manager and instanciate VM */ - class StateManagerCommonStorageDump extends DefaultStateManager { keyHashes: { [key: string]: string } - constructor () { - super() + constructor (opts: DefaultStateManagerOpts = {}) { + super(opts) this.keyHashes = {} } @@ -28,6 +45,12 @@ class StateManagerCommonStorageDump extends DefaultStateManager { return super.putContractStorage(address, key, value) } + copy(): StateManagerCommonStorageDump { + return new StateManagerCommonStorageDump({ + trie: this._trie.copy(false), + }) + } + async dumpStorage (address): Promise { return new Promise((resolve, reject) => { this._getStorageTrie(address)