feat(rpc): set eip1559 gasPrice field (#2579)

This commit is contained in:
Matthias Seitz
2023-05-05 19:08:52 +02:00
committed by GitHub
parent 09f1a5b640
commit 35e2421022
7 changed files with 74 additions and 39 deletions

View File

@@ -363,26 +363,6 @@ impl Transaction {
}
}
// TODO: dedup with effective_tip_per_gas
/// Determine the effective gas limit for the given transaction and base fee.
/// If the base fee is `None`, the `max_priority_fee_per_gas`, or gas price for non-EIP1559
/// transactions is returned.
///
/// If the `max_fee_per_gas` is less than the base fee, `None` returned.
pub fn effective_gas_tip(&self, base_fee: Option<u64>) -> Option<u128> {
if let Some(base_fee) = base_fee {
let max_fee_per_gas = self.max_fee_per_gas();
if max_fee_per_gas < base_fee as u128 {
None
} else {
let effective_max_fee = max_fee_per_gas - base_fee as u128;
Some(std::cmp::min(effective_max_fee, self.priority_fee_or_price()))
}
} else {
Some(self.priority_fee_or_price())
}
}
/// Return the max priority fee per gas if the transaction is an EIP-1559 transaction, and
/// otherwise return the gas price.
///
@@ -413,7 +393,28 @@ impl Transaction {
dynamic_tx.effective_gas_price(base_fee)
}
/// Returns the effective miner gas tip cap (`gasTipCap`) for the given base fee.
// TODO: dedup with effective_tip_per_gas
/// Determine the effective gas limit for the given transaction and base fee.
/// If the base fee is `None`, the `max_priority_fee_per_gas`, or gas price for non-EIP1559
/// transactions is returned.
///
/// If the `max_fee_per_gas` is less than the base fee, `None` returned.
pub fn effective_gas_tip(&self, base_fee: Option<u64>) -> Option<u128> {
if let Some(base_fee) = base_fee {
let max_fee_per_gas = self.max_fee_per_gas();
if max_fee_per_gas < base_fee as u128 {
None
} else {
let effective_max_fee = max_fee_per_gas - base_fee as u128;
Some(std::cmp::min(effective_max_fee, self.priority_fee_or_price()))
}
} else {
Some(self.priority_fee_or_price())
}
}
/// Returns the effective miner gas tip cap (`gasTipCap`) for the given base fee:
/// `min(maxFeePerGas - baseFee, maxPriorityFeePerGas)`
///
/// Returns `None` if the basefee is higher than the [Transaction::max_fee_per_gas].
pub fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> {

View File

@@ -64,7 +64,7 @@ impl ParityTraceBuilder {
info: TransactionInfo,
) -> impl Iterator<Item = LocalizedTransactionTrace> {
self.into_transaction_traces_iter().map(move |trace| {
let TransactionInfo { hash, index, block_hash, block_number } = info;
let TransactionInfo { hash, index, block_hash, block_number, .. } = info;
LocalizedTransactionTrace {
trace,
transaction_position: index,

View File

@@ -144,6 +144,7 @@ impl Block {
signed_tx,
block_hash,
block_number,
block.base_fee_per_gas,
U256::from(idx),
))
}

View File

@@ -14,4 +14,6 @@ pub struct TransactionInfo {
pub block_hash: Option<H256>,
/// Number of the block.
pub block_number: Option<u64>,
/// Base fee of the block.
pub base_fee: Option<u64>,
}

View File

@@ -80,18 +80,27 @@ impl Transaction {
tx: TransactionSignedEcRecovered,
block_hash: H256,
block_number: BlockNumber,
base_fee: Option<u64>,
tx_index: U256,
) -> Self {
let mut tx = Self::from_recovered(tx);
tx.block_hash = Some(block_hash);
tx.block_number = Some(U256::from(block_number));
tx.transaction_index = Some(tx_index);
tx
Self::fill(tx, Some(block_hash), Some(block_number), base_fee, Some(tx_index))
}
/// Create a new rpc transaction result for a _pending_ signed transaction, setting block
/// environment related fields to `None`.
pub fn from_recovered(tx: TransactionSignedEcRecovered) -> Self {
Self::fill(tx, None, None, None, None)
}
/// Create a new rpc transaction result for a _pending_ signed transaction, setting block
/// environment related fields to `None`.
fn fill(
tx: TransactionSignedEcRecovered,
block_hash: Option<H256>,
block_number: Option<BlockNumber>,
base_fee: Option<u64>,
transaction_index: Option<U256>,
) -> Self {
let signer = tx.signer();
let signed_tx = tx.into_signed();
@@ -103,7 +112,17 @@ impl Transaction {
let (gas_price, max_fee_per_gas) = match signed_tx.tx_type() {
TxType::Legacy => (Some(U128::from(signed_tx.max_fee_per_gas())), None),
TxType::EIP2930 => (None, Some(U128::from(signed_tx.max_fee_per_gas()))),
TxType::EIP1559 => (None, Some(U128::from(signed_tx.max_fee_per_gas()))),
TxType::EIP1559 => {
// the gas price field for EIP1559 is set to `min(tip, gasFeeCap - baseFee) +
// baseFee`
let gas_price = base_fee
.and_then(|base_fee| {
signed_tx.effective_tip_per_gas(base_fee).map(|tip| tip + base_fee as u128)
})
.unwrap_or_else(|| signed_tx.max_fee_per_gas());
(Some(U128::from(gas_price)), Some(U128::from(signed_tx.max_fee_per_gas())))
}
};
let chain_id = signed_tx.chain_id().map(U64::from);
@@ -154,9 +173,9 @@ impl Transaction {
transaction_type: Some(U64::from(signed_tx.tx_type() as u8)),
// These fields are set to None because they are not stored as part of the transaction
block_hash: None,
block_number: None,
transaction_index: None,
block_hash,
block_number: block_number.map(U256::from),
transaction_index,
}
}
}

View File

@@ -234,11 +234,12 @@ where
let transaction =
tx.into_ecrecovered().ok_or(EthApiError::InvalidTransactionSignature)?;
let tx = TransactionSource::Database {
let tx = TransactionSource::Block {
transaction,
index: meta.index,
block_hash: meta.block_hash,
block_number: meta.block_number,
base_fee: meta.base_fee,
};
Ok(Some(tx))
}
@@ -256,18 +257,20 @@ where
tx @ TransactionSource::Pool(_) => {
(tx, BlockId::Number(BlockNumberOrTag::Pending))
}
TransactionSource::Database {
TransactionSource::Block {
transaction,
index,
block_hash,
block_number,
base_fee,
} => {
let at = BlockId::Hash(block_hash.into());
let tx = TransactionSource::Database {
let tx = TransactionSource::Block {
transaction,
index,
block_hash,
block_number,
base_fee,
};
(tx, at)
}
@@ -548,6 +551,7 @@ where
tx,
block_hash,
block.header.number,
block.header.base_fee_per_gas,
index.into(),
)))
}
@@ -644,8 +648,10 @@ where
pub enum TransactionSource {
/// Transaction exists in the pool (Pending)
Pool(TransactionSignedEcRecovered),
/// Transaction already executed
Database {
/// Transaction already included in a block
///
/// This can be a historical block or a pending block (received from the CL)
Block {
/// Transaction fetched via provider
transaction: TransactionSignedEcRecovered,
/// Index of the transaction in the block
@@ -654,6 +660,8 @@ pub enum TransactionSource {
block_hash: H256,
/// Number of the block.
block_number: u64,
/// base fee of the block.
base_fee: Option<u64>,
},
}
@@ -677,10 +685,11 @@ impl TransactionSource {
index: None,
block_hash: None,
block_number: None,
base_fee: None,
},
)
}
TransactionSource::Database { transaction, index, block_hash, block_number } => {
TransactionSource::Block { transaction, index, block_hash, block_number, base_fee } => {
let hash = transaction.hash();
(
transaction,
@@ -689,6 +698,7 @@ impl TransactionSource {
index: Some(index),
block_hash: Some(block_hash),
block_number: Some(block_number),
base_fee,
},
)
}
@@ -700,7 +710,7 @@ impl From<TransactionSource> for TransactionSignedEcRecovered {
fn from(value: TransactionSource) -> Self {
match value {
TransactionSource::Pool(tx) => tx,
TransactionSource::Database { transaction, .. } => transaction,
TransactionSource::Block { transaction, .. } => transaction,
}
}
}
@@ -709,11 +719,12 @@ impl From<TransactionSource> for Transaction {
fn from(value: TransactionSource) -> Self {
match value {
TransactionSource::Pool(tx) => Transaction::from_recovered(tx),
TransactionSource::Database { transaction, index, block_hash, block_number } => {
TransactionSource::Block { transaction, index, block_hash, block_number, base_fee } => {
Transaction::from_recovered_with_block_context(
transaction,
block_hash,
block_number,
base_fee,
U256::from(index),
)
}

View File

@@ -237,6 +237,7 @@ where
index: Some(idx as u64),
block_hash: Some(block_hash),
block_number: Some(block_env.number.try_into().unwrap_or(u64::MAX)),
base_fee: Some(block_env.basefee.try_into().unwrap_or(u64::MAX)),
};
let tx = tx_env_with_recovered(&tx);