Skip to content

Commit

Permalink
Add invalid scenario checks and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
acolytec3 committed Oct 13, 2022
1 parent 10ab351 commit fa8e2bd
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 32 additions & 5 deletions packages/tx/src/eip4844Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { toHexString } from '@chainsafe/ssz'
import { Address, MAX_INTEGER, bufferToBigInt, toBuffer } from '@ethereumjs/util'

import { BaseTransaction } from './baseTransaction'
import { BlobTransactionType } from './types'
import { BLOB_COMMITMENT_VERSION_KZG, BlobTransactionType, MAX_BLOBS_PER_TX } from './types'
import { AccessLists, checkMaxInitCodeSize } from './util'

import type {
Expand Down Expand Up @@ -79,6 +79,21 @@ export class BlobEIP4844Transaction extends BaseTransaction<BlobEIP4844Transacti
checkMaxInitCodeSize(this.common, this.data.length)
}

for (const hash of txData.versionedHashes) {
if (hash.length !== 32) {
const msg = this._errorMsg('versioned hash is invalid length')
throw new Error(msg)
}
if (hash[0] !== BLOB_COMMITMENT_VERSION_KZG) {
const msg = this._errorMsg('versioned hash does not start with KZG commitment version')
throw new Error(msg)
}
}
if (txData.versionedHashes.length > MAX_BLOBS_PER_TX) {
const msg = this._errorMsg(`tx can contain at most ${MAX_BLOBS_PER_TX} blobs`)
throw new Error(msg)
}

this.versionedHashes = txData.versionedHashes

const freeze = opts?.freeze ?? true
Expand Down Expand Up @@ -161,10 +176,22 @@ export class BlobEIP4844Transaction extends BaseTransaction<BlobEIP4844Transacti
_processSignature(_v: bigint, _r: Buffer, _s: Buffer): BlobEIP4844Transaction {
throw new Error('Method not implemented.')
}
public errorStr(): string {
throw new Error('Method not implemented.')
/**
* Return a compact error string representation of the object
*/
public errorStr() {
let errorStr = this._getSharedErrorPostfix()
errorStr += ` maxFeePerGas=${this.maxFeePerGas} maxPriorityFeePerGas=${this.maxPriorityFeePerGas}`
return errorStr
}
_errorMsg(_msg: string): string {
throw new Error('Method not implemented.')

/**
* Internal helper function to create an annotated error message
*
* @param msg Base error message
* @hidden
*/
protected _errorMsg(msg: string) {
return `${msg} (${this.errorStr()})`
}
}
3 changes: 3 additions & 0 deletions packages/tx/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,12 @@ export interface JsonRpcTx {

/** EIP4844 constants */

// TODO: Decide which of these should be in the hardfork params instead of hardcoded as constants here
export const BLOB_COMMITMENT_VERSION_KZG = 0x01
export const MAX_CALLDATA_SIZE = 2 ** 24
export const MAX_ACCESS_LIST_SIZE = 2 ** 24
export const MAX_VERSIONED_HASHES_LIST_SIZE = 2 ** 24
export const MAX_BLOBS_PER_TX = 2

/** EIP4844 types */
export const AddressType = new ByteVectorType(20) // SSZ encoded address
Expand Down
46 changes: 44 additions & 2 deletions packages/tx/test/eip4844.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { randomBytes } from 'crypto'
import * as tape from 'tape'

import { BlobEIP4844Transaction, TransactionFactory } from '../src'

tape('EIP4844 constructor tests', (t) => {
tape('EIP4844 constructor tests - valid scenarios', (t) => {
const txData = {
type: 0x05,
versionedHashes: [Buffer.from([])],
versionedHashes: [Buffer.concat([Buffer.from([1]), randomBytes(31)])],
}
const tx = BlobEIP4844Transaction.fromTxData(txData)
t.equal(tx.type, 5, 'successfully instantiated a blob transaction from txData')
Expand All @@ -18,3 +19,44 @@ tape('EIP4844 constructor tests', (t) => {
t.equal(deserializedTx.type, 5, 'deserialized a blob tx')
t.end()
})

tape('EIP4844 constructor tests - invalid scenarios', (t) => {
const baseTxData = {
type: 0x05,
}
const shortVersionHash = {
versionedHashes: [Buffer.concat([Buffer.from([3]), randomBytes(3)])],
}
const invalidVersionHash = {
versionedHashes: [Buffer.concat([Buffer.from([3]), randomBytes(31)])],
}
const tooManyBlobs = {
versionedHashes: [
Buffer.concat([Buffer.from([1]), randomBytes(31)]),
Buffer.concat([Buffer.from([1]), randomBytes(31)]),
Buffer.concat([Buffer.from([1]), randomBytes(31)]),
],
}
try {
BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...shortVersionHash })
} catch (err: any) {
t.ok(
err.message.includes('versioned hash is invalid length'),
'throws on invalid versioned hash length'
)
}
try {
BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...invalidVersionHash })
} catch (err: any) {
t.ok(
err.message.includes('does not start with KZG commitment'),
'throws on invalid commitment version'
)
}
try {
BlobEIP4844Transaction.fromTxData({ ...baseTxData, ...tooManyBlobs })
} catch (err: any) {
t.ok(err.message.includes('tx can contain at most'), 'throws on too many versioned hashes')
}
t.end()
})

0 comments on commit fa8e2bd

Please sign in to comment.