diff --git a/bin/oe/cli/mod.rs b/bin/oe/cli/mod.rs index 216b7177c..82115ad9a 100644 --- a/bin/oe/cli/mod.rs +++ b/bin/oe/cli/mod.rs @@ -680,7 +680,7 @@ usage! { ARG arg_min_gas_price: (Option) = None, or |c: &Config| c.mining.as_ref()?.min_gas_price.clone(), "--min-gas-price=[STRING]", - "Minimum amount of Wei per GAS to be paid for a transaction to be accepted for mining. Overrides --usd-per-tx.", + "Minimum amount of Wei per GAS to be paid for a transaction on top of base fee, to be accepted for mining. Overrides --usd-per-tx.", ARG arg_gas_price_percentile: (usize) = 50usize, or |c: &Config| c.mining.as_ref()?.gas_price_percentile, "--gas-price-percentile=[PCT]", diff --git a/crates/concensus/miner/src/pool/queue.rs b/crates/concensus/miner/src/pool/queue.rs index 82d41b84c..11ad76050 100644 --- a/crates/concensus/miner/src/pool/queue.rs +++ b/crates/concensus/miner/src/pool/queue.rs @@ -659,7 +659,10 @@ impl TransactionQueue { Some(tx) => tx .signed() .effective_gas_price(self.options.read().block_base_fee), - None => self.options.read().minimal_gas_price, + None => { + self.options.read().minimal_gas_price + + self.options.read().block_base_fee.unwrap_or_default() + } } } diff --git a/crates/concensus/miner/src/pool/verifier.rs b/crates/concensus/miner/src/pool/verifier.rs index b8053bb8f..1f08d9ce8 100644 --- a/crates/concensus/miner/src/pool/verifier.rs +++ b/crates/concensus/miner/src/pool/verifier.rs @@ -42,7 +42,7 @@ use super::{ /// Verification options. #[derive(Debug, Clone, PartialEq)] pub struct Options { - /// Minimal allowed gas price. + /// Minimal allowed gas price (actually minimal block producer reward = effective_priority_fee). pub minimal_gas_price: U256, /// Current block gas limit. pub block_gas_limit: U256, @@ -122,6 +122,24 @@ impl Transaction { } } + /// Return effective fee - part of the transaction fee that goes to the miner + pub fn effective_priority_fee(&self, block_base_fee: Option) -> U256 { + match *self { + Transaction::Unverified(ref tx) => tx.effective_priority_fee(block_base_fee), + Transaction::Retracted(ref tx) => tx.effective_priority_fee(block_base_fee), + Transaction::Local(ref tx) => tx.effective_priority_fee(block_base_fee), + } + } + + /// Cheeck if transaction is service transaction + pub fn is_service(&self) -> bool { + match *self { + Transaction::Unverified(ref tx) => tx.is_service(), + Transaction::Retracted(ref tx) => tx.is_service(), + Transaction::Local(ref tx) => tx.is_service(), + } + } + fn transaction(&self) -> &transaction::TypedTransaction { match *self { Transaction::Unverified(ref tx) => &*tx, @@ -225,24 +243,26 @@ impl txpool::Verifier } let is_own = tx.is_local(); - let gas_price = tx.effective_gas_price(self.options.block_base_fee); + let is_service = tx.is_service(); // Quick exit for non-service and non-local transactions // // We're checking if the transaction is below configured minimal gas price // or the effective minimal gas price in case the pool is full. - if !gas_price.is_zero() && !is_own { - if gas_price < self.options.minimal_gas_price { + if !is_service && !is_own { + let effective_priority_fee = tx.effective_priority_fee(self.options.block_base_fee); + + if effective_priority_fee < self.options.minimal_gas_price { trace!( target: "txqueue", "[{:?}] Rejected tx below minimal gas price threshold: {} < {}", hash, - gas_price, + effective_priority_fee, self.options.minimal_gas_price, ); bail!(transaction::Error::InsufficientGasPrice { minimal: self.options.minimal_gas_price, - got: gas_price, + got: effective_priority_fee, }); } @@ -252,7 +272,7 @@ impl txpool::Verifier target: "txqueue", "[{:?}] Rejected tx early, cause it doesn't have any chance to get to the pool: (gas price: {} < {})", hash, - gas_price, + tx.effective_gas_price(self.options.block_base_fee), vtx.transaction.effective_gas_price(self.options.block_base_fee), ); return Err(transaction::Error::TooCheapToReplace { @@ -260,7 +280,7 @@ impl txpool::Verifier vtx.transaction .effective_gas_price(self.options.block_base_fee), ), - new: Some(gas_price), + new: Some(tx.effective_gas_price(self.options.block_base_fee)), }); } } diff --git a/crates/ethcore/src/tx_filter.rs b/crates/ethcore/src/tx_filter.rs index 118d776b8..963dcb06a 100644 --- a/crates/ethcore/src/tx_filter.rs +++ b/crates/ethcore/src/tx_filter.rs @@ -39,10 +39,7 @@ use_contract!( transact_acl_gas_price, "res/contracts/tx_acl_gas_price.json" ); -use_contract!( - transact_acl_1559, - "res/contracts/tx_acl_1559.json" -); +use_contract!(transact_acl_1559, "res/contracts/tx_acl_1559.json"); const MAX_CACHE_SIZE: usize = 4096; @@ -169,16 +166,15 @@ impl TransactionFilter { } 4 => { trace!(target: "tx_filter", "Using filter with maxFeePerGas and maxPriorityFeePerGas and data"); - let (data, decoder) = - transact_acl_1559::functions::allowed_tx_types::call( - sender, - to, - value, - gas_price, - max_priority_fee_per_gas, - gas_limit, - transaction.tx().data.clone(), - ); + let (data, decoder) = transact_acl_1559::functions::allowed_tx_types::call( + sender, + to, + value, + gas_price, + max_priority_fee_per_gas, + gas_limit, + transaction.tx().data.clone(), + ); client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) .map(|(p, f)| (p.low_u32(), f)) @@ -227,7 +223,9 @@ mod test { use std::{str::FromStr, sync::Arc}; use tempdir::TempDir; use test_helpers; - use types::transaction::{Action, Transaction, TypedTransaction, AccessListTx, EIP1559TransactionTx}; + use types::transaction::{ + AccessListTx, Action, EIP1559TransactionTx, Transaction, TypedTransaction, + }; /// Contract code: https://gist.github.com/VladLupashevskyi/84f18eabb1e4afadf572cf92af3e7e7f #[test] @@ -628,10 +626,7 @@ mod test { let filter = TransactionFilter::from_params(spec.params()).unwrap(); let mut tx = TypedTransaction::EIP1559Transaction(EIP1559TransactionTx { - transaction: AccessListTx::new( - Transaction::default(), - vec![], - ), + transaction: AccessListTx::new(Transaction::default(), vec![]), max_priority_fee_per_gas: U256::from(0), }); tx.tx_mut().action = diff --git a/crates/ethcore/types/src/transaction/transaction.rs b/crates/ethcore/types/src/transaction/transaction.rs index bd3f41048..a813f5fa1 100644 --- a/crates/ethcore/types/src/transaction/transaction.rs +++ b/crates/ethcore/types/src/transaction/transaction.rs @@ -651,6 +651,22 @@ impl TypedTransaction { } } + pub fn effective_priority_fee(&self, block_base_fee: Option) -> U256 { + self.effective_gas_price(block_base_fee) + .checked_sub(block_base_fee.unwrap_or_default()) + .unwrap_or_default() + } + + pub fn is_service(&self) -> bool { + match self { + Self::EIP1559Transaction(tx) => { + tx.tx().gas_price == 0.into() && tx.max_priority_fee_per_gas == 0.into() + } + Self::AccessList(tx) => tx.tx().gas_price == 0.into(), + Self::Legacy(tx) => tx.gas_price == 0.into(), + } + } + fn decode_new(tx: &[u8]) -> Result { if tx.is_empty() { // at least one byte needs to be present