diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 2ab8de4876..9d5e9df6ea 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -447,8 +447,9 @@ export class Block { /** * Validates the transaction trie by generating a trie * and do a check on the root hash. + * @returns True if the transaction trie is valid, false otherwise */ - async validateTransactionsTrie(): Promise { + async transactionsTrieIsValid(): Promise { let result if (this.transactions.length === 0) { result = equalsBytes(this.header.transactionsTrie, KECCAK256_RLP) @@ -464,13 +465,9 @@ export class Block { /** * Validates transaction signatures and minimum gas requirements. - * - * @param stringError - If `true`, a string with the indices of the invalid txs is returned. + * @returns {string[]} an array of error strings */ - validateTransactions(): boolean - validateTransactions(stringError: false): boolean - validateTransactions(stringError: true): string[] - validateTransactions(stringError = false) { + getTransactionsValidationErrors(): string[] { const errors: string[] = [] let dataGasUsed = BigInt(0) const dataGasLimit = this._common.param('gasConfig', 'maxDataGasPerBlock') @@ -478,7 +475,7 @@ export class Block { // eslint-disable-next-line prefer-const for (let [i, tx] of this.transactions.entries()) { - const errs = tx.validate(true) + const errs = tx.getValidationErrors() if (this._common.isActivatedEIP(1559) === true) { if (tx.supports(Capability.EIP1559FeeMarket)) { tx = tx as FeeMarketEIP1559Transaction @@ -513,7 +510,17 @@ export class Block { } } - return stringError ? errors : errors.length === 0 + return errors + } + + /** + * Validates transaction signatures and minimum gas requirements. + * @returns True if all transactions are valid, false otherwise + */ + transactionsAreValid(): boolean { + const errors = this.getTransactionsValidationErrors() + + return errors.length === 0 } /** @@ -526,7 +533,7 @@ export class Block { * @param onlyHeader if only passed the header, skip validating txTrie and unclesHash (default: false) */ async validateData(onlyHeader: boolean = false): Promise { - const txErrors = this.validateTransactions(true) + const txErrors = this.getTransactionsValidationErrors() if (txErrors.length > 0) { const msg = this._errorMsg(`invalid transactions: ${txErrors.join(' ')}`) throw new Error(msg) @@ -536,18 +543,17 @@ export class Block { return } - const validateTxTrie = await this.validateTransactionsTrie() - if (!validateTxTrie) { + if (!(await this.transactionsTrieIsValid())) { const msg = this._errorMsg('invalid transaction trie') throw new Error(msg) } - if (!this.validateUnclesHash()) { + if (!this.uncleHashIsValid()) { const msg = this._errorMsg('invalid uncle hash') throw new Error(msg) } - if (this._common.isActivatedEIP(4895) && !(await this.validateWithdrawalsTrie())) { + if (this._common.isActivatedEIP(4895) && !(await this.withdrawalsTrieIsValid())) { const msg = this._errorMsg('invalid withdrawals trie') throw new Error(msg) } @@ -603,8 +609,9 @@ export class Block { /** * Validates the uncle's hash. + * @returns true if the uncle's hash is valid, false otherwise. */ - validateUnclesHash(): boolean { + uncleHashIsValid(): boolean { const uncles = this.uncleHeaders.map((uh) => uh.raw()) const raw = RLP.encode(uncles) return equalsBytes(keccak256(raw), this.header.uncleHash) @@ -612,8 +619,9 @@ export class Block { /** * Validates the withdrawal root + * @returns true if the withdrawals trie root is valid, false otherwise */ - async validateWithdrawalsTrie(): Promise { + async withdrawalsTrieIsValid(): Promise { if (!this._common.isActivatedEIP(4895)) { throw new Error('EIP 4895 is not activated') } diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index 7ca51ee776..2f7d31c945 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -168,8 +168,8 @@ describe('[Block]: block functions', () => { }) async function testTransactionValidation(block: Block) { - assert.ok(block.validateTransactions()) - assert.ok(await block.validateTransactionsTrie()) + assert.ok(block.transactionsAreValid()) + assert.ok(block.getTransactionsValidationErrors().length === 0) } it('should test transaction validation', async () => { @@ -197,7 +197,7 @@ describe('[Block]: block functions', () => { const block = Block.fromRLPSerializedBlock(blockRlp, { common, freeze: false }) await testTransactionValidation(block) ;(block.transactions[0] as any).gasPrice = BigInt(0) - const result = block.validateTransactions(true) + const result = block.getTransactionsValidationErrors() assert.ok( result[0].includes('tx unable to pay base fee (non EIP-1559 tx)'), 'should throw when legacy tx is unable to pay base fee' @@ -208,7 +208,7 @@ describe('[Block]: block functions', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) const blockRlp = toBytes(testDataPreLondon2.blocks[2].rlp) const block = Block.fromRLPSerializedBlock(blockRlp, { common, freeze: false }) - assert.equal(block.validateUnclesHash(), true) + assert.equal(block.uncleHashIsValid(), true) ;(block.header as any).uncleHash = new Uint8Array(32) try { await block.validateData() diff --git a/packages/block/test/eip1559block.spec.ts b/packages/block/test/eip1559block.spec.ts index f26e0fdc5e..48d364748f 100644 --- a/packages/block/test/eip1559block.spec.ts +++ b/packages/block/test/eip1559block.spec.ts @@ -442,7 +442,7 @@ describe('EIP1559 tests', () => { } ) - const errs = block.validateTransactions(true) + const errs = block.getTransactionsValidationErrors() assert.ok( errs[0].includes('unable to pay base fee'), 'should throw if transaction is unable to pay base fee' diff --git a/packages/block/test/eip4844block.spec.ts b/packages/block/test/eip4844block.spec.ts index 5dc110cd8f..6e154fd7ae 100644 --- a/packages/block/test/eip4844block.spec.ts +++ b/packages/block/test/eip4844block.spec.ts @@ -250,7 +250,7 @@ describe('transaction validation tests', () => { assert.ok( blockWithTooManyBlobs - .validateTransactions(true) + .getTransactionsValidationErrors() .join(' ') .includes('exceed maximum data gas per block'), 'tx erros includes correct error message when too many blobs in a block' diff --git a/packages/block/test/eip4895block.spec.ts b/packages/block/test/eip4895block.spec.ts index a90d3698e4..12690b504b 100644 --- a/packages/block/test/eip4895block.spec.ts +++ b/packages/block/test/eip4895block.spec.ts @@ -130,7 +130,7 @@ describe('EIP4895 tests', () => { } ) assert.notOk( - await block.validateWithdrawalsTrie(), + await block.withdrawalsTrieIsValid(), 'should invalidate the empty withdrawals root' ) const validHeader = BlockHeader.fromHeaderData( @@ -148,7 +148,7 @@ describe('EIP4895 tests', () => { common, } ) - assert.ok(await validBlock.validateWithdrawalsTrie(), 'should validate empty withdrawals root') + assert.ok(await validBlock.withdrawalsTrieIsValid(), 'should validate empty withdrawals root') const withdrawal = { index: BigInt(0), @@ -171,7 +171,7 @@ describe('EIP4895 tests', () => { } ) assert.ok( - await validBlockWithWithdrawal.validateWithdrawalsTrie(), + await validBlockWithWithdrawal.withdrawalsTrieIsValid(), 'should validate withdrawals root' ) @@ -196,7 +196,7 @@ describe('EIP4895 tests', () => { } ) assert.ok( - await validBlockWithWithdrawal2.validateWithdrawalsTrie(), + await validBlockWithWithdrawal2.withdrawalsTrieIsValid(), 'should validate withdrawals root' ) assert.doesNotThrow(() => { diff --git a/packages/block/test/from-rpc.spec.ts b/packages/block/test/from-rpc.spec.ts index c43867146b..fb3dd30d75 100644 --- a/packages/block/test/from-rpc.spec.ts +++ b/packages/block/test/from-rpc.spec.ts @@ -96,13 +96,13 @@ describe('[fromRPC]:', () => { it('should create a block with uncles', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul }) const block = blockFromRpc(blockDataWithUncles, [uncleBlockData], { common }) - assert.ok(block.validateUnclesHash()) + assert.ok(block.uncleHashIsValid()) }) it('should create a block with EIP-4896 withdrawals', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai }) const block = blockFromRpc(blockDataWithWithdrawals, [], { common }) - assert.ok(block.validateWithdrawalsTrie()) + assert.ok(block.withdrawalsTrieIsValid()) }) it('should create a block header with the correct hash when EIP-4896 withdrawals are present', () => { diff --git a/packages/client/test/rpc/eth/getStorageAt.spec.ts b/packages/client/test/rpc/eth/getStorageAt.spec.ts index 8a197a2080..a4ef8d8ae5 100644 --- a/packages/client/test/rpc/eth/getStorageAt.spec.ts +++ b/packages/client/test/rpc/eth/getStorageAt.spec.ts @@ -32,7 +32,7 @@ tape(`${method}: call with valid arguments`, async (t) => { // construct block with tx const gasLimit = 2000000 const tx = LegacyTransaction.fromTxData({ gasLimit, data }, { common, freeze: false }) - const signedTx = tx.sign(tx.getMessageToSign()) + const signedTx = tx.sign(tx.getHashedMessageToSign()) const parent = await chain.blockchain.getCanonicalHeadHeader() const block = Block.fromBlockData( diff --git a/packages/devp2p/examples/peer-communication-les.cts b/packages/devp2p/examples/peer-communication-les.cts index 98fddfdf48..66e458c98c 100644 --- a/packages/devp2p/examples/peer-communication-les.cts +++ b/packages/devp2p/examples/peer-communication-les.cts @@ -211,15 +211,11 @@ function onNewBlock(block: Block, peer: Peer) { ) } -function isValidTx(tx: TypedTransaction) { - return tx.validate() -} - async function isValidBlock(block: Block) { return ( - block.validateUnclesHash() && - block.transactions.every(isValidTx) && - block.validateTransactionsTrie() + block.uncleHashIsValid() && + block.transactions.every(({ isValid }) => isValid()) && + block.transactionsTrieIsValid() ) } diff --git a/packages/devp2p/examples/peer-communication.cts b/packages/devp2p/examples/peer-communication.cts index f892b4a345..ce43ea5f6e 100644 --- a/packages/devp2p/examples/peer-communication.cts +++ b/packages/devp2p/examples/peer-communication.cts @@ -136,7 +136,7 @@ rlpx.on('peer:added', (peer) => { for (const item of payload) { const tx = TransactionFactory.fromBlockBodyData(item) - if (isValidTx(tx)) onNewTx(tx, peer) + if (tx.isValid()) onNewTx(tx, peer) } break @@ -352,15 +352,11 @@ function onNewBlock(block: Block, peer: Peer) { for (const tx of block.transactions) onNewTx(tx, peer) } -function isValidTx(tx: TypedTransaction) { - return tx.validate() -} - async function isValidBlock(block: Block) { return ( - block.validateUnclesHash() && - block.transactions.every(isValidTx) && - block.validateTransactionsTrie() + block.uncleHashIsValid() && + block.transactions.every(({ isValid }) => isValid()) && + block.transactionsTrieIsValid() ) } diff --git a/packages/tx/README.md b/packages/tx/README.md index c6d7f06a7d..ec40d48717 100644 --- a/packages/tx/README.md +++ b/packages/tx/README.md @@ -340,7 +340,7 @@ const common = Common.custom({ chainId: 1234 }) ### Signing with a hardware or external wallet -To sign a tx with a hardware or external wallet use `tx.getMessageToSign(false)` to return an [EIP-155](https://eips.ethereum.org/EIPS/eip-155) compliant unsigned tx. +To sign a tx with a hardware or external wallet use `tx.getMessageToSign()` to return an [EIP-155](https://eips.ethereum.org/EIPS/eip-155) compliant unsigned tx. A legacy transaction will return a Buffer list of the values, and a Typed Transaction ([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)) will return the serialized output. @@ -365,7 +365,7 @@ const bip32Path = "44'/60'/0'/0/0" const run = async () => { // Signing a legacy tx tx = LegacyTransaction.fromTxData(txData, { common }) - unsignedTx = tx.getMessageToSign(false) + unsignedTx = tx.getMessageToSign() unsignedTx = Buffer.from(RLP.encode(bufArrToArr(unsignedTx))) // ledger signTransaction API expects it to be serialized let { v, r, s } = await eth.signTransaction(bip32Path, unsignedTx) txData = { ...txData, v, r, s } @@ -376,7 +376,7 @@ const run = async () => { // Signing a 1559 tx txData = { value: 1 } tx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }) - unsignedTx = tx.getMessageToSign(false) + unsignedTx = tx.getMessageToSign() ;({ v, r, s } = await eth.signTransaction(bip32Path, unsignedTx)) // this syntax is: object destructuring - assignment without declaration txData = { ...txData, v, r, s } signedTx = FeeMarketEIP1559Transaction.fromTxData(txData, { common }) diff --git a/packages/tx/docs/classes/AccessListEIP2930Transaction.md b/packages/tx/docs/classes/AccessListEIP2930Transaction.md index 40b41a522d..cee9015560 100644 --- a/packages/tx/docs/classes/AccessListEIP2930Transaction.md +++ b/packages/tx/docs/classes/AccessListEIP2930Transaction.md @@ -378,7 +378,7 @@ Note: in contrast to the legacy tx the raw message format is already serialized and doesn't need to be RLP encoded any more. ```javascript -const serializedMessage = tx.getMessageToSign(false) // use this for the HW wallet input +const serializedMessage = tx.getMessageToSign() // use this for the HW wallet input ``` #### Parameters diff --git a/packages/tx/docs/classes/FeeMarketEIP1559Transaction.md b/packages/tx/docs/classes/FeeMarketEIP1559Transaction.md index afb408adfa..0ef5c36238 100644 --- a/packages/tx/docs/classes/FeeMarketEIP1559Transaction.md +++ b/packages/tx/docs/classes/FeeMarketEIP1559Transaction.md @@ -389,7 +389,7 @@ Note: in contrast to the legacy tx the raw message format is already serialized and doesn't need to be RLP encoded any more. ```javascript -const serializedMessage = tx.getMessageToSign(false) // use this for the HW wallet input +const serializedMessage = tx.getMessageToSign() // use this for the HW wallet input ``` #### Parameters diff --git a/packages/tx/docs/classes/Transaction.md b/packages/tx/docs/classes/Transaction.md index 8fd4753c9c..d2a50c77c7 100644 --- a/packages/tx/docs/classes/Transaction.md +++ b/packages/tx/docs/classes/Transaction.md @@ -317,7 +317,7 @@ and you might need to do yourself with: ```javascript import { bufArrToArr } from '@ethereumjs/util' import { RLP } from '@ethereumjs/rlp' -const message = tx.getMessageToSign(false) +const message = tx.getMessageToSign() const serializedMessage = Buffer.from(RLP.encode(bufArrToArr(message))) // use this for the HW wallet input ``` diff --git a/packages/tx/examples/custom-chain-tx.cts b/packages/tx/examples/custom-chain-tx.cts index f4e5f01bb5..32b49eb627 100644 --- a/packages/tx/examples/custom-chain-tx.cts +++ b/packages/tx/examples/custom-chain-tx.cts @@ -40,7 +40,7 @@ const privateKey = hexToBytes('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dc const signedTx = tx.sign(privateKey) const address = Address.fromPrivateKey(privateKey) -if (signedTx.validate() && signedTx.getSenderAddress().equals(address)) { +if (signedTx.isValid() && signedTx.getSenderAddress().equals(address)) { console.log('Valid signature') } else { console.log('Invalid signature') diff --git a/packages/tx/examples/ropsten-tx.cts b/packages/tx/examples/ropsten-tx.cts index 8b44bbaf2b..b2b77b17e0 100644 --- a/packages/tx/examples/ropsten-tx.cts +++ b/packages/tx/examples/ropsten-tx.cts @@ -10,7 +10,7 @@ const common = new Common({ chain: Chain.Ropsten, hardfork: Hardfork.Petersburg const tx = LegacyTransaction.fromSerializedTx(txData, { common }) if ( - tx.validate() && + tx.isValid() && tx.getSenderAddress().toString() === '0x9dfd2d2b2ed960923f7bf2e8883d73f213f3b24b' ) { console.log('Correctly created the tx') diff --git a/packages/tx/src/baseTransaction.ts b/packages/tx/src/baseTransaction.ts index 28979c21a1..753c0a972f 100644 --- a/packages/tx/src/baseTransaction.ts +++ b/packages/tx/src/baseTransaction.ts @@ -143,7 +143,7 @@ export abstract class BaseTransaction * tx type is unknown (e.g. when instantiated with * the tx factory). * - * See `Capabilites` in the `types` module for a reference + * See `Capabilities` in the `types` module for a reference * on all supported capabilities. */ supports(capability: Capability) { @@ -151,24 +151,31 @@ export abstract class BaseTransaction } /** - * Checks if the transaction has the minimum amount of gas required - * (DataFee + TxFee + Creation Fee). + * Validates the transaction signature and minimum gas requirements. + * @returns {string[]} an array of error strings */ - validate(): boolean - validate(stringError: false): boolean - validate(stringError: true): string[] - validate(stringError: boolean = false): boolean | string[] { + getValidationErrors(): string[] { const errors = [] + if (this.isSigned() && !this.verifySignature()) { + errors.push('Invalid Signature') + } + if (this.getBaseFee() > this.gasLimit) { errors.push(`gasLimit is too low. given ${this.gasLimit}, need at least ${this.getBaseFee()}`) } - if (this.isSigned() && !this.verifySignature()) { - errors.push('Invalid Signature') - } + return errors + } + + /** + * Validates the transaction signature and minimum gas requirements. + * @returns {boolean} true if the transaction is valid, false otherwise + */ + isValid(): boolean { + const errors = this.getValidationErrors() - return stringError ? errors : errors.length === 0 + return errors.length === 0 } protected _validateYParity() { @@ -257,12 +264,11 @@ export abstract class BaseTransaction */ abstract serialize(): Uint8Array - // Returns the unsigned tx (hashed or raw), which is used to sign the transaction. - // - // Note: do not use code docs here since VS Studio is then not able to detect the - // comments from the inherited methods - abstract getMessageToSign(hashMessage: false): Uint8Array | Uint8Array[] - abstract getMessageToSign(hashMessage?: true): Uint8Array + // Returns the raw unsigned tx, which is used to sign the transaction. + abstract getMessageToSign(): Uint8Array | Uint8Array[] + + // Returns the hashed unsigned tx, which is used to sign the transaction. + abstract getHashedMessageToSign(): Uint8Array abstract hash(): Uint8Array @@ -331,7 +337,7 @@ export abstract class BaseTransaction hackApplied = true } - const msgHash = this.getMessageToSign(true) + const msgHash = this.getHashedMessageToSign() const { v, r, s } = ecsign(msgHash, privateKey) const tx = this._processSignature(v, r, s) diff --git a/packages/tx/src/eip1559Transaction.ts b/packages/tx/src/eip1559Transaction.ts index 026d1fada3..3f25da4f06 100644 --- a/packages/tx/src/eip1559Transaction.ts +++ b/packages/tx/src/eip1559Transaction.ts @@ -276,26 +276,31 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction { return RLP.encode(this.raw()) } - private _getMessageToSign() { - const values = [ + /** + * Returns the raw unsigned tx, which can be used + * to sign the transaction (e.g. for sending to a hardware wallet). + * + * Note: the raw message message format for the legacy tx is not RLP encoded + * and you might need to do yourself with: + * + * ```javascript + * import { RLP } from '@ethereumjs/rlp' + * const message = tx.getMessageToSign() + * const serializedMessage = RLP.encode(message)) // use this for the HW wallet input + * ``` + */ + getMessageToSign(): Uint8Array[] { + const message = [ bigIntToUnpaddedBytes(this.nonce), bigIntToUnpaddedBytes(this.gasPrice), bigIntToUnpaddedBytes(this.gasLimit), @@ -194,38 +207,21 @@ export class LegacyTransaction extends BaseTransaction { ] if (this.supports(Capability.EIP155ReplayProtection)) { - values.push(bigIntToUnpaddedBytes(this.common.chainId())) - values.push(unpadBytes(toBytes(0))) - values.push(unpadBytes(toBytes(0))) + message.push(bigIntToUnpaddedBytes(this.common.chainId())) + message.push(unpadBytes(toBytes(0))) + message.push(unpadBytes(toBytes(0))) } - return values + return message } /** - * Returns the unsigned tx (hashed or raw), which can be used + * Returns the hashed serialized unsigned tx, which can be used * to sign the transaction (e.g. for sending to a hardware wallet). - * - * Note: the raw message message format for the legacy tx is not RLP encoded - * and you might need to do yourself with: - * - * ```javascript - * import { RLP } from '@ethereumjs/rlp' - * const message = tx.getMessageToSign(false) - * const serializedMessage = RLP.encode(message)) // use this for the HW wallet input - * ``` - * - * @param hashMessage - Return hashed message if set to true (default: true) */ - getMessageToSign(hashMessage: false): Uint8Array[] - getMessageToSign(hashMessage?: true): Uint8Array - getMessageToSign(hashMessage = true) { - const message = this._getMessageToSign() - if (hashMessage) { - return keccak256(RLP.encode(message)) - } else { - return message - } + getHashedMessageToSign() { + const message = this.getMessageToSign() + return keccak256(RLP.encode(message)) } /** @@ -283,8 +279,7 @@ export class LegacyTransaction extends BaseTransaction { const msg = this._errorMsg('This transaction is not signed') throw new Error(msg) } - const message = this._getMessageToSign() - return keccak256(RLP.encode(message)) + return this.getHashedMessageToSign() } /** diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index 7f7c4726bb..ddc833e3e6 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -131,21 +131,19 @@ export function isBlobEIP4844Tx(tx: TypedTransaction): tx is BlobEIP4844Transact export interface TransactionInterface { supports(capability: Capability): boolean type: number - validate(): boolean - validate(stringError: false): boolean - validate(stringError: true): string[] - validate(stringError: boolean): boolean | string[] getBaseFee(): bigint getDataFee(): bigint getUpfrontCost(): bigint toCreationAddress(): boolean raw(): TxValuesArray[T] serialize(): Uint8Array - getMessageToSign(hashMessage: false): Uint8Array | Uint8Array[] - getMessageToSign(hashMessage?: true): Uint8Array + getMessageToSign(): Uint8Array | Uint8Array[] + getHashedMessageToSign(): Uint8Array hash(): Uint8Array getMessageToVerifySignature(): Uint8Array + getValidationErrors(): string[] isSigned(): boolean + isValid(): boolean verifySignature(): boolean getSenderAddress(): Address getSenderPublicKey(): Uint8Array diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index 68470c1d6b..aacd631982 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -261,10 +261,10 @@ describe('[BaseTransaction]', () => { const tx = txType.class.fromTxData((txFixture as any).data, { common }) assert.equal(tx.verifySignature(), false, `${txType.name}: signature should not be valid`) assert.ok( - (tx.validate(true)).includes('Invalid Signature'), + tx.getValidationErrors().includes('Invalid Signature'), `${txType.name}: should return an error string about not verifying signatures` ) - assert.notOk(tx.validate(), `${txType.name}: should not validate correctly`) + assert.notOk(tx.isValid(), `${txType.name}: should not validate correctly`) } } }) diff --git a/packages/tx/test/eip1559.spec.ts b/packages/tx/test/eip1559.spec.ts index 64ac0ef914..b958582051 100644 --- a/packages/tx/test/eip1559.spec.ts +++ b/packages/tx/test/eip1559.spec.ts @@ -145,7 +145,7 @@ describe('[FeeMarketEIP1559Transaction]', () => { assert.ok(signedTxn.common.eips().includes(2537), 'signed tx common is taken from tx.common') }) - it('unsigned tx -> getMessageToSign()', () => { + it('unsigned tx -> getMessageToSign()/getHashedMessageToSign()', () => { const unsignedTx = FeeMarketEIP1559Transaction.fromTxData( { data: hexStringToBytes('010200'), @@ -158,13 +158,13 @@ describe('[FeeMarketEIP1559Transaction]', () => { const expectedHash = hexStringToBytes( 'fa81814f7dd57bad435657a05eabdba2815f41e3f15ddd6139027e7db56b0dea' ) - assert.deepEqual(unsignedTx.getMessageToSign(true), expectedHash), 'correct hashed version' + assert.deepEqual(unsignedTx.getHashedMessageToSign(), expectedHash), 'correct hashed version' const expectedSerialization = hexStringToBytes( '02f85904808080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101' ) assert.deepEqual( - unsignedTx.getMessageToSign(false), + unsignedTx.getMessageToSign(), expectedSerialization, 'correct serialized unhashed version' ) diff --git a/packages/tx/test/eip4844.spec.ts b/packages/tx/test/eip4844.spec.ts index e0a40f11da..afa1abe72a 100644 --- a/packages/tx/test/eip4844.spec.ts +++ b/packages/tx/test/eip4844.spec.ts @@ -444,7 +444,7 @@ describe('hash() and signature verification', () => { { common } ) assert.equal( - bytesToHex(unsignedTx.getMessageToSign(true)), + bytesToHex(unsignedTx.getHashedMessageToSign()), '8ce8c3544ca173c0e8dd0e86319d4ebfe649e15a730137a6659ba3a721a9ff8b', 'produced the correct transaction hash' ) @@ -513,7 +513,7 @@ describe('Network wrapper deserialization test', () => { ) assert.ok(equalsBytes(deserializedTx.kzgProofs![0], proofs[0]), 'proofs should match') - const unsignedHash = bytesToHex(deserializedTx.getMessageToSign()) + const unsignedHash = bytesToHex(deserializedTx.getHashedMessageToSign()) const hash = bytesToHex(deserializedTx.hash()) const networkSerialized = bytesToHex(deserializedTx.serializeNetworkWrapper()) const serialized = bytesToHex(deserializedTx.serialize()) diff --git a/packages/tx/test/legacy.spec.ts b/packages/tx/test/legacy.spec.ts index 43c030c744..a7200788c7 100644 --- a/packages/tx/test/legacy.spec.ts +++ b/packages/tx/test/legacy.spec.ts @@ -135,9 +135,15 @@ describe('[Transaction]', () => { }) }) - it('validate() -> should validate with string option', () => { + it('getValidationErrors() -> should validate', () => { for (const tx of transactions) { - assert.equal(typeof tx.validate(true)[0], 'string') + assert.equal(typeof tx.getValidationErrors()[0], 'string') + } + }) + + it('isValid() -> should validate', () => { + for (const tx of transactions) { + assert.equal(typeof tx.isValid(), 'boolean') } }) @@ -205,7 +211,7 @@ describe('[Transaction]', () => { assert.ok(equalsBytes(s1, s2)) }) - it('hash() / getMessageToSign(true) / getMessageToSign(false)', () => { + it('hash() / getHashedMessageToSign() / getMessageToSign()', () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.TangerineWhistle, @@ -230,10 +236,10 @@ describe('[Transaction]', () => { hexStringToBytes('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa') ) assert.deepEqual( - tx.getMessageToSign(), + tx.getHashedMessageToSign(), hexStringToBytes('61e1ec33764304dddb55348e7883d4437426f44ab3ef65e6da1e025734c03ff0') ) - assert.equal(tx.getMessageToSign(false).length, 6) + assert.equal(tx.getMessageToSign().length, 6) assert.deepEqual( tx.hash(), hexStringToBytes('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa') @@ -251,21 +257,21 @@ describe('[Transaction]', () => { '0f09dc98ea85b7872f4409131a790b91e7540953992886fc268b7ba5c96820e4' ) assert.equal( - bytesToHex(tx.getMessageToSign()), + bytesToHex(tx.getHashedMessageToSign()), 'f97c73fdca079da7652dbc61a46cd5aeef804008e057be3e712c43eac389aaf0' ) }) - it("getMessageToSign(), getSenderPublicKey() (implicit call) -> verify EIP155 signature based on Vitalik's tests", () => { + it("getHashedMessageToSign(), getSenderPublicKey() (implicit call) -> verify EIP155 signature based on Vitalik's tests", () => { for (const tx of txFixturesEip155) { const pt = LegacyTransaction.fromSerializedTx(toBytes(tx.rlp)) - assert.equal(bytesToHex(pt.getMessageToSign()), tx.hash) + assert.equal(bytesToHex(pt.getHashedMessageToSign()), tx.hash) assert.equal(bytesToPrefixedHexString(pt.serialize()), tx.rlp) assert.equal(pt.getSenderAddress().toString(), '0x' + tx.sender) } }) - it('getMessageToSign(), sign(), getSenderPublicKey() (implicit call) -> verify EIP155 signature before and after signing', () => { + it('getHashedMessageToSign(), sign(), getSenderPublicKey() (implicit call) -> verify EIP155 signature before and after signing', () => { // Inputs and expected results for this test are taken directly from the example in https://eips.ethereum.org/EIPS/eip-155 const txRaw = [ '0x09', @@ -289,7 +295,7 @@ describe('[Transaction]', () => { ) const signedTx = pt.sign(privateKey) assert.equal( - bytesToHex(signedTx.getMessageToSign()), + bytesToHex(signedTx.getHashedMessageToSign()), 'daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53' ) assert.equal( diff --git a/packages/tx/test/transactionRunner.spec.ts b/packages/tx/test/transactionRunner.spec.ts index 7faf7a6a0f..018d142c24 100644 --- a/packages/tx/test/transactionRunner.spec.ts +++ b/packages/tx/test/transactionRunner.spec.ts @@ -72,7 +72,7 @@ describe('TransactionTests', async () => { const tx = TransactionFactory.fromSerializedData(rawTx, { common }) const sender = tx.getSenderAddress().toString() const hash = bytesToHex(tx.hash()) - const txIsValid = tx.validate() + const txIsValid = tx.isValid() const senderIsCorrect = forkTestData.sender === sender const hashIsCorrect = forkTestData.hash?.slice(2) === hash diff --git a/packages/tx/test/typedTxsAndEIP2930.spec.ts b/packages/tx/test/typedTxsAndEIP2930.spec.ts index 93174f841f..2889900b09 100644 --- a/packages/tx/test/typedTxsAndEIP2930.spec.ts +++ b/packages/tx/test/typedTxsAndEIP2930.spec.ts @@ -511,7 +511,7 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { assert.equal(tx.getUpfrontCost(), BigInt(10000000042)) }) - it('unsigned tx -> getMessageToSign()', () => { + it('unsigned tx -> getHashedMessageToSign()/getMessageToSign()', () => { const unsignedTx = AccessListEIP2930Transaction.fromTxData( { data: hexStringToBytes('010200'), @@ -524,13 +524,13 @@ describe('[AccessListEIP2930Transaction] -> Class Specific Tests', () => { const expectedHash = hexStringToBytes( '78528e2724aa359c58c13e43a7c467eb721ce8d410c2a12ee62943a3aaefb60b' ) - assert.deepEqual(unsignedTx.getMessageToSign(true), expectedHash), 'correct hashed version' + assert.deepEqual(unsignedTx.getHashedMessageToSign(), expectedHash), 'correct hashed version' const expectedSerialization = hexStringToBytes( '01f858018080809401010101010101010101010101010101010101018083010200f838f7940101010101010101010101010101010101010101e1a00101010101010101010101010101010101010101010101010101010101010101' ) assert.deepEqual( - unsignedTx.getMessageToSign(false), + unsignedTx.getMessageToSign(), expectedSerialization, 'correct serialized unhashed version' ) diff --git a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts index 5f2309d62f..efe8502118 100644 --- a/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts +++ b/packages/vm/test/tester/runners/GeneralStateTestsRunner.ts @@ -125,7 +125,7 @@ async function runTestCase(options: any, testData: any, t: tape.Test) { } if (tx) { - if (tx.validate()) { + if (tx.isValid()) { const block = makeBlockFromEnv(testData.env, { common }) if (options.jsontrace === true) {