Skip to content

Commit 77bf2e9

Browse files
EVM: cleanup error messages and fix styling (#3994)
* evm/vm: use constant as string to ref for `EVMError` * Remove unused EOFError key-values * Remove unused SimpleErrors * Remove unused EVMErrorMessages elements * Rename EvmErrorResult to EVMErrorResult * Rename Evm to EVM in comments and strings * Make EVMErrorMessages a static field in EVMError --------- Co-authored-by: Amir <[email protected]>
1 parent 20cae2b commit 77bf2e9

30 files changed

+223
-245
lines changed

packages/evm/src/eof/errors.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export const EOFError = {
3232
MAX_STACK_HEIGHT: 'expected maxStackHeight',
3333
MAX_STACK_HEIGHT_LIMIT: 'stack height limit of 1024 exceeded: ',
3434
MIN_CODE_SECTIONS: 'should have at least 1 code section',
35-
MAX_CODE_SECTIONS: 'can have at most 1024 code sections',
3635
CODE_SECTION: 'expected a code section',
3736
DATA_SECTION: 'Expected data section',
3837
CONTAINER_SECTION: 'expected a container section',
@@ -66,39 +65,6 @@ export const EOFError = {
6665
RETURN_STACK_OVERFLOW: 'Return stack overflow',
6766
INVALID_EXTCALL_TARGET: 'invalid extcall target: address > 20 bytes',
6867
INVALID_RETURN_CONTRACT_DATA_SIZE: 'invalid RETURNCONTRACT: data size lower than expected',
69-
INVALID_EOF_FORMAT: 'invalid EOF format',
70-
} as const
71-
72-
export type SimpleErrors = (typeof SimpleErrors)[keyof typeof SimpleErrors]
73-
74-
export const SimpleErrors = {
75-
MIN_CONTAINER_SIZE: 'err: container size less than minimum valid size',
76-
INVALID_CONTAINER_SIZE: 'err: invalid container size',
77-
TYPE_SIZE: 'err: type section size invalid',
78-
CODE0_MSH: 'err: computed max stack height for code section 0 does not match expect',
79-
UNDERFLOW: 'err: stack underflow',
80-
CODE0_IO: 'err: input and output of first code section must be 0',
81-
VERIFY_UINT: 'Uint does not match expected value ',
82-
VERIFY_BYTES: 'Bytes do not match expected value',
83-
INVALID_TYPE_SIZE: 'err: type section invalid',
84-
CODE_SIZE: 'missing code size',
85-
CODE_SECTION_SIZE: 'code section should be at least one byte',
86-
INVALID_CODE_SIZE: 'code size does not match type size',
87-
DATA_SIZE: 'missing data size',
88-
TYPE_SECTIONS: 'need to have a type section for each code section',
89-
INPUTS: 'expected inputs',
90-
OUTPUTS: 'expected outputs',
91-
MAX_INPUTS: 'inputs exceeds 127, the maximum, got: ',
92-
MAX_OUTPUTS: 'outputs exceeds 127, the maximum, got: ',
93-
CODE0_INPUTS: 'first code section should have 0 inputs',
94-
CODE0_OUTPUTS: 'first code section should have 0 outputs',
95-
MAX_STACK_HEIGHT: 'expected maxStackHeight',
96-
MAX_STACK_HEIGHT_LIMIT: 'stack height limit of 1024 exceeded: ',
97-
MIN_CODE_SECTIONS: 'should have at least 1 code section',
98-
MAX_CODE_SECTIONS: 'can have at most 1024 code sections',
99-
CODE_SECTION: 'expected a code section',
100-
DATA_SECTION: 'Expected data section',
101-
DANGLING_BYTES: 'got dangling bytes in body',
10268
} as const
10369

10470
export function validationErrorMsg(type: EOFError, ...args: any) {

packages/evm/src/errors.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export type EVMErrorType = (typeof EVMErrorMessages)[keyof typeof EVMErrorMessages]
22

3-
export const EVMErrorMessages = {
3+
export const EVMErrorTypeString = 'EVMError'
4+
5+
const EVMErrorMessages = {
46
OUT_OF_GAS: 'out of gas',
57
CODESTORE_OUT_OF_GAS: 'code store out of gas',
68
CODESIZE_EXCEEDS_MAXIMUM: 'code size to deposit exceeds maximum code size',
@@ -17,9 +19,6 @@ export const EVMErrorMessages = {
1719
REFUND_EXHAUSTED: 'refund exhausted',
1820
VALUE_OVERFLOW: 'value overflow',
1921
INSUFFICIENT_BALANCE: 'insufficient balance',
20-
INVALID_BEGINSUB: 'invalid BEGINSUB',
21-
INVALID_RETURNSUB: 'invalid RETURNSUB',
22-
INVALID_JUMPSUB: 'invalid JUMPSUB',
2322
INVALID_BYTECODE_RESULT: 'invalid bytecode deployed',
2423
INITCODE_SIZE_VIOLATION: 'initcode exceeds max initcode size',
2524
INVALID_INPUT_LENGTH: 'invalid input length',
@@ -37,9 +36,10 @@ export const EVMErrorMessages = {
3736
export class EVMError {
3837
error: EVMErrorType
3938
errorType: string
39+
static errorMessages: Record<keyof typeof EVMErrorMessages, EVMErrorType> = EVMErrorMessages
4040

4141
constructor(error: EVMErrorType) {
4242
this.error = error
43-
this.errorType = 'EVMError'
43+
this.errorType = EVMErrorTypeString
4444
}
4545
}

packages/evm/src/evm.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { EventEmitter } from 'eventemitter3'
2121

2222
import { FORMAT } from './eof/constants.ts'
2323
import { isEOF } from './eof/util.ts'
24-
import { EVMError, EVMErrorMessages } from './errors.ts'
24+
import { EVMError } from './errors.ts'
2525
import { Interpreter } from './interpreter.ts'
2626
import { Journal } from './journal.ts'
2727
import { EVMPerformanceLogger } from './logger.ts'
@@ -64,43 +64,43 @@ export function OOGResult(gasLimit: bigint): ExecResult {
6464
return {
6565
returnValue: new Uint8Array(0),
6666
executionGasUsed: gasLimit,
67-
exceptionError: new EVMError(EVMErrorMessages.OUT_OF_GAS),
67+
exceptionError: new EVMError(EVMError.errorMessages.OUT_OF_GAS),
6868
}
6969
}
7070
// CodeDeposit OOG Result
7171
export function COOGResult(gasUsedCreateCode: bigint): ExecResult {
7272
return {
7373
returnValue: new Uint8Array(0),
7474
executionGasUsed: gasUsedCreateCode,
75-
exceptionError: new EVMError(EVMErrorMessages.CODESTORE_OUT_OF_GAS),
75+
exceptionError: new EVMError(EVMError.errorMessages.CODESTORE_OUT_OF_GAS),
7676
}
7777
}
7878

7979
export function INVALID_BYTECODE_RESULT(gasLimit: bigint): ExecResult {
8080
return {
8181
returnValue: new Uint8Array(0),
8282
executionGasUsed: gasLimit,
83-
exceptionError: new EVMError(EVMErrorMessages.INVALID_BYTECODE_RESULT),
83+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_BYTECODE_RESULT),
8484
}
8585
}
8686

8787
export function INVALID_EOF_RESULT(gasLimit: bigint): ExecResult {
8888
return {
8989
returnValue: new Uint8Array(0),
9090
executionGasUsed: gasLimit,
91-
exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT),
91+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT),
9292
}
9393
}
9494

9595
export function CodesizeExceedsMaximumError(gasUsed: bigint): ExecResult {
9696
return {
9797
returnValue: new Uint8Array(0),
9898
executionGasUsed: gasUsed,
99-
exceptionError: new EVMError(EVMErrorMessages.CODESIZE_EXCEEDS_MAXIMUM),
99+
exceptionError: new EVMError(EVMError.errorMessages.CODESIZE_EXCEEDS_MAXIMUM),
100100
}
101101
}
102102

103-
export function EvmErrorResult(error: EVMError, gasUsed: bigint): ExecResult {
103+
export function EVMErrorResult(error: EVMError, gasUsed: bigint): ExecResult {
104104
return {
105105
returnValue: new Uint8Array(0),
106106
executionGasUsed: gasUsed,
@@ -508,7 +508,7 @@ export class EVM implements EVMInterface {
508508
createdAddress: message.to,
509509
execResult: {
510510
returnValue: new Uint8Array(0),
511-
exceptionError: new EVMError(EVMErrorMessages.INITCODE_SIZE_VIOLATION),
511+
exceptionError: new EVMError(EVMError.errorMessages.INITCODE_SIZE_VIOLATION),
512512
executionGasUsed: message.gasLimit,
513513
},
514514
}
@@ -567,7 +567,7 @@ export class EVM implements EVMInterface {
567567
createdAddress: message.to,
568568
execResult: {
569569
returnValue: new Uint8Array(0),
570-
exceptionError: new EVMError(EVMErrorMessages.CREATE_COLLISION),
570+
exceptionError: new EVMError(EVMError.errorMessages.CREATE_COLLISION),
571571
executionGasUsed: message.gasLimit,
572572
},
573573
}
@@ -871,8 +871,8 @@ export class EVM implements EVMInterface {
871871
let gasUsed = message.gasLimit - interpreterRes.runState!.gasLeft
872872
if (interpreterRes.exceptionError) {
873873
if (
874-
interpreterRes.exceptionError.error !== EVMErrorMessages.REVERT &&
875-
interpreterRes.exceptionError.error !== EVMErrorMessages.INVALID_EOF_FORMAT
874+
interpreterRes.exceptionError.error !== EVMError.errorMessages.REVERT &&
875+
interpreterRes.exceptionError.error !== EVMError.errorMessages.INVALID_EOF_FORMAT
876876
) {
877877
gasUsed = message.gasLimit
878878
}
@@ -1019,7 +1019,7 @@ export class EVM implements EVMInterface {
10191019
// There is one exception: if the CODESTORE_OUT_OF_GAS error is thrown
10201020
// (this only happens the Frontier/Chainstart fork)
10211021
// then the error is dismissed
1022-
if (err && err.error !== EVMErrorMessages.CODESTORE_OUT_OF_GAS) {
1022+
if (err && err.error !== EVMError.errorMessages.CODESTORE_OUT_OF_GAS) {
10231023
result.execResult.selfdestruct = new Set()
10241024
result.execResult.createdAddresses = new Set()
10251025
result.execResult.gasRefund = BIGINT_0
@@ -1028,7 +1028,7 @@ export class EVM implements EVMInterface {
10281028
err &&
10291029
!(
10301030
this.common.hardfork() === Hardfork.Chainstart &&
1031-
err.error === EVMErrorMessages.CODESTORE_OUT_OF_GAS
1031+
err.error === EVMError.errorMessages.CODESTORE_OUT_OF_GAS
10321032
)
10331033
) {
10341034
result.execResult.logs = []
@@ -1159,7 +1159,7 @@ export class EVM implements EVMInterface {
11591159
protected async _reduceSenderBalance(account: Account, message: Message): Promise<void> {
11601160
account.balance -= message.value
11611161
if (account.balance < BIGINT_0) {
1162-
throw new EVMError(EVMErrorMessages.INSUFFICIENT_BALANCE)
1162+
throw new EVMError(EVMError.errorMessages.INSUFFICIENT_BALANCE)
11631163
}
11641164
const result = this.journal.putAccount(message.caller, account)
11651165
if (this.DEBUG) {
@@ -1171,7 +1171,7 @@ export class EVM implements EVMInterface {
11711171
protected async _addToBalance(toAccount: Account, message: MessageWithTo): Promise<void> {
11721172
const newBalance = toAccount.balance + message.value
11731173
if (newBalance > MAX_INTEGER) {
1174-
throw new EVMError(EVMErrorMessages.VALUE_OVERFLOW)
1174+
throw new EVMError(EVMError.errorMessages.VALUE_OVERFLOW)
11751175
}
11761176
toAccount.balance = newBalance
11771177
// putAccount as the nonce may have changed for contract creation

packages/evm/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EOFContainer, validateEOF } from './eof/container.ts'
2-
import { EVMError, EVMErrorMessages } from './errors.ts'
2+
import { EVMError } from './errors.ts'
33
import { EVM } from './evm.ts'
44
import { Message } from './message.ts'
55
import { getOpcodesForHF } from './opcodes/index.ts'
@@ -47,7 +47,6 @@ export {
4747
EOFContainer,
4848
EVM,
4949
EVMError,
50-
EVMErrorMessages,
5150
EVMMockBlockchain,
5251
getActivePrecompiles,
5352
getOpcodesForHF,

packages/evm/src/interpreter.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { FORMAT, MAGIC, VERSION } from './eof/constants.ts'
1818
import { EOFContainerMode, validateEOF } from './eof/container.ts'
1919
import { setupEOF } from './eof/setup.ts'
2020
import { ContainerSectionType } from './eof/verify.ts'
21-
import { EVMError, EVMErrorMessages } from './errors.ts'
21+
import { EVMError, EVMErrorTypeString } from './errors.ts'
2222
import { type EVMPerformanceLogger, type Timer } from './logger.ts'
2323
import { Memory } from './memory.ts'
2424
import { Message } from './message.ts'
@@ -219,14 +219,14 @@ export class Interpreter {
219219
// Bytecode contains invalid EOF magic byte
220220
return {
221221
runState: this._runState,
222-
exceptionError: new EVMError(EVMErrorMessages.INVALID_BYTECODE_RESULT),
222+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_BYTECODE_RESULT),
223223
}
224224
}
225225
if (code[2] !== VERSION) {
226226
// Bytecode contains invalid EOF version number
227227
return {
228228
runState: this._runState,
229-
exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT),
229+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT),
230230
}
231231
}
232232
this._runState.code = code
@@ -239,7 +239,7 @@ export class Interpreter {
239239
} catch {
240240
return {
241241
runState: this._runState,
242-
exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed
242+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed
243243
}
244244
}
245245

@@ -256,7 +256,7 @@ export class Interpreter {
256256
// Trying to deploy an invalid EOF container
257257
return {
258258
runState: this._runState,
259-
exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed
259+
exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed
260260
}
261261
}
262262
}
@@ -336,11 +336,11 @@ export class Interpreter {
336336
this.performanceLogger.unpauseTimer(overheadTimer)
337337
}
338338
// re-throw on non-VM errors
339-
if (!('errorType' in e && e.errorType === 'EVMError')) {
339+
if (!('errorType' in e && e.errorType === EVMErrorTypeString)) {
340340
throw e
341341
}
342342
// STOP is not an exception
343-
if (e.error !== EVMErrorMessages.STOP) {
343+
if (e.error !== EVMError.errorMessages.STOP) {
344344
err = e
345345
}
346346
break
@@ -403,7 +403,7 @@ export class Interpreter {
403403

404404
// Check for invalid opcode
405405
if (opInfo.isInvalid) {
406-
throw new EVMError(EVMErrorMessages.INVALID_OPCODE)
406+
throw new EVMError(EVMError.errorMessages.INVALID_OPCODE)
407407
}
408408

409409
// Reduce opcode's base fee
@@ -563,7 +563,7 @@ export class Interpreter {
563563
}
564564
if (this._runState.gasLeft < BIGINT_0) {
565565
this._runState.gasLeft = BIGINT_0
566-
trap(EVMErrorMessages.OUT_OF_GAS)
566+
trap(EVMError.errorMessages.OUT_OF_GAS)
567567
}
568568
}
569569

@@ -599,7 +599,7 @@ export class Interpreter {
599599
this._runState.gasRefund -= amount
600600
if (this._runState.gasRefund < BIGINT_0) {
601601
this._runState.gasRefund = BIGINT_0
602-
trap(EVMErrorMessages.REFUND_EXHAUSTED)
602+
trap(EVMError.errorMessages.REFUND_EXHAUSTED)
603603
}
604604
}
605605

@@ -681,7 +681,7 @@ export class Interpreter {
681681
*/
682682
finish(returnData: Uint8Array): void {
683683
this._result.returnValue = returnData
684-
trap(EVMErrorMessages.STOP)
684+
trap(EVMError.errorMessages.STOP)
685685
}
686686

687687
/**
@@ -691,7 +691,7 @@ export class Interpreter {
691691
*/
692692
revert(returnData: Uint8Array): void {
693693
this._result.returnValue = returnData
694-
trap(EVMErrorMessages.REVERT)
694+
trap(EVMError.errorMessages.REVERT)
695695
}
696696

697697
/**
@@ -1016,7 +1016,7 @@ export class Interpreter {
10161016
if (
10171017
results.execResult.returnValue !== undefined &&
10181018
(!results.execResult.exceptionError ||
1019-
results.execResult.exceptionError.error === EVMErrorMessages.REVERT)
1019+
results.execResult.exceptionError.error === EVMError.errorMessages.REVERT)
10201020
) {
10211021
this._runState.returnBytes = results.execResult.returnValue
10221022
}
@@ -1117,14 +1117,14 @@ export class Interpreter {
11171117
// Set return buffer in case revert happened
11181118
if (
11191119
results.execResult.exceptionError &&
1120-
results.execResult.exceptionError.error === EVMErrorMessages.REVERT
1120+
results.execResult.exceptionError.error === EVMError.errorMessages.REVERT
11211121
) {
11221122
this._runState.returnBytes = results.execResult.returnValue
11231123
}
11241124

11251125
if (
11261126
!results.execResult.exceptionError ||
1127-
results.execResult.exceptionError.error === EVMErrorMessages.CODESTORE_OUT_OF_GAS
1127+
results.execResult.exceptionError.error === EVMError.errorMessages.CODESTORE_OUT_OF_GAS
11281128
) {
11291129
for (const addressToSelfdestructHex of selfdestruct) {
11301130
this._result.selfdestruct.add(addressToSelfdestructHex)
@@ -1230,19 +1230,19 @@ export class Interpreter {
12301230
})
12311231
}
12321232

1233-
trap(EVMErrorMessages.STOP)
1233+
trap(EVMError.errorMessages.STOP)
12341234
}
12351235

12361236
/**
12371237
* Creates a new log in the current environment.
12381238
*/
12391239
log(data: Uint8Array, numberOfTopics: number, topics: Uint8Array[]): void {
12401240
if (numberOfTopics < 0 || numberOfTopics > 4) {
1241-
trap(EVMErrorMessages.OUT_OF_RANGE)
1241+
trap(EVMError.errorMessages.OUT_OF_RANGE)
12421242
}
12431243

12441244
if (topics.length !== numberOfTopics) {
1245-
trap(EVMErrorMessages.INTERNAL_ERROR)
1245+
trap(EVMError.errorMessages.INTERNAL_ERROR)
12461246
}
12471247

12481248
const log: Log = [this._env.address.bytes, topics, data]
@@ -1259,7 +1259,7 @@ export class Interpreter {
12591259
} else {
12601260
// EOF mode, call was either EXTCALL / EXTDELEGATECALL / EXTSTATICCALL
12611261
if (results.execResult.exceptionError !== undefined) {
1262-
if (results.execResult.exceptionError.error === EVMErrorMessages.REVERT) {
1262+
if (results.execResult.exceptionError.error === EVMError.errorMessages.REVERT) {
12631263
// Revert
12641264
return BIGINT_1
12651265
} else {

packages/evm/src/opcodes/EIP2200.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { equalsBytes } from '@ethereumjs/util'
22

3-
import { EVMErrorMessages } from '../errors.ts'
3+
import { EVMError } from '../errors.ts'
44

55
import { adjustSstoreGasEIP2929 } from './EIP2929.ts'
66
import { trap } from './util.ts'
@@ -27,7 +27,7 @@ export function updateSstoreGasEIP2200(
2727
) {
2828
// Fail if not enough gas is left
2929
if (runState.interpreter.getGasLeft() <= common.param('sstoreSentryEIP2200Gas')) {
30-
trap(EVMErrorMessages.OUT_OF_GAS)
30+
trap(EVMError.errorMessages.OUT_OF_GAS)
3131
}
3232

3333
// Noop

0 commit comments

Comments
 (0)