Merge branch 'master' into foundry

pull/3285/head
bunsenstraat 2 years ago committed by GitHub
commit bffe6e461b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      libs/remix-debug/src/trace/traceCache.ts
  2. 12
      libs/remix-debug/src/trace/traceManager.ts
  3. 4
      libs/remix-debug/test/traceManager.ts
  4. 2
      libs/remix-lib/src/execution/txRunnerWeb3.ts
  5. 45
      libs/remix-simulator/src/VmProxy.ts
  6. 1
      libs/remix-simulator/src/methods/transactions.ts
  7. 15
      libs/remix-simulator/src/vm-context.ts

@ -17,6 +17,7 @@ export class TraceCache {
memoryChanges
storageChanges
sstore
formattedMemory
constructor () {
this.init()
@ -36,6 +37,7 @@ export class TraceCache {
this.addresses = []
this.callDataChanges = []
this.memoryChanges = []
this.formattedMemory = {}
this.storageChanges = []
this.sstore = {} // all sstore occurence in the trace
}
@ -53,6 +55,10 @@ export class TraceCache {
this.memoryChanges.push(value)
}
setFormattedMemory (stepIndex, memory) {
this.formattedMemory[stepIndex] = memory
}
// outOfGas has been removed because gas left logging is apparently made differently
// in the vm/geth/eth. TODO add the error property (with about the error in all clients)
pushCall (step, index, address, callStack, reverted) {

@ -190,13 +190,21 @@ export class TraceManager {
return this.traceCache.contractCreation[token]
}
getMemoryAt (stepIndex) {
getMemoryAt (stepIndex, format = true) {
this.checkRequestedStep(stepIndex)
const lastChanges = util.findLowerBoundValue(stepIndex, this.traceCache.memoryChanges)
if (lastChanges === null) {
throw new Error('no memory found')
}
return this.trace[lastChanges].memory
if (!format) {
return this.trace[lastChanges].memory
}
if (this.traceCache.formattedMemory[lastChanges]) {
return this.traceCache.formattedMemory[lastChanges]
}
const memory = util.formatMemory(this.trace[lastChanges].memory)
this.traceCache.setFormattedMemory(lastChanges, memory)
return memory
}
getCurrentPC (stepIndex) {

@ -164,7 +164,7 @@ tape('TraceManager', function (t) {
t.test('TraceManager.getMemoryAt', function (st) {
st.plan(3)
try {
const result = traceManager.getMemoryAt(0)
const result = traceManager.getMemoryAt(0, false)
console.log(result)
st.ok(result.length === 0)
} catch (error) {
@ -172,7 +172,7 @@ tape('TraceManager', function (t) {
}
try {
const result = traceManager.getMemoryAt(34)
const result = traceManager.getMemoryAt(34, false)
console.log(result)
st.ok(result.length === 3)
st.ok(result[2] === '0000000000000000000000000000000000000000000000000000000000000060')

@ -61,7 +61,7 @@ export class TxRunnerWeb3 {
tx = await tryTillTxAvailable(resp, this.getWeb3())
currentDateTime = new Date();
const end = currentDateTime.getTime() / 1000
console.log('stopwatch', end - start)
console.log('tx duration', end - start)
resolve({
receipt,
tx,

@ -43,6 +43,8 @@ export class VmProxy {
txsMapBlock
blocks
stateCopy: StateManager
flagDoNotRecordEVMSteps: boolean
lastMemoryUpdate: Array<string>
constructor (vmContext: VMContext) {
this.vmContext = vmContext
@ -85,6 +87,7 @@ export class VmProxy {
this.utils = utils
this.txsMapBlock = {}
this.blocks = {}
this.lastMemoryUpdate = []
}
setVM (vm) {
@ -109,7 +112,13 @@ export class VmProxy {
return ret
}
flagNextAsDoNotRecordEvmSteps () {
this.flagDoNotRecordEVMSteps = true
}
async txWillProcess (data: TypedTransaction) {
if (this.flagDoNotRecordEVMSteps) return
this.lastMemoryUpdate = []
this.stateCopy = await this.vm.stateManager.copy()
this.incr++
this.processingHash = bufferToHex(data.hash())
@ -148,6 +157,10 @@ export class VmProxy {
}
async txProcessed (data: AfterTxEvent) {
if (this.flagDoNotRecordEVMSteps) {
this.flagDoNotRecordEVMSteps = false
return
}
const lastOp = this.vmTraces[this.processingHash].structLogs[this.processingIndex - 1]
if (lastOp) {
lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT'
@ -181,9 +194,15 @@ export class VmProxy {
const to = this.txs[this.processingHash].to
if (to) {
try {
const account = Address.fromString(to)
const storage = await this.vm.stateManager.dumpStorage(account)
this.storageCache['after_' + this.processingHash][to] = storage
await (async (processingHash, processingAddress, self) => {
try {
const account = Address.fromString(processingAddress)
const storage = await self.vm.stateManager.dumpStorage(account)
self.storageCache['after_' + processingHash][processingAddress] = storage
} catch (e) {
console.log(e)
}
})(this.processingHash, to, this)
} catch (e) {
console.log(e)
}
@ -191,8 +210,9 @@ export class VmProxy {
if (data.createdAddress) {
const address = data.createdAddress.toString()
this.vmTraces[this.processingHash].return = toChecksumAddress(address)
this.txsReceipt[this.processingHash].contractAddress = toChecksumAddress(address)
const checksumedAddress = toChecksumAddress(address)
this.vmTraces[this.processingHash].return = checksumedAddress
this.txsReceipt[this.processingHash].contractAddress = checksumedAddress
} else if (data.execResult.returnValue) {
this.vmTraces[this.processingHash].return = '0x' + data.execResult.returnValue.toString('hex')
} else {
@ -205,6 +225,7 @@ export class VmProxy {
}
async pushTrace (data: InterpreterStep) {
if (this.flagDoNotRecordEVMSteps) return
try {
const depth = data.depth + 1 // geth starts the depth from 1
if (!this.processingHash) {
@ -220,21 +241,27 @@ export class VmProxy {
}
const step = {
stack: hexListFromBNs(data.stack),
memory: formatMemory(data.memory),
storage: {},
memory: null,
op: data.opcode.name,
pc: data.pc,
gasCost: data.opcode.fee.toString(),
gas: data.gasLeft.toString(),
depth: depth
}
if (previousOpcode && (previousOpcode.op === 'CALLDATACOPY' || previousOpcode.op === 'CODECOPY' || previousOpcode.op === 'EXTCODECOPY' || previousOpcode.op === 'RETURNDATACOPY' || previousOpcode.op === 'MSTORE' || previousOpcode.op === 'MSTORE8')) {
step.memory = data.memory
this.lastMemoryUpdate = step.memory
}
this.vmTraces[this.processingHash].structLogs.push(step)
// Track hardhat console.log call
if (step.op === 'STATICCALL' && step.stack[step.stack.length - 2] === '0x000000000000000000000000000000000000000000636f6e736f6c652e6c6f67') {
const stackLength = step.stack.length
const payloadStart = parseInt(step.stack[stackLength - 3], 16)
const memory = step.memory.join('')
let payload = memory.substring(payloadStart * 2, memory.length)
const memory = formatMemory(data.memory)
const memoryStr = memory.join('')
let payload = memoryStr.substring(payloadStart * 2, memoryStr.length)
const fnselectorStr = payload.substring(0, 8)
const fnselectorStrInHex = '0x' + fnselectorStr
const fnselector = parseInt(fnselectorStrInHex)
@ -279,7 +306,7 @@ export class VmProxy {
}
}
if (previousOpcode && previousOpcode.op === 'SHA3') {
const preimage = this.getSha3Input(previousOpcode.stack, previousOpcode.memory)
const preimage = this.getSha3Input(previousOpcode.stack, formatMemory(this.lastMemoryUpdate))
const imageHash = step.stack[step.stack.length - 1].replace('0x', '')
this.sha3Preimages[imageHash] = {
preimage: preimage

@ -155,6 +155,7 @@ export class Transactions {
payload.params[0].gas = 10000000 * 10
this.vmContext.web3().flagNextAsDoNotRecordEvmSteps()
processTx(this.txRunnerInstance, payload, true, (error, value: VMexecutionResult) => {
const result: RunTxResult = value.result
if (error) return cb(error)

@ -79,21 +79,6 @@ class StateManagerCommonStorageDump extends DefaultStateManager {
})
})
}
async setStateRoot (stateRoot) {
await this._cache.flush()
if (!stateRoot.equals(this._trie.EMPTY_TRIE_ROOT)) {
const hasRoot = await this._trie.checkRoot(stateRoot)
if (!hasRoot) {
throw new Error('State trie does not contain state root')
}
}
this._trie.root = stateRoot
this._cache.clear()
this._storageTries = {}
}
}
export type CurrentVm = {

Loading…
Cancel
Save