From e99e7f0ba6b5e943d981d7800d0fb32706f9405b Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:43:21 +1200 Subject: [PATCH] Assume rpc transaction has gasPrice set, even for EIP-1559 Fee Market transaction --- .../src/eip1559-fee-market-transaction.ts | 15 +-- .../src/transaction-serialization.ts | 96 +++++++------------ 2 files changed, 38 insertions(+), 73 deletions(-) diff --git a/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts b/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts index 103534cdf4..3aa6e1c04d 100644 --- a/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts +++ b/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts @@ -239,22 +239,9 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { public updateEffectiveGasPrice(baseFeePerGas: bigint) { const maxFeePerGas = this.maxFeePerGas.toBigInt(); const maxPriorityFeePerGas = this.maxPriorityFeePerGas.toBigInt(); - const effectiveGasPrice = EIP1559FeeMarketTransaction.getEffectiveGasPrice( - baseFeePerGas, - maxFeePerGas, - maxPriorityFeePerGas - ); - this.effectiveGasPrice = Quantity.from(effectiveGasPrice); - } - - public static getEffectiveGasPrice( - baseFeePerGas: bigint, - maxFeePerGas: bigint, - maxPriorityFeePerGas: bigint - ): bigint { const a = maxFeePerGas - baseFeePerGas; const tip = a < maxPriorityFeePerGas ? a : maxPriorityFeePerGas; - return baseFeePerGas + tip; + this.effectiveGasPrice = Quantity.from(baseFeePerGas + tip); } } diff --git a/src/chains/ethereum/transaction/src/transaction-serialization.ts b/src/chains/ethereum/transaction/src/transaction-serialization.ts index 70d9d64b58..78ba0e3922 100644 --- a/src/chains/ethereum/transaction/src/transaction-serialization.ts +++ b/src/chains/ethereum/transaction/src/transaction-serialization.ts @@ -6,7 +6,6 @@ import { TransactionType } from "./transaction-factory"; import { Transaction } from "./rpc-transaction"; import { AccessLists } from "./access-lists"; import { CodedError } from "@ganache/ethereum-utils"; -import { EIP1559FeeMarketTransaction } from "./eip1559-fee-market-transaction"; export function serializeRpcForDb( tx: Transaction, @@ -21,30 +20,12 @@ export function serializeRpcForDb( type = parseInt(tx.type, 16); } - let effectiveGasPrice: Quantity; - - switch (type) { - case TransactionType.Legacy: - case TransactionType.EIP2930AccessList: - effectiveGasPrice = Quantity.from(tx.gasPrice); - break; - case TransactionType.EIP1559AccessList: - effectiveGasPrice = Quantity.from( - EIP1559FeeMarketTransaction.getEffectiveGasPrice( - // this becomes problematic because we need the baseFeePerGas which - // comes from the block :( - 0n, - Quantity.toBigInt(tx.maxFeePerGas), - Quantity.toBigInt(tx.maxPriorityFeePerGas) - ) - ); - break; - } const txData = { raw: rawFromRpc(tx, type), from: Address.from(tx.from), hash: Data.from((tx as any).hash, 32), - effectiveGasPrice, + // this assumes that gasPrice has been set - even for EIP-1559 Fee Market transactions + effectiveGasPrice: Quantity.from(tx.gasPrice), type: Quantity.from(type) }; @@ -72,7 +53,7 @@ export function serializeForDb( // block it twice for each block save step. legacy ? tx.raw : ([tx.type.toBuffer(), ...tx.raw] as any), [ - tx.from.toBuffer(), + tx.from.buf, tx.hash.toBuffer(), blockHash.toBuffer(), blockNumber.toBuffer(), @@ -83,10 +64,19 @@ export function serializeForDb( return encode(txAndExtraData); } -export function rawFromRpc( - txData: Transaction, - txType: number -): TypedRawTransaction { +function rawFromRpc(txData: Transaction, txType: number): TypedRawTransaction { + const chainId = Quantity.toBuffer(txData.chainId); + const nonce = Quantity.toBuffer(txData.nonce); + const gasPrice = Quantity.toBuffer(txData.gasPrice); + const gasLimit = Quantity.toBuffer(txData.gas || txData.gasLimit); + // todo: use Address type + const to = Data.toBuffer(txData.to, 20); + const value = Quantity.toBuffer(txData.value); + const data = Data.toBuffer(txData.data || txData.input); + const v = Data.toBuffer((txData as any).v); + const r = Data.toBuffer((txData as any).r); + const s = Data.toBuffer((txData as any).s); + // if no access list is provided, we convert to legacy const targetType = txType === TransactionType.EIP2930AccessList && @@ -96,54 +86,42 @@ export function rawFromRpc( switch (targetType) { case TransactionType.Legacy: - return [ - Quantity.toBuffer(txData.nonce), - Quantity.toBuffer(txData.gasPrice), - Quantity.toBuffer(txData.gas || txData.gasLimit), - // todo: use address? - Data.toBuffer(txData.to, 20), - Quantity.toBuffer(txData.value), - Data.toBuffer(txData.data || txData.input), - Data.toBuffer((txData as any).v), - Data.toBuffer((txData as any).r), - Data.toBuffer((txData as any).s) - ]; + return [nonce, gasPrice, gasLimit, to, value, data, v, r, s]; case TransactionType.EIP2930AccessList: return [ - Quantity.toBuffer(txData.chainId), - Quantity.toBuffer(txData.nonce), - Quantity.toBuffer(txData.gasPrice), - Quantity.toBuffer(txData.gas || txData.gasLimit), - // todo: use address? - Data.toBuffer(txData.to, 20), - Quantity.toBuffer(txData.value), - Data.toBuffer(txData.data || txData.input), + chainId, + nonce, + gasPrice, + gasLimit, + to, + value, + data, // accesslists is _always_ set, otherwise it's legacy txData.accessList ? AccessLists.getAccessListData(txData.accessList).accessList : [], - Data.toBuffer((txData as any).v), - Data.toBuffer((txData as any).r), - Data.toBuffer((txData as any).s) + v, + r, + s ]; // todo: should this be TransactionType.EIP1559FeeMarket? case TransactionType.EIP1559AccessList: return [ - Quantity.toBuffer(txData.chainId), - Quantity.toBuffer(txData.nonce), + chainId, + nonce, + Quantity.toBuffer(txData.maxPriorityFeePerGas), Quantity.toBuffer(txData.maxFeePerGas), - Quantity.toBuffer(txData.gas || txData.gasLimit), - // todo: use address? - Data.toBuffer(txData.to, 20), - Quantity.toBuffer(txData.value), - Data.toBuffer(txData.data || txData.input), + gasLimit, + to, + value, + data, txData.accessList ? AccessLists.getAccessListData(txData.accessList).accessList : [], - Data.toBuffer((txData as any).v), - Data.toBuffer((txData as any).r), - Data.toBuffer((txData as any).s) + v, + r, + s ]; default: throw new CodedError(