Skip to content

Commit 4416bfb

Browse files
ryanioholgerd77
authored andcommitted
copy the vm first in case new blocks are executed during the call
1 parent fbe7fc9 commit 4416bfb

File tree

2 files changed

+70
-46
lines changed

2 files changed

+70
-46
lines changed

packages/client/lib/rpc/modules/eth.ts

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -117,27 +117,31 @@ export class Eth {
117117
async call(params: [RpcCallTx, string]) {
118118
const [transaction, blockOpt] = params
119119

120+
if (!this._vm) {
121+
throw new Error('missing vm')
122+
}
123+
124+
// use a copy of the vm in case new blocks are executed,
125+
// and to not make any underlying changes during the call
126+
const vm = this._vm.copy()
127+
120128
if (blockOpt !== 'latest') {
121-
const latest = await this.blockNumber()
122-
if (blockOpt !== latest) {
129+
const latest = await vm.blockchain.getLatestHeader()
130+
const number = latest.number.toString(16)
131+
if (blockOpt !== `0x${number}`) {
123132
return {
124133
code: INVALID_PARAMS,
125134
message: `Currently only "latest" block supported`,
126135
}
127136
}
128137
}
129138

130-
if (!this._vm) {
131-
throw new Error('missing vm')
132-
}
133-
134139
if (!transaction.gas) {
135140
// If no gas limit is specified use the last block gas limit as an upper bound.
136-
const latestHeader = await this._chain.getLatestHeader()
137-
transaction.gas = latestHeader.gasLimit as any
141+
const latest = await vm.blockchain.getLatestHeader()
142+
transaction.gas = latest.gasLimit as any
138143
}
139144

140-
const vm = this._vm.copy()
141145
const txData = { ...transaction, gasLimit: transaction.gas }
142146
const tx = Transaction.fromTxData(txData, { common: vm._common, freeze: false })
143147

@@ -171,27 +175,30 @@ export class Eth {
171175
async estimateGas(params: [RpcCallTx, string]) {
172176
const [transaction, blockOpt] = params
173177

178+
if (!this._vm) {
179+
throw new Error('missing vm')
180+
}
181+
182+
// use a copy of the vm in case new blocks are executed
183+
const vm = this._vm.copy()
184+
174185
if (blockOpt !== 'latest') {
175-
const latest = await this.blockNumber()
176-
if (blockOpt !== latest) {
186+
const latest = await vm.blockchain.getLatestHeader()
187+
const number = latest.number.toString(16)
188+
if (blockOpt !== `0x${number}`) {
177189
return {
178190
code: INVALID_PARAMS,
179191
message: `Currently only "latest" block supported`,
180192
}
181193
}
182194
}
183195

184-
if (!this._vm) {
185-
throw new Error('missing vm')
186-
}
187-
188196
if (!transaction.gas) {
189197
// If no gas limit is specified use the last block gas limit as an upper bound.
190-
const latestHeader = await this._chain.getLatestHeader()
191-
transaction.gas = latestHeader.gasLimit as any
198+
const latest = await this._chain.getLatestHeader()
199+
transaction.gas = latest.gasLimit as any
192200
}
193201

194-
const vm = this._vm.copy()
195202
const txData = { ...transaction, gasLimit: transaction.gas }
196203
const tx = Transaction.fromTxData(txData, { common: vm._common, freeze: false })
197204

@@ -220,22 +227,26 @@ export class Eth {
220227
async getBalance(params: [string, string]) {
221228
const [addressHex, blockOpt] = params
222229

230+
if (!this._vm) {
231+
throw new Error('missing vm')
232+
}
233+
234+
// use a copy of the vm in case new blocks are sync'd
235+
const vm = this._vm.copy()
236+
223237
if (blockOpt !== 'latest') {
224-
const latest = await this.blockNumber()
225-
if (blockOpt !== latest) {
238+
const latest = await vm.blockchain.getLatestHeader()
239+
const number = latest.number.toString(16)
240+
if (blockOpt !== `0x${number}`) {
226241
return {
227242
code: INVALID_PARAMS,
228243
message: `Currently only "latest" block supported`,
229244
}
230245
}
231246
}
232247

233-
if (!this._vm) {
234-
throw new Error('missing vm')
235-
}
236-
237248
const address = Address.fromString(addressHex)
238-
const account: Account = await (this._vm.stateManager as any).getAccount(address)
249+
const account: Account = await vm.stateManager.getAccount(address)
239250
return `0x${account.balance.toString(16)}`
240251
}
241252

@@ -294,21 +305,26 @@ export class Eth {
294305
async getCode(params: [string, string]) {
295306
const [addressHex, blockOpt] = params
296307

308+
if (!this._vm) {
309+
throw new Error('missing vm')
310+
}
311+
312+
// use a copy of the vm in case new blocks are sync'd
313+
const vm = this._vm.copy()
314+
297315
if (blockOpt !== 'latest') {
298-
const latest = await this.blockNumber()
299-
if (blockOpt !== latest) {
316+
const latest = await vm.blockchain.getLatestHeader()
317+
const number = latest.number.toString(16)
318+
if (blockOpt !== `0x${number}`) {
300319
return {
301320
code: INVALID_PARAMS,
302321
message: `Currently only "latest" block supported`,
303322
}
304323
}
305324
}
306325

307-
if (!this._vm) {
308-
throw new Error('missing vm')
309-
}
310326
const address = Address.fromString(addressHex)
311-
const code = await (this._vm.stateManager as any).getContractCode(address)
327+
const code = await vm.stateManager.getContractCode(address)
312328
return bufferToHex(code)
313329
}
314330

@@ -323,22 +339,26 @@ export class Eth {
323339
async getStorageAt(params: [string, string, string]) {
324340
const [addressHex, positionHex, blockOpt] = params
325341

342+
if (!this._vm) {
343+
throw new Error('missing vm')
344+
}
345+
346+
// use a copy of the vm in case new blocks are executed
347+
const vm = this._vm.copy()
348+
326349
if (blockOpt !== 'latest') {
327-
const latest = await this.blockNumber()
328-
if (blockOpt !== latest) {
350+
const latest = await vm.blockchain.getLatestHeader()
351+
const number = latest.number.toString(16)
352+
if (blockOpt !== `0x${number}`) {
329353
return {
330354
code: INVALID_PARAMS,
331355
message: `Currently only "latest" block supported`,
332356
}
333357
}
334358
}
335359

336-
if (!this._vm) {
337-
throw new Error('missing vm')
338-
}
339-
340360
const address = Address.fromString(addressHex)
341-
const storageTrie = await (this._vm.stateManager as any)._getStorageTrie(address)
361+
const storageTrie = await (vm.stateManager as any)._getStorageTrie(address)
342362
const position = setLengthLeft(toBuffer(positionHex), 32)
343363
const storage = await storageTrie.get(position)
344364
return storage ? bufferToHex(setLengthLeft(decode(storage), 32)) : '0x'
@@ -354,22 +374,26 @@ export class Eth {
354374
async getTransactionCount(params: [string, string]) {
355375
const [addressHex, blockOpt] = params
356376

377+
if (!this._vm) {
378+
throw new Error('missing vm')
379+
}
380+
381+
// use a copy of the vm in case new blocks are executed
382+
const vm = this._vm.copy()
383+
357384
if (blockOpt !== 'latest') {
358-
const latest = await this.blockNumber()
359-
if (blockOpt !== latest) {
385+
const latest = await vm.blockchain.getLatestHeader()
386+
const number = latest.number.toString(16)
387+
if (blockOpt !== `0x${number}`) {
360388
return {
361389
code: INVALID_PARAMS,
362390
message: `Currently only "latest" block supported`,
363391
}
364392
}
365393
}
366394

367-
if (!this._vm) {
368-
throw new Error('missing vm')
369-
}
370-
371395
const address = Address.fromString(addressHex)
372-
const account: Account = await (this._vm.stateManager as any).getAccount(address)
396+
const account: Account = await vm.stateManager.getAccount(address)
373397
return `0x${account.nonce.toString(16)}`
374398
}
375399

packages/client/test/rpc/eth/call.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import tape from 'tape'
2-
import { Address, BN, bufferToHex, unpadBuffer } from 'ethereumjs-util'
2+
import { Address, BN, bufferToHex } from 'ethereumjs-util'
33
import Blockchain from '@ethereumjs/blockchain'
44
import { Transaction } from '@ethereumjs/tx'
55
import { FullSynchronizer } from '../../../lib/sync'

0 commit comments

Comments
 (0)