diff --git a/packages/block/src/errors.ts b/packages/block/src/errors.ts new file mode 100644 index 0000000000..379808a280 --- /dev/null +++ b/packages/block/src/errors.ts @@ -0,0 +1,12 @@ +import { EthereumJSError } from '@ethereumjs/util' + +export enum HeaderValidationErrorCode { + WRONG_TX_TRIE_LENGTH = 'WRONG_TX_TRIE_LENGTH', +} + +export type HeaderValidationErrorType = { + block: string + received: string +} + +export class HeaderValidationError extends EthereumJSError {} diff --git a/packages/block/src/header/header.ts b/packages/block/src/header/header.ts index 9f24919f56..b23366f6a4 100644 --- a/packages/block/src/header/header.ts +++ b/packages/block/src/header/header.ts @@ -26,6 +26,7 @@ import { CLIQUE_EXTRA_VANITY, cliqueIsEpochTransition, } from '../consensus/clique.js' +import { HeaderValidationError, HeaderValidationErrorCode } from '../errors.js' import { fakeExponential } from '../helpers.js' import { paramsBlock } from '../params.js' @@ -267,10 +268,15 @@ export class BlockHeader { throw new Error(msg) } if (transactionsTrie.length !== 32) { - const msg = this._errorMsg( - `transactionsTrie must be 32 bytes, received ${transactionsTrie.length} bytes`, + const e = new HeaderValidationError( + 'transactionsTrie must be 32 bytes', + HeaderValidationErrorCode.WRONG_TX_TRIE_LENGTH, + { + block: this.errorStr(), + received: `${bytesToHex(transactionsTrie)} (${transactionsTrie.length} bytes)`, + }, ) - throw new Error(msg) + throw e } if (receiptTrie.length !== 32) { const msg = this._errorMsg( diff --git a/packages/util/src/errors.ts b/packages/util/src/errors.ts new file mode 100644 index 0000000000..0430621648 --- /dev/null +++ b/packages/util/src/errors.ts @@ -0,0 +1,30 @@ +/** + * Generic EthereumJS error with metadata attached + * + * Kudos to https://github.com/ChainSafe/lodestar monorepo + * for the inspiration :-) + */ +export class EthereumJSError extends Error { + code: string + errorContext: T + + constructor(msg: string, code: string, errorContext: T) { + super(msg) + this.code = code + this.errorContext = errorContext + } + + getErrorContext(): Record { + return { code: this.code, ...this.errorContext } + } + + /** + * Get the metadata and the stacktrace for the error. + */ + toObject(): Record { + return { + ...this.getErrorContext(), + stack: this.stack ?? '', + } + } +} diff --git a/packages/util/src/index.ts b/packages/util/src/index.ts index d1f6dd95e7..2776c03d03 100644 --- a/packages/util/src/index.ts +++ b/packages/util/src/index.ts @@ -28,6 +28,11 @@ export * from './db.js' */ export * from './withdrawal.js' +/** + * EthereumJS Extended Errors + */ +export * from './errors.js' + /** * ECDSA signature */