feat(primitives): effective_gas_tip and effective_tip_per_gas functions together (#5144)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
DoTheBestToGetTheBest
2023-11-02 07:31:30 -07:00
committed by GitHub
parent 0449c5eca6
commit 93fc2e2991
7 changed files with 27 additions and 39 deletions

View File

@ -802,8 +802,9 @@ where
})); }));
// update add to total fees // update add to total fees
let miner_fee = let miner_fee = tx
tx.effective_tip_per_gas(base_fee).expect("fee is always valid; execution succeeded"); .effective_tip_per_gas(Some(base_fee))
.expect("fee is always valid; execution succeeded");
total_fees += U256::from(miner_fee) * U256::from(gas_used); total_fees += U256::from(miner_fee) * U256::from(gas_used);
// append transaction to the list of executed transactions // append transaction to the list of executed transactions

View File

@ -307,50 +307,35 @@ 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())
}
}
/// Returns the effective miner gas tip cap (`gasTipCap`) for the given base fee: /// Returns the effective miner gas tip cap (`gasTipCap`) for the given base fee:
/// `min(maxFeePerGas - baseFee, maxPriorityFeePerGas)` /// `min(maxFeePerGas - baseFee, maxPriorityFeePerGas)`
/// ///
/// If the base fee is `None`, the `max_priority_fee_per_gas`, or gas price for non-EIP1559
/// transactions is returned.
///
/// Returns `None` if the basefee is higher than the [Transaction::max_fee_per_gas]. /// 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> { pub fn effective_tip_per_gas(&self, base_fee: Option<u64>) -> Option<u128> {
let base_fee = base_fee as u128; let base_fee = match base_fee {
Some(base_fee) => base_fee as u128,
None => return Some(self.priority_fee_or_price()),
};
let max_fee_per_gas = self.max_fee_per_gas(); let max_fee_per_gas = self.max_fee_per_gas();
// Check if max_fee_per_gas is less than base_fee
if max_fee_per_gas < base_fee { if max_fee_per_gas < base_fee {
return None return None
} }
// the miner tip is the difference between the max fee and the base fee or the // Calculate the difference between max_fee_per_gas and base_fee
// max_priority_fee_per_gas, whatever is lower
// SAFETY: max_fee_per_gas >= base_fee
let fee = max_fee_per_gas - base_fee; let fee = max_fee_per_gas - base_fee;
// Compare the fee with max_priority_fee_per_gas (or gas price for non-EIP1559 transactions)
if let Some(priority_fee) = self.max_priority_fee_per_gas() { if let Some(priority_fee) = self.max_priority_fee_per_gas() {
return Some(fee.min(priority_fee)) Some(fee.min(priority_fee))
} else {
Some(fee)
} }
Some(fee)
} }
/// Get the transaction's input field. /// Get the transaction's input field.

View File

@ -54,7 +54,9 @@ fn fill(
// baseFee` // baseFee`
let gas_price = base_fee let gas_price = base_fee
.and_then(|base_fee| { .and_then(|base_fee| {
signed_tx.effective_tip_per_gas(base_fee).map(|tip| tip + base_fee as u128) signed_tx
.effective_tip_per_gas(Some(base_fee))
.map(|tip| tip + base_fee as u128)
}) })
.unwrap_or_else(|| signed_tx.max_fee_per_gas()); .unwrap_or_else(|| signed_tx.max_fee_per_gas());

View File

@ -163,7 +163,7 @@ where
Some(TxGasAndReward { Some(TxGasAndReward {
gas_used, gas_used,
reward: tx.effective_gas_tip(header.base_fee_per_gas).unwrap_or_default(), reward: tx.effective_tip_per_gas(header.base_fee_per_gas).unwrap_or_default(),
}) })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -96,7 +96,7 @@ where
let tx = tx.into_ecrecovered_transaction(); let tx = tx.into_ecrecovered_transaction();
hash_bytes.extend_from_slice(tx.hash().as_slice()); hash_bytes.extend_from_slice(tx.hash().as_slice());
let gas_price = tx let gas_price = tx
.effective_gas_tip(basefee) .effective_tip_per_gas(basefee)
.ok_or_else(|| RpcInvalidTransactionError::FeeCapTooLow)?; .ok_or_else(|| RpcInvalidTransactionError::FeeCapTooLow)?;
tx.try_fill_tx_env(&mut evm.env.tx)?; tx.try_fill_tx_env(&mut evm.env.tx)?;
let ResultAndState { result, state } = evm.transact()?; let ResultAndState { result, state } = evm.transact()?;

View File

@ -237,7 +237,7 @@ where
let parent_hash = block.parent_hash; let parent_hash = block.parent_hash;
// sort the functions by ascending effective tip first // sort the functions by ascending effective tip first
block.body.sort_by_cached_key(|tx| tx.effective_gas_tip(base_fee_per_gas)); block.body.sort_by_cached_key(|tx| tx.effective_tip_per_gas(base_fee_per_gas));
let mut prices = Vec::with_capacity(limit); let mut prices = Vec::with_capacity(limit);
@ -245,7 +245,7 @@ where
let mut effective_gas_tip = None; let mut effective_gas_tip = None;
// ignore transactions with a tip under the configured threshold // ignore transactions with a tip under the configured threshold
if let Some(ignore_under) = self.ignore_price { if let Some(ignore_under) = self.ignore_price {
let tip = tx.effective_gas_tip(base_fee_per_gas); let tip = tx.effective_tip_per_gas(base_fee_per_gas);
effective_gas_tip = Some(tip); effective_gas_tip = Some(tip);
if tip < Some(ignore_under) { if tip < Some(ignore_under) {
continue continue
@ -262,7 +262,7 @@ where
// a `None` effective_gas_tip represents a transaction where the max_fee_per_gas is // a `None` effective_gas_tip represents a transaction where the max_fee_per_gas is
// less than the base fee which would be invalid // less than the base fee which would be invalid
let effective_gas_tip = effective_gas_tip let effective_gas_tip = effective_gas_tip
.unwrap_or_else(|| tx.effective_gas_tip(base_fee_per_gas)) .unwrap_or_else(|| tx.effective_tip_per_gas(base_fee_per_gas))
.ok_or(RpcInvalidTransactionError::FeeCapTooLow)?; .ok_or(RpcInvalidTransactionError::FeeCapTooLow)?;
prices.push(U256::from(effective_gas_tip)); prices.push(U256::from(effective_gas_tip));

View File

@ -938,7 +938,7 @@ impl PoolTransaction for EthPooledTransaction {
/// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`.
/// For legacy transactions: `gas_price - base_fee`. /// For legacy transactions: `gas_price - base_fee`.
fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> { fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> {
self.transaction.effective_tip_per_gas(base_fee) self.transaction.effective_tip_per_gas(Some(base_fee))
} }
/// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and /// Returns the max priority fee per gas if the transaction is an EIP-1559 transaction, and