Skip to content

Commit ced64de

Browse files
committed
tx: some function reordering, remove tx.getChainId() API function
1 parent eddd88c commit ced64de

File tree

4 files changed

+177
-173
lines changed

4 files changed

+177
-173
lines changed

packages/tx/src/baseTransaction.ts

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -36,43 +36,51 @@ export abstract class BaseTransaction<TransactionObject> {
3636
value: this.value,
3737
}
3838

39-
this.validateExceedsMaxInteger(validateCannotExceedMaxInteger)
39+
this._validateExceedsMaxInteger(validateCannotExceedMaxInteger)
4040

4141
this.common =
4242
(txOptions.common &&
4343
Object.assign(Object.create(Object.getPrototypeOf(txOptions.common)), txOptions.common)) ??
4444
new Common({ chain: 'mainnet' })
4545
}
4646

47-
protected validateExceedsMaxInteger(validateCannotExceedMaxInteger: { [key: string]: BN }) {
48-
for (const [key, value] of Object.entries(validateCannotExceedMaxInteger)) {
49-
if (value && value.gt(MAX_INTEGER)) {
50-
throw new Error(`${key} cannot exceed MAX_INTEGER, given ${value}`)
51-
}
52-
}
53-
}
54-
5547
/**
56-
* If the tx's `to` is to the creation address
48+
* Checks if the transaction has the minimum amount of gas required
49+
* (DataFee + TxFee + Creation Fee).
5750
*/
58-
toCreationAddress(): boolean {
59-
return this.to === undefined || this.to.buf.length === 0
60-
}
61-
6251
/**
63-
* Computes a sha3-256 hash of the serialized unsigned tx, which is used to sign the transaction.
52+
* Checks if the transaction has the minimum amount of gas required
53+
* (DataFee + TxFee + Creation Fee).
6454
*/
65-
rawTxHash(): Buffer {
66-
return this.getMessageToSign()
67-
}
55+
validate(): boolean
56+
/* eslint-disable-next-line no-dupe-class-members */
57+
validate(stringError: false): boolean
58+
/* eslint-disable-next-line no-dupe-class-members */
59+
validate(stringError: true): string[]
60+
/* eslint-disable-next-line no-dupe-class-members */
61+
validate(stringError: boolean = false): boolean | string[] {
62+
const errors = []
6863

69-
abstract getMessageToSign(): Buffer
64+
if (this.getBaseFee().gt(this.gasLimit)) {
65+
errors.push(`gasLimit is too low. given ${this.gasLimit}, need at least ${this.getBaseFee()}`)
66+
}
67+
68+
if (this.isSigned() && !this.verifySignature()) {
69+
errors.push('Invalid Signature')
70+
}
71+
72+
return stringError ? errors : errors.length === 0
73+
}
7074

7175
/**
72-
* Returns chain ID
76+
* The minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee)
7377
*/
74-
getChainId(): number {
75-
return this.common.chainId()
78+
getBaseFee(): BN {
79+
const fee = this.getDataFee().addn(this.common.param('gasPrices', 'tx'))
80+
if (this.common.gteHardfork('homestead') && this.toCreationAddress()) {
81+
fee.iaddn(this.common.param('gasPrices', 'txCreation'))
82+
}
83+
return fee
7684
}
7785

7886
/**
@@ -89,17 +97,6 @@ export abstract class BaseTransaction<TransactionObject> {
8997
return new BN(cost)
9098
}
9199

92-
/**
93-
* The minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee)
94-
*/
95-
getBaseFee(): BN {
96-
const fee = this.getDataFee().addn(this.common.param('gasPrices', 'tx'))
97-
if (this.common.gteHardfork('homestead') && this.toCreationAddress()) {
98-
fee.iaddn(this.common.param('gasPrices', 'txCreation'))
99-
}
100-
return fee
101-
}
102-
103100
/**
104101
* The up front amount that an account must have for this transaction to be valid
105102
*/
@@ -108,42 +105,42 @@ export abstract class BaseTransaction<TransactionObject> {
108105
}
109106

110107
/**
111-
* Checks if the transaction has the minimum amount of gas required
112-
* (DataFee + TxFee + Creation Fee).
108+
* If the tx's `to` is to the creation address
113109
*/
110+
toCreationAddress(): boolean {
111+
return this.to === undefined || this.to.buf.length === 0
112+
}
113+
114114
/**
115-
* Checks if the transaction has the minimum amount of gas required
116-
* (DataFee + TxFee + Creation Fee).
115+
* Returns the raw `Buffer[]` (Transaction) or `Buffer` (typed transaction).
116+
* This is the data which is found in the transactions of the block body.
117+
*
118+
* Note that if you want to use this function in a tx type independent way
119+
* to then use the raw data output for tx instantiation with
120+
* `Tx.fromValuesArray()` you should set the `asList` parameter to `true` -
121+
* which is ignored on a legacy tx but provides the correct format on
122+
* a typed tx.
123+
*
124+
* To prepare a tx to be added as block data with `Block.fromValuesArray()`
125+
* just use the plain `raw()` method.
117126
*/
118-
validate(): boolean
119-
/* eslint-disable-next-line no-dupe-class-members */
120-
validate(stringError: false): boolean
121-
/* eslint-disable-next-line no-dupe-class-members */
122-
validate(stringError: true): string[]
123-
/* eslint-disable-next-line no-dupe-class-members */
124-
validate(stringError: boolean = false): boolean | string[] {
125-
const errors = []
126-
127-
if (this.getBaseFee().gt(this.gasLimit)) {
128-
errors.push(`gasLimit is too low. given ${this.gasLimit}, need at least ${this.getBaseFee()}`)
129-
}
130-
131-
if (this.isSigned() && !this.verifySignature()) {
132-
errors.push('Invalid Signature')
133-
}
134-
135-
return stringError ? errors : errors.length === 0
136-
}
127+
abstract raw(asList: boolean): Buffer[] | Buffer
137128

138129
/**
139130
* Returns the encoding of the transaction.
140131
*/
141132
abstract serialize(): Buffer
142133

143134
/**
144-
* Returns an object with the JSON representation of the transaction
135+
* Computes a sha3-256 hash of the serialized unsigned tx, which is used to sign the transaction.
145136
*/
146-
abstract toJSON(): JsonTx
137+
rawTxHash(): Buffer {
138+
return this.getMessageToSign()
139+
}
140+
141+
abstract getMessageToSign(): Buffer
142+
143+
abstract hash(): Buffer
147144

148145
abstract isSigned(): boolean
149146

@@ -160,14 +157,8 @@ export abstract class BaseTransaction<TransactionObject> {
160157
}
161158
}
162159

163-
/**
164-
* Returns the raw `Buffer[]` (Transaction) or `Buffer` (typed transaction).
165-
* This is the data which is found in the transactions of the block body.
166-
*/
167-
abstract raw(): Buffer[] | Buffer
168-
abstract hash(): Buffer
169-
170160
abstract getMessageToVerifySignature(): Buffer
161+
171162
/**
172163
* Returns the sender's address
173164
*/
@@ -187,9 +178,22 @@ export abstract class BaseTransaction<TransactionObject> {
187178
/* eslint-disable-next-line prefer-const */
188179
let { v, r, s } = ecsign(msgHash, privateKey)
189180

190-
return this.processSignature(v, r, s)
181+
return this._processSignature(v, r, s)
191182
}
192183

193184
// Accept the v,r,s values from the `sign` method, and convert this into a TransactionObject
194-
protected abstract processSignature(v: number, r: Buffer, s: Buffer): TransactionObject
185+
protected abstract _processSignature(v: number, r: Buffer, s: Buffer): TransactionObject
186+
187+
/**
188+
* Returns an object with the JSON representation of the transaction
189+
*/
190+
abstract toJSON(): JsonTx
191+
192+
protected _validateExceedsMaxInteger(validateCannotExceedMaxInteger: { [key: string]: BN }) {
193+
for (const [key, value] of Object.entries(validateCannotExceedMaxInteger)) {
194+
if (value && value.gt(MAX_INTEGER)) {
195+
throw new Error(`${key} cannot exceed MAX_INTEGER, given ${value}`)
196+
}
197+
}
198+
}
195199
}

packages/tx/src/eip2930Transaction.ts

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,6 @@ export default class AccessListEIP2930Transaction extends BaseTransaction<Access
220220
}
221221
}
222222

223-
getMessageToSign() {
224-
const base = this.raw(true).slice(0, 8)
225-
return keccak256(Buffer.concat([Buffer.from('01', 'hex'), rlp.encode(base)]))
226-
}
227-
228223
/**
229224
* The amount of gas paid for the data in this tx
230225
*/
@@ -279,41 +274,9 @@ export default class AccessListEIP2930Transaction extends BaseTransaction<Access
279274
return <Buffer>this.raw()
280275
}
281276

282-
/**
283-
* Returns an object with the JSON representation of the transaction
284-
*/
285-
toJSON(): JsonTx {
286-
const accessListJSON = []
287-
288-
for (let index = 0; index < this.accessList.length; index++) {
289-
const item: any = this.accessList[index]
290-
const JSONItem: any = {
291-
address: '0x' + setLengthLeft(<Buffer>item[0], 20).toString('hex'),
292-
storageKeys: [],
293-
}
294-
const storageSlots: Buffer[] = item[1]
295-
for (let slot = 0; slot < storageSlots.length; slot++) {
296-
const storageSlot = storageSlots[slot]
297-
JSONItem.storageKeys.push('0x' + setLengthLeft(storageSlot, 32).toString('hex'))
298-
}
299-
accessListJSON.push(JSONItem)
300-
}
301-
302-
return {
303-
chainId: bnToHex(this.chainId),
304-
nonce: bnToHex(this.nonce),
305-
gasPrice: bnToHex(this.gasPrice),
306-
gasLimit: bnToHex(this.gasLimit),
307-
to: this.to !== undefined ? this.to.toString() : undefined,
308-
value: bnToHex(this.value),
309-
data: '0x' + this.data.toString('hex'),
310-
accessList: accessListJSON,
311-
}
312-
}
313-
314-
public isSigned(): boolean {
315-
const { yParity, r, s } = this
316-
return yParity !== undefined && !!r && !!s
277+
getMessageToSign() {
278+
const base = this.raw(true).slice(0, 8)
279+
return keccak256(Buffer.concat([Buffer.from('01', 'hex'), rlp.encode(base)]))
317280
}
318281

319282
public hash(): Buffer {
@@ -328,6 +291,11 @@ export default class AccessListEIP2930Transaction extends BaseTransaction<Access
328291
return this.getMessageToSign()
329292
}
330293

294+
public isSigned(): boolean {
295+
const { yParity, r, s } = this
296+
return yParity !== undefined && !!r && !!s
297+
}
298+
331299
public getSenderPublicKey(): Buffer {
332300
if (!this.isSigned()) {
333301
throw new Error('Cannot call this method if transaction is not signed')
@@ -360,7 +328,7 @@ export default class AccessListEIP2930Transaction extends BaseTransaction<Access
360328
}
361329
}
362330

363-
processSignature(v: number, r: Buffer, s: Buffer) {
331+
_processSignature(v: number, r: Buffer, s: Buffer) {
364332
const opts = {
365333
common: this.common,
366334
}
@@ -382,4 +350,36 @@ export default class AccessListEIP2930Transaction extends BaseTransaction<Access
382350
opts
383351
)
384352
}
353+
354+
/**
355+
* Returns an object with the JSON representation of the transaction
356+
*/
357+
toJSON(): JsonTx {
358+
const accessListJSON = []
359+
360+
for (let index = 0; index < this.accessList.length; index++) {
361+
const item: any = this.accessList[index]
362+
const JSONItem: any = {
363+
address: '0x' + setLengthLeft(<Buffer>item[0], 20).toString('hex'),
364+
storageKeys: [],
365+
}
366+
const storageSlots: Buffer[] = item[1]
367+
for (let slot = 0; slot < storageSlots.length; slot++) {
368+
const storageSlot = storageSlots[slot]
369+
JSONItem.storageKeys.push('0x' + setLengthLeft(storageSlot, 32).toString('hex'))
370+
}
371+
accessListJSON.push(JSONItem)
372+
}
373+
374+
return {
375+
chainId: bnToHex(this.chainId),
376+
nonce: bnToHex(this.nonce),
377+
gasPrice: bnToHex(this.gasPrice),
378+
gasLimit: bnToHex(this.gasLimit),
379+
to: this.to !== undefined ? this.to.toString() : undefined,
380+
value: bnToHex(this.value),
381+
data: '0x' + this.data.toString('hex'),
382+
accessList: accessListJSON,
383+
}
384+
}
385385
}

0 commit comments

Comments
 (0)