diff --git a/crates/transaction-pool/src/pool/state.rs b/crates/transaction-pool/src/pool/state.rs index 055ecd272287..d0282311e158 100644 --- a/crates/transaction-pool/src/pool/state.rs +++ b/crates/transaction-pool/src/pool/state.rs @@ -17,10 +17,14 @@ bitflags::bitflags! { const NOT_TOO_MUCH_GAS = 0b000100; /// Covers the Dynamic fee requirement. /// - /// Set to 1 if `feeCap` of the transaction meets the requirement of the pending block. + /// Set to 1 if `maxBlobFeePerGas` of the transaction meets the requirement of the pending block. const ENOUGH_FEE_CAP_BLOCK = 0b000010; + /// Covers the dynamic blob fee requirement, only relevant for EIP-4844 blob transactions + /// + /// Set to 1 if `maxBlobFeePer` of the transaction meets the requirement of the pending block. + const ENOUGH_BLOB_FEE_CAP_BLOCK = 0b000001; - const PENDING_POOL_BITS = Self::NO_PARKED_ANCESTORS.bits()| Self::NO_NONCE_GAPS.bits() | Self::ENOUGH_BALANCE.bits() | Self::NOT_TOO_MUCH_GAS.bits() | Self::ENOUGH_FEE_CAP_BLOCK.bits(); + const PENDING_POOL_BITS = Self::NO_PARKED_ANCESTORS.bits()| Self::NO_NONCE_GAPS.bits() | Self::ENOUGH_BALANCE.bits() | Self::NOT_TOO_MUCH_GAS.bits() | Self::ENOUGH_FEE_CAP_BLOCK.bits() | Self::ENOUGH_BLOB_FEE_CAP_BLOCK.bits(); const BASE_FEE_POOL_BITS = Self::NO_PARKED_ANCESTORS.bits() | Self::NO_NONCE_GAPS.bits() | Self::ENOUGH_BALANCE.bits() | Self::NOT_TOO_MUCH_GAS.bits(); @@ -140,12 +144,12 @@ mod tests { assert_eq!(SubPool::Pending, state.into()); assert!(state.is_pending()); - let bits = 0b111110; + let bits = 0b111111; let state = TxState::from_bits(bits).unwrap(); assert_eq!(SubPool::Pending, state.into()); assert!(state.is_pending()); - let bits = 0b111110; + let bits = 0b111111; let state = TxState::from_bits(bits).unwrap(); assert_eq!(SubPool::Pending, state.into()); assert!(state.is_pending()); diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 0ba78359772b..8789fbd6c7d8 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1326,7 +1326,15 @@ impl AllTransactions { if transaction.is_eip4844() { transaction = self.ensure_valid_blob_transaction(transaction, on_chain_balance, ancestor)?; + let blob_fee_cap = transaction.transaction.max_fee_per_blob_gas().unwrap_or_default(); + if blob_fee_cap >= self.pending_blob_fee as u128 { + state.insert(TxState::ENOUGH_BLOB_FEE_CAP_BLOCK); + } + } else { + // Non-EIP4844 transaction always satisfy the blob fee cap condition + state.insert(TxState::ENOUGH_BLOB_FEE_CAP_BLOCK); } + let transaction = Arc::new(transaction); // If there's no ancestor tx then this is the next transaction. @@ -1669,6 +1677,44 @@ mod tests { traits::TransactionOrigin, }; + #[test] + fn test_insert_blob() { + let on_chain_balance = U256::MAX; + let on_chain_nonce = 0; + let mut f = MockTransactionFactory::default(); + let mut pool = AllTransactions::default(); + let tx = MockTransaction::eip4844().inc_price().inc_limit(); + let valid_tx = f.validated(tx); + let InsertOk { updates, replaced_tx, move_to, state, .. } = + pool.insert_tx(valid_tx.clone(), on_chain_balance, on_chain_nonce).unwrap(); + assert!(updates.is_empty()); + assert!(replaced_tx.is_none()); + assert!(state.contains(TxState::NO_NONCE_GAPS)); + assert!(state.contains(TxState::ENOUGH_BALANCE)); + assert!(state.contains(TxState::ENOUGH_BLOB_FEE_CAP_BLOCK)); + assert_eq!(move_to, SubPool::Pending); + + let inserted = pool.txs.get(&valid_tx.transaction_id).unwrap(); + assert_eq!(inserted.subpool, SubPool::Pending); + } + + #[test] + fn test_insert_blob_not_enough_blob_fee() { + let on_chain_balance = U256::MAX; + let on_chain_nonce = 0; + let mut f = MockTransactionFactory::default(); + let mut pool = AllTransactions { pending_blob_fee: 10_000_000, ..Default::default() }; + pool.pending_blob_fee = 10_000_000; + let tx = MockTransaction::eip4844().inc_price().inc_limit(); + let valid_tx = f.validated(tx); + let InsertOk { state, .. } = + pool.insert_tx(valid_tx.clone(), on_chain_balance, on_chain_nonce).unwrap(); + assert!(state.contains(TxState::NO_NONCE_GAPS)); + assert!(!state.contains(TxState::ENOUGH_BLOB_FEE_CAP_BLOCK)); + + let _ = pool.txs.get(&valid_tx.transaction_id).unwrap(); + } + #[test] fn test_insert_pending() { let on_chain_balance = U256::MAX;