Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tx: get rid of BaseTransaction #3744

Merged
merged 29 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fb11275
tx: remove basetx [WIP] [no ci]
jochem-brouwer Oct 17, 2024
31c3c75
tx: prep legacy tx to remove basetx [no ci]
jochem-brouwer Nov 5, 2024
acca777
tx: move basetx constructor to shared constructor fn
jochem-brouwer Nov 7, 2024
d3ff76c
tx: move json stuff to shared
jochem-brouwer Nov 7, 2024
eb6124f
tx: add comment
jochem-brouwer Nov 7, 2024
eedb3ce
tx: 2930 remove basetx
jochem-brouwer Nov 7, 2024
c9e855a
tx: rename AccessList2930Transaction -> AccessList2930Tx
jochem-brouwer Nov 7, 2024
06fa07c
tx: legacy use shared legacy isSigned
jochem-brouwer Nov 7, 2024
f4cb214
Merge branch 'master' into tx-remove-basetx
jochem-brouwer Nov 7, 2024
f0d06cd
tx: mini cleanup
jochem-brouwer Nov 8, 2024
51a4660
tx: 2930 remove validateArray
jochem-brouwer Nov 8, 2024
f2a5691
tx: fix comment
jochem-brouwer Nov 8, 2024
7d24fd9
tx: 2930 move methods around
jochem-brouwer Nov 8, 2024
6983480
tx: 1559 remove basetx
jochem-brouwer Nov 8, 2024
3a2649b
tx: 1559 group data part
jochem-brouwer Nov 8, 2024
35828dd
tx: 4844 remove basetx
jochem-brouwer Nov 8, 2024
6e834e2
tx: legacy/2930 clarify data part
jochem-brouwer Nov 8, 2024
a251a91
tx: 7702 remove basetx and rename to EOACode7702Tx
jochem-brouwer Nov 8, 2024
4c980c3
tx: fix build/imports
jochem-brouwer Nov 8, 2024
b55fc95
vm: fix build
jochem-brouwer Nov 8, 2024
686ed86
tx: use correct PrefixedHexString for toJSON
jochem-brouwer Nov 8, 2024
7f4c803
Merge branch 'master' into tx-remove-basetx
jochem-brouwer Nov 8, 2024
62627c9
Merge branch 'tx-remove-basetx' of github.com:ethereumjs/ethereumjs-m…
jochem-brouwer Nov 8, 2024
06eaaf1
tx: fix tests
jochem-brouwer Nov 9, 2024
7a4bd1c
vm/tx: fix more tests
jochem-brouwer Nov 9, 2024
8910a40
tx: tests comment out failing tsc line
jochem-brouwer Nov 9, 2024
03b7caf
tx: cleanup error msgs
jochem-brouwer Nov 10, 2024
6a9b15e
throw when gasPrice passed to 1559 tx
acolytec3 Nov 11, 2024
226135b
Revert "throw when gasPrice passed to 1559 tx"
acolytec3 Nov 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 115 additions & 28 deletions packages/tx/src/1559/tx.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Common } from '@ethereumjs/common'
import {
BIGINT_0,
BIGINT_27,
Expand All @@ -9,14 +8,13 @@ import {
toBytes,
} from '@ethereumjs/util'

import { BaseTransaction } from '../baseTransaction.js'
import * as EIP1559 from '../capabilities/eip1559.js'
import * as EIP2718 from '../capabilities/eip2718.js'
import * as EIP2930 from '../capabilities/eip2930.js'
import * as Legacy from '../capabilities/legacy.js'
import { paramsTx } from '../params.js'
import { getBaseJSON, sharedConstructor, valueBoundaryCheck } from '../features/util.js'
import { TransactionType } from '../types.js'
import { AccessLists, validateNotArray } from '../util.js'
import { AccessLists } from '../util.js'

import { createFeeMarket1559Tx } from './constructors.js'

Expand All @@ -25,9 +23,14 @@ import type {
AccessListBytes,
TxData as AllTypesTxData,
TxValuesArray as AllTypesTxValuesArray,
Capability,
JSONTx,
TransactionCache,
TransactionInterface,
TxOptions,
} from '../types.js'
import type { Common } from '@ethereumjs/common'
import type { Address } from '@ethereumjs/util'

export type TxData = AllTypesTxData[TransactionType.FeeMarketEIP1559]
export type TxValuesArray = AllTypesTxValuesArray[TransactionType.FeeMarketEIP1559]
Expand All @@ -38,15 +41,42 @@ export type TxValuesArray = AllTypesTxValuesArray[TransactionType.FeeMarketEIP15
* - TransactionType: 2
* - EIP: [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)
*/
export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEIP1559> {
export class FeeMarket1559Tx implements TransactionInterface<TransactionType.FeeMarketEIP1559> {
// implements EIP1559CompatibleTx<TransactionType.FeeMarketEIP1559>
public readonly chainId: bigint
public type: number = TransactionType.FeeMarketEIP1559 // 1559 tx type

// Tx data part (part of the RLP)
public readonly nonce!: bigint
public readonly gasLimit!: bigint
public readonly value!: bigint
public readonly data!: Uint8Array
public readonly to?: Address
public readonly accessList: AccessListBytes
public readonly AccessListJSON: AccessList
public readonly chainId: bigint
public readonly maxPriorityFeePerGas: bigint
public readonly maxFeePerGas: bigint

public readonly common: Common
// Props only for signed txs
public readonly v?: bigint
public readonly r?: bigint
public readonly s?: bigint

// End of Tx data part

public readonly AccessListJSON: AccessList

public readonly common!: Common

readonly txOptions!: TxOptions

readonly cache: TransactionCache = {}

/**
* List of tx type defining EIPs,
* e.g. 1559 (fee market) and 2930 (access lists)
* for FeeMarket1559Tx objects
*/
protected activeCapabilities: number[] = []

/**
* This constructor takes the values, validates them, assigns them and freezes the object.
Expand All @@ -56,16 +86,14 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
* varying data types.
*/
public constructor(txData: TxData, opts: TxOptions = {}) {
super({ ...txData, type: TransactionType.FeeMarketEIP1559 }, opts)
sharedConstructor(this, { ...txData, type: TransactionType.FeeMarketEIP1559 }, opts)
const { chainId, accessList, maxFeePerGas, maxPriorityFeePerGas } = txData

this.common = opts.common?.copy() ?? new Common({ chain: this.DEFAULT_CHAIN })
if (chainId !== undefined && bytesToBigInt(toBytes(chainId)) !== this.common.chainId()) {
throw new Error(
`Common chain ID ${this.common.chainId} not matching the derived chain ID ${chainId}`,
)
}
this.common.updateParams(opts.params ?? paramsTx)
this.chainId = this.common.chainId()

if (!this.common.isActivatedEIP(1559)) {
Expand All @@ -83,20 +111,22 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
this.maxFeePerGas = bytesToBigInt(toBytes(maxFeePerGas))
this.maxPriorityFeePerGas = bytesToBigInt(toBytes(maxPriorityFeePerGas))

this._validateCannotExceedMaxInteger({
valueBoundaryCheck({
maxFeePerGas: this.maxFeePerGas,
maxPriorityFeePerGas: this.maxPriorityFeePerGas,
})

validateNotArray(txData)

if (this.gasLimit * this.maxFeePerGas > MAX_INTEGER) {
const msg = this._errorMsg('gasLimit * maxFeePerGas cannot exceed MAX_INTEGER (2^256-1)')
const msg = Legacy.errorMsg(
this,
'gasLimit * maxFeePerGas cannot exceed MAX_INTEGER (2^256-1)',
)
throw new Error(msg)
}

if (this.maxFeePerGas < this.maxPriorityFeePerGas) {
const msg = this._errorMsg(
const msg = Legacy.errorMsg(
this,
'maxFeePerGas cannot be less than maxPriorityFeePerGas (The total must be the larger of the two)',
)
throw new Error(msg)
Expand All @@ -111,6 +141,26 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
}
}

/**
* Checks if a tx type defining capability is active
* on a tx, for example the EIP-1559 fee market mechanism
* or the EIP-2930 access list feature.
*
* Note that this is different from the tx type itself,
* so EIP-2930 access lists can very well be active
* on an EIP-1559 tx for example.
*
* This method can be useful for feature checks if the
* tx type is unknown (e.g. when instantiated with
* the tx factory).
*
* See `Capabilities` in the `types` module for a reference
* on all supported capabilities.
*/
supports(capability: Capability) {
return this.activeCapabilities.includes(capability)
}

/**
* The amount of gas paid for the data in this tx
*/
Expand All @@ -134,6 +184,24 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
return EIP1559.getUpfrontCost(this, baseFee)
}

/**
* The minimum gas limit which the tx to have to be valid.
* This covers costs as the standard fee (21000 gas), the data fee (paid for each calldata byte),
* the optional creation fee (if the transaction creates a contract), and if relevant the gas
* to be paid for access lists (EIP-2930) and authority lists (EIP-7702).
*/
getIntrinsicGas(): bigint {
return Legacy.getIntrinsicGas(this)
}

// TODO figure out if this is necessary
/**
* If the tx's `to` is to the creation address
*/
toCreationAddress(): boolean {
return Legacy.toCreationAddress(this)
}

/**
* Returns a Uint8Array Array of the raw Bytes of the EIP-1559 transaction, in order.
*
Expand Down Expand Up @@ -262,7 +330,7 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
*/
toJSON(): JSONTx {
const accessListJSON = AccessLists.getAccessListJSON(this.accessList)
const baseJSON = super.toJSON()
const baseJSON = getBaseJSON(this)

return {
...baseJSON,
Expand All @@ -273,22 +341,41 @@ export class FeeMarket1559Tx extends BaseTransaction<TransactionType.FeeMarketEI
}
}

getValidationErrors(): string[] {
return Legacy.getValidationErrors(this)
}

isValid(): boolean {
return Legacy.isValid(this)
}

verifySignature(): boolean {
return Legacy.verifySignature(this)
}

getSenderAddress(): Address {
return Legacy.getSenderAddress(this)
}

sign(privateKey: Uint8Array): FeeMarket1559Tx {
return <FeeMarket1559Tx>Legacy.sign(this, privateKey)
}

public isSigned(): boolean {
const { v, r, s } = this
if (v === undefined || r === undefined || s === undefined) {
return false
} else {
return true
}
}

/**
* Return a compact error string representation of the object
*/
public errorStr() {
let errorStr = this._getSharedErrorPostfix()
let errorStr = Legacy.getSharedErrorPostfix(this)
errorStr += ` maxFeePerGas=${this.maxFeePerGas} maxPriorityFeePerGas=${this.maxPriorityFeePerGas}`
return errorStr
}

/**
* Internal helper function to create an annotated error message
*
* @param msg Base error message
* @hidden
*/
protected _errorMsg(msg: string) {
return Legacy.errorMsg(this, msg)
}
}
6 changes: 3 additions & 3 deletions packages/tx/src/2930/constructors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { bytesToBigInt, bytesToHex, equalsBytes, validateNoLeadingZeroes } from
import { TransactionType } from '../types.js'
import { txTypeBytes, validateNotArray } from '../util.js'

import { AccessList2930Transaction } from './tx.js'
import { AccessList2930Tx } from './tx.js'

import type { AccessList, TxOptions } from '../types.js'
import type { TxData, TxValuesArray } from './tx.js'
Expand All @@ -20,7 +20,7 @@ import type { TxData, TxValuesArray } from './tx.js'
* - All parameters are optional and have some basic default values
*/
export function createAccessList2930Tx(txData: TxData, opts: TxOptions = {}) {
return new AccessList2930Transaction(txData, opts)
return new AccessList2930Tx(txData, opts)
}

/**
Expand All @@ -43,7 +43,7 @@ export function createAccessList2930TxFromBytesArray(values: TxValuesArray, opts

const emptyAccessList: AccessList = []

return new AccessList2930Transaction(
return new AccessList2930Tx(
{
chainId: bytesToBigInt(chainId),
nonce,
Expand Down
2 changes: 1 addition & 1 deletion packages/tx/src/2930/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './constructors.js'
export { AccessList2930Transaction } from './tx.js'
export { AccessList2930Tx } from './tx.js'
Loading
Loading