fix using ethereumjsèvm return values

pull/3262/head^2
yann300 2 years ago committed by Aniket
parent 0f2161fc21
commit 16a13f3b80
  1. 6
      apps/remix-ide/src/blockchain/providers/worker-vm.ts
  2. 2
      libs/remix-lib/src/execution/txListener.ts
  3. 4
      libs/remix-lib/src/execution/txRunnerVM.ts
  4. 1
      libs/remix-lib/src/index.ts
  5. 12
      libs/remix-simulator/src/VmProxy.ts
  6. 32
      libs/remix-simulator/src/methods/blocks.ts
  7. 62
      libs/remix-simulator/src/methods/transactions.ts

@ -1,4 +1,5 @@
import { Provider } from '@remix-project/remix-simulator'
import { bigIntToHex } from '@ethereumjs/util'
let provider: Provider = null
self.onmessage = (e: MessageEvent) => {
@ -14,7 +15,10 @@ self.onmessage = (e: MessageEvent) => {
{
if (provider) {
provider.sendAsync(data.query, (error, result) => {
result = JSON.parse(JSON.stringify(result))
result = JSON.parse(JSON.stringify(result, (key, value) => {
if (typeof value === 'bigint') return bigIntToHex(value)
return value
}))
self.postMessage({
cmd: 'sendAsyncResult',
error,

@ -10,7 +10,7 @@ function addExecutionCosts (txResult, tx, execResult) {
if (txResult) {
if (execResult) {
tx.returnValue = execResult.returnValue
if (execResult.gasUsed) tx.executionCost = execResult.gasUsed.toString(10)
if (execResult.executionGasUsed) tx.executionCost = execResult.executionGasUsed.toString(10)
}
if (txResult.receipt && txResult.receipt.gasUsed) tx.transactionCost = txResult.receipt.gasUsed.toString(10)
}

@ -52,7 +52,7 @@ export class TxRunnerVM {
this.nextNonceForCall = 0
}
execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) {
execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback: VMExecutionCallBack) {
let data = args.data
if (data.slice(0, 2) !== '0x') {
data = '0x' + data
@ -136,7 +136,7 @@ export class TxRunnerVM {
runBlockInVm (tx, block, callback) {
this.getVMObject().vm.runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false, skipNonce: true }).then((results: RunBlockResult) => {
const result = results.results[0]
const result: RunTxResult = results.results[0]
/*if (result) {
const status = result.execResult.exceptionError ? 0 : 1
result.receipt.status

@ -18,6 +18,7 @@ import * as txResultHelper from './helpers/txResultHelper'
export { ConsoleLogs } from './helpers/hhconsoleSigs'
export { ICompilerApi, ConfigurationSettings } from './types/ICompilerApi'
export { QueryParams } from './query-params'
export { VMxecutionResult } from './execution/txRunnerVM'
const helpers = {
ui: uiHelper,

@ -8,6 +8,8 @@ import utils from 'web3-utils'
import { ethers } from 'ethers'
import { VMContext } from './vm-context'
import type { InterpreterStep } from '@ethereumjs/evm/dist/interpreter'
import type { AfterTxEvent } from '@ethereumjs/vm'
import type { TypedTransaction } from '@ethereumjs/tx'
export class VmProxy {
vmContext: VMContext
@ -90,10 +92,10 @@ export class VmProxy {
this.vm.evm.events.on('step', async (data: InterpreterStep) => {
await this.pushTrace(data)
})
this.vm.events.on('afterTx', async (data: any) => {
this.vm.events.on('afterTx', async (data: AfterTxEvent) => {
await this.txProcessed(data)
})
this.vm.events.on('beforeTx', async (data: any) => {
this.vm.events.on('beforeTx', async (data: TypedTransaction) => {
await this.txWillProcess(data)
})
}
@ -104,7 +106,7 @@ export class VmProxy {
return ret
}
async txWillProcess (data) {
async txWillProcess (data: TypedTransaction) {
this.incr++
this.processingHash = bufferToHex(data.hash())
this.vmTraces[this.processingHash] = {
@ -140,12 +142,12 @@ export class VmProxy {
this.processingIndex = 0
}
async txProcessed (data) {
async txProcessed (data: AfterTxEvent) {
const lastOp = this.vmTraces[this.processingHash].structLogs[this.processingIndex - 1]
if (lastOp) {
lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT'
}
const gasUsed = '0x' + data.gasUsed.toString(16)
const gasUsed = '0x' + data.totalGasSpent.toString(16)
this.vmTraces[this.processingHash].gas = gasUsed
this.txsReceipt[this.processingHash].gasUsed = gasUsed
const logs = []

@ -51,22 +51,22 @@ export class Blocks {
blockHash: '0x' + block.hash().toString('hex'),
blockNumber: bigIntToHex(block.header.number),
from: receipt.from,
gas: toHex(receipt.gas),
gas: bigIntToHex(receipt.gas),
chainId: '0xd05',
gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash,
input: receipt.input,
nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX,
value: receipt.value === '0x' ? '0x0' : receipt.value,
value: bigIntToHex(tx.value),
to: receipt.to ? receipt.to : null
}
}
})
const b = {
baseFeePerGas: '0x01',
number: this.toHex(block.header.number),
hash: this.toHex(block.hash()),
number: bigIntToHex(block.header.number),
hash: block.hash(),
parentHash: this.toHex(block.header.parentHash),
nonce: this.toHex(block.header.nonce),
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
@ -74,13 +74,13 @@ export class Blocks {
transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
stateRoot: this.toHex(block.header.stateRoot),
miner: this.coinbase,
difficulty: this.toHex(block.header.difficulty),
totalDifficulty: this.toHex((block.header as any).totalDifficulty),
difficulty: bigIntToHex(block.header.difficulty),
totalDifficulty: bigIntToHex((block.header as any).totalDifficulty || 0),
extraData: this.toHex(block.header.extraData),
size: '0x027f07', // 163591
gasLimit: this.toHex(block.header.gasLimit),
gasUsed: this.toHex(block.header.gasUsed),
timestamp: this.toHex(block.header.timestamp),
gasLimit: bigIntToHex(block.header.gasLimit),
gasUsed: bigIntToHex(block.header.gasUsed),
timestamp: bigIntToHex(block.header.timestamp),
transactions,
uncles: []
}
@ -112,14 +112,14 @@ export class Blocks {
input: receipt.input,
nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX,
value: receipt.value === '0x' ? '0x0' : receipt.value,
value: bigIntToHex(tx.value),
to: receipt.to ? receipt.to : null
}
}
})
const b = {
baseFeePerGas: '0x01',
number: this.toHex(block.header.number),
number: bigIntToHex(block.header.number),
hash: this.toHex(block.hash()),
parentHash: this.toHex(block.header.parentHash),
nonce: this.toHex(block.header.nonce),
@ -128,13 +128,13 @@ export class Blocks {
transactionsRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
stateRoot: this.toHex(block.header.stateRoot),
miner: this.coinbase,
difficulty: this.toHex(block.header.difficulty),
totalDifficulty: this.toHex((block.header as any).totalDifficulty),
difficulty: bigIntToHex(block.header.difficulty),
totalDifficulty: bigIntToHex((block.header as any).totalDifficulty || 0),
extraData: this.toHex(block.header.extraData),
size: '0x027f07', // 163591
gasLimit: this.toHex(block.header.gasLimit),
gasUsed: this.toHex(block.header.gasUsed),
timestamp: this.toHex(block.header.timestamp),
gasLimit: bigIntToHex(block.header.gasLimit),
gasUsed: bigIntToHex(block.header.gasUsed),
timestamp: bigIntToHex(block.header.timestamp),
transactions,
uncles: []
}

@ -1,11 +1,24 @@
import { toHex, toDecimal } from 'web3-utils'
import { bigIntToHex } from '@ethereumjs/util'
import { toChecksumAddress, BN, Address } from 'ethereumjs-util'
import { processTx } from './txProcess'
import { execution } from '@remix-project/remix-lib'
import { ethers } from 'ethers'
import { VMxecutionResult } from '@remix-project/remix-lib'
import { RunTxResult } from '@ethereumjs/vm'
import { Log, EvmError } from '@ethereumjs/evm'
const TxRunnerVM = execution.TxRunnerVM
const TxRunner = execution.TxRunner
export type VMExecResult = {
exceptionError: EvmError
executionGasUsed: bigint
gas: bigint
gasRefund: bigint
logs: Log[]
returnValue: Buffer
}
export class Transactions {
vmContext
accounts
@ -69,12 +82,20 @@ export class Transactions {
if (payload.params && payload.params.length > 0 && payload.params[0].from) {
payload.params[0].from = toChecksumAddress(payload.params[0].from)
}
processTx(this.txRunnerInstance, payload, false, (error, result) => {
processTx(this.txRunnerInstance, payload, false, (error, result: VMxecutionResult) => {
if (!error && result) {
this.vmContext.addBlock(result.block)
const hash = '0x' + result.tx.hash().toString('hex')
this.vmContext.trackTx(hash, result.block, result.tx)
this.vmContext.trackExecResult(hash, result.result.execResult)
const execResult: VMExecResult = {
exceptionError: result.result.execResult.exceptionError,
executionGasUsed: result.result.execResult.executionGasUsed,
gas: result.result.execResult.gas,
gasRefund: result.result.execResult.gasRefund,
logs: result.result.execResult.logs,
returnValue: result.result.execResult.returnValue
}
this.vmContext.trackExecResult(hash, execResult)
return cb(null, result.transactionHash)
}
cb(error)
@ -105,7 +126,7 @@ export class Transactions {
transactionHash: receipt.hash,
transactionIndex: this.TX_INDEX,
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
blockNumber: bigIntToHex(txBlock.header.number),
gasUsed: receipt.gasUsed,
cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block
contractAddress: receipt.contractAddress,
@ -133,9 +154,10 @@ export class Transactions {
payload.params[0].gas = 10000000 * 10
processTx(this.txRunnerInstance, payload, true, (error, { result }) => {
processTx(this.txRunnerInstance, payload, true, (error, value: VMxecutionResult) => {
const result: RunTxResult = value.result
if (error) return cb(error)
if (result.status === '0x0') {
if ((result as any).receipt === '0x0') {
try {
const msg = result.execResult.returnValue
const abiCoder = new ethers.utils.AbiCoder()
@ -145,11 +167,11 @@ export class Transactions {
return cb(e.message)
}
}
let gasUsed = result.execResult.gasUsed.toNumber()
let gasUsed = result.execResult.executionGasUsed
if (result.execResult.gasRefund) {
gasUsed += result.execResult.gasRefund.toNumber()
gasUsed += result.execResult.gasRefund
}
cb(null, Math.ceil(gasUsed + (15 * gasUsed) / 100))
cb(null, Math.ceil(Number(gasUsed) + (15 * Number(gasUsed)) / 100))
})
}
@ -183,7 +205,15 @@ export class Transactions {
this.vmContext.addBlock(result.block)
const hash = '0x' + result.tx.hash().toString('hex')
this.vmContext.trackTx(hash, result.block, result.tx)
this.vmContext.trackExecResult(hash, result.result.execResult)
const execResult: VMExecResult = {
exceptionError: result.result.execResult.exceptionError,
executionGasUsed: result.result.execResult.executionGasUsed,
gas: result.result.execResult.gas,
gasRefund: result.result.execResult.gasRefund,
logs: result.result.execResult.logs,
returnValue: result.result.execResult.returnValue
}
this.vmContext.trackExecResult(hash, execResult)
this.tags[tag] = result.transactionHash
// calls are not supposed to return a transaction hash. we do this for keeping track of it and allowing debugging calls.
const returnValue = `0x${result.result.execResult.returnValue.toString('hex') || '0'}`
@ -222,7 +252,7 @@ export class Transactions {
// TODO: params to add later
const r: Record<string, unknown> = {
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
blockNumber: bigIntToHex(txBlock.header.number),
from: receipt.from,
gas: toHex(receipt.gas),
chainId: '0xd05',
@ -230,9 +260,9 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash,
input: receipt.input,
nonce: '0x' + tx.nonce.toString('hex'),
nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX,
value: receipt.value
value: bigIntToHex(tx.value)
// "value":"0xf3dbb76162000" // 4290000000000000
// "v": "0x25", // 37
// "r": "0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea",
@ -271,7 +301,7 @@ export class Transactions {
// TODO: params to add later
const r: Record<string, unknown> = {
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
blockNumber: bigIntToHex(txBlock.header.number),
from: receipt.from,
gas: toHex(receipt.gas),
chainId: '0xd05',
@ -279,7 +309,7 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash,
input: receipt.input,
nonce: '0x' + tx.nonce.toString('hex'),
nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX,
value: receipt.value
// "value":"0xf3dbb76162000" // 4290000000000000
@ -316,7 +346,7 @@ export class Transactions {
// TODO: params to add later
const r: Record<string, unknown> = {
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
blockNumber: bigIntToHex(txBlock.header.number),
from: receipt.from,
gas: toHex(receipt.gas),
// 'gasPrice': '2000000000000', // 0x123
@ -324,7 +354,7 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash,
input: receipt.input,
nonce: '0x' + tx.nonce.toString('hex'),
nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX,
value: receipt.value
// "value":"0xf3dbb76162000" // 4290000000000000

Loading…
Cancel
Save