Skip to content

Commit 37a4de1

Browse files
authored
Migrate Loop to typescript (ethereumjs#505)
* Change loop filetype to ts * Migrate loop to ts
1 parent 8faa894 commit 37a4de1

File tree

6 files changed

+148
-74
lines changed

6 files changed

+148
-74
lines changed

lib/evm/eei.ts

+35-22
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
11
import BN = require('bn.js')
2+
import { toBuffer } from 'ethereumjs-util'
3+
import Account from 'ethereumjs-account'
24
import PStateManager from '../state/promisified'
5+
import { VmError, ERROR } from '../exceptions'
36
import Message from './message'
4-
import { toBuffer } from 'ethereumjs-util'
7+
import { RunState, RunResult } from './loop'
8+
import Interpreter from './interpreter'
59
const promisify = require('util.promisify')
6-
const { VmError, ERROR } = require('../exceptions')
10+
11+
export interface Env {
12+
blockchain: any // TODO: update to ethereumjs-blockchain v4.0.0
13+
address: Buffer
14+
caller: Buffer
15+
callData: Buffer
16+
callValue: BN
17+
code: Buffer
18+
isStatic: boolean
19+
depth: number
20+
gasPrice: Buffer // TODO: Set type to BN?
21+
origin: Buffer
22+
block: any
23+
contract: Account
24+
}
725

826
export default class EEI {
9-
_env: any
10-
_runState: any
11-
_result: any
27+
_env: Env
28+
_runState: RunState
29+
_result: RunResult
1230
_state: PStateManager
13-
_interpreter: any
31+
_interpreter: Interpreter
1432
_lastReturned: Buffer
1533

16-
constructor (env: any, runState: any, result: any, state: PStateManager, interpreter: any) {
34+
constructor (env: Env, runState: RunState, result: RunResult, state: PStateManager, interpreter: Interpreter) {
1735
this._env = env
1836
this._runState = runState
1937
this._result = result
@@ -36,7 +54,7 @@ export default class EEI {
3654
}
3755

3856
refundGas (amount: BN): void {
39-
this._result.gasRefund.iaddn(amount)
57+
this._result.gasRefund.iadd(amount)
4058
}
4159

4260
/**
@@ -115,9 +133,9 @@ export default class EEI {
115133

116134
/**
117135
* Returns the code running in current environment.
118-
* @returns {BN}
136+
* @returns {Buffer}
119137
*/
120-
getCode (): BN {
138+
getCode (): Buffer {
121139
return this._env.code
122140
}
123141

@@ -314,9 +332,9 @@ export default class EEI {
314332
* Creates a new log in the current environment.
315333
* @param {Buffer} data
316334
* @param {Number} numberOfTopics
317-
* @param {BN[]} topics
335+
* @param {Buffer[]} topics
318336
*/
319-
log (data: Buffer, numberOfTopics: number, topics: BN[]): void {
337+
log (data: Buffer, numberOfTopics: number, topics: Buffer[]): void {
320338
if (numberOfTopics < 0 || numberOfTopics > 4) {
321339
trap(ERROR.OUT_OF_RANGE)
322340
}
@@ -326,7 +344,7 @@ export default class EEI {
326344
}
327345

328346
// add address
329-
const log = [this._env.address]
347+
const log: any = [this._env.address]
330348
log.push(topics)
331349

332350
// add data
@@ -451,7 +469,7 @@ export default class EEI {
451469
this.useGas(results.gasUsed)
452470

453471
// Set return value
454-
if (results.vm.return && (!results.vm.exceptionError || results.vm.exceptionError.error === ERROR.REVERT)) {
472+
if (results.vm.return && (!results.vm.exceptionError || (results.vm.exceptionError as VmError).error === ERROR.REVERT)) {
455473
this._lastReturned = results.vm.return
456474
}
457475

@@ -491,7 +509,7 @@ export default class EEI {
491509
return new BN(0)
492510
}
493511

494-
this._env.contract.nonce = new BN(this._env.contract.nonce).addn(1)
512+
this._env.contract.nonce = toBuffer(new BN(this._env.contract.nonce).addn(1))
495513
await this._state.putAccount(this._env.address, this._env.contract)
496514

497515
const results = await this._interpreter.executeMessage(msg)
@@ -509,7 +527,7 @@ export default class EEI {
509527
this.useGas(results.gasUsed)
510528

511529
// Set return buffer in case revert happened
512-
if (results.vm.exceptionError && results.vm.exceptionError.error === ERROR.REVERT) {
530+
if (results.vm.exceptionError && (results.vm.exceptionError as VmError).error === ERROR.REVERT) {
513531
this._lastReturned = results.vm.return
514532
}
515533

@@ -522,11 +540,6 @@ export default class EEI {
522540
// push the created address to the stack
523541
return new BN(results.createdAddress)
524542
}
525-
} else {
526-
// creation failed so don't increment the nonce
527-
if (results.vm.createdAddress) {
528-
this._env.contract.nonce = new BN(this._env.contract.nonce).subn(1)
529-
}
530543
}
531544

532545
return new BN(results.vm.exception)
@@ -554,7 +567,7 @@ export default class EEI {
554567
}
555568
}
556569

557-
function trap (err: string) {
570+
function trap (err: ERROR) {
558571
throw new VmError(err)
559572
}
560573

lib/evm/interpreter.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import BN = require('bn.js')
22
import { toBuffer, generateAddress, generateAddress2, KECCAK256_NULL, MAX_INTEGER } from 'ethereumjs-util'
33
import Account from 'ethereumjs-account'
4-
import { ERROR } from '../exceptions'
4+
import { VmError, ERROR } from '../exceptions'
55
import { StorageReader } from '../state'
66
import PStateManager from '../state/promisified'
77
import { getPrecompile, PrecompileFunc, PrecompileResult } from './precompiles'
88
import { OOGResult } from './precompiles/types'
99
import TxContext from './txContext'
1010
import Message from './message'
11-
const Loop = require('./loop')
11+
import { default as Loop, LoopResult } from './loop'
1212

1313
export interface InterpreterResult {
1414
gasUsed: BN
1515
createdAddress?: Buffer
16-
vm: any // TODO
16+
vm: LoopResult
1717
}
1818

1919
export default class Interpreter {
@@ -50,7 +50,7 @@ export default class Interpreter {
5050
// because the bug in both Geth and Parity led to deleting RIPEMD precompiled in this case
5151
// see https://github.com/ethereum/go-ethereum/pull/3341/files#diff-2433aa143ee4772026454b8abd76b9dd
5252
// We mark the account as touched here, so that is can be removed among other touched empty accounts (after tx finalization)
53-
if (err === ERROR.OUT_OF_GAS || err.error === ERROR.OUT_OF_GAS) {
53+
if (err as ERROR === ERROR.OUT_OF_GAS || (err as VmError).error === ERROR.OUT_OF_GAS) {
5454
await this._touchAccount(message.to)
5555
}
5656
}
@@ -80,7 +80,9 @@ export default class Interpreter {
8080
return {
8181
gasUsed: new BN(0),
8282
vm: {
83-
exception: 1
83+
exception: 1,
84+
gasUsed: new BN(0),
85+
return: Buffer.alloc(0)
8486
}
8587
}
8688
}
@@ -131,7 +133,9 @@ export default class Interpreter {
131133
gasUsed: new BN(0),
132134
createdAddress: message.to,
133135
vm: {
134-
exception: 1
136+
exception: 1,
137+
gasUsed: new BN(0),
138+
return: Buffer.alloc(0)
135139
}
136140
}
137141
}
@@ -140,7 +144,7 @@ export default class Interpreter {
140144

141145
// fee for size of the return value
142146
let totalGas = result.gasUsed
143-
if (!result.runState.vmError) {
147+
if (!result.exceptionError) {
144148
const returnFee = new BN(result.return.length * this._vm._common.param('gasPrices', 'createData'))
145149
totalGas = totalGas.add(returnFee)
146150
}
@@ -153,7 +157,7 @@ export default class Interpreter {
153157
}
154158

155159
// Save code if a new contract was created
156-
if (!result.runState.vmError && result.return && result.return.toString() !== '') {
160+
if (!result.exceptionError && result.return && result.return.toString() !== '') {
157161
await this._state.putContractCode(message.to, result.return)
158162
}
159163

0 commit comments

Comments
 (0)