From 4a1ec6647b4e418856e651b1eaebef25ea1e1c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Tue, 28 Oct 2025 17:44:56 -0300 Subject: [PATCH 1/6] reject privileged txs in p2p messages --- crates/networking/p2p/rlpx/connection/server.rs | 8 ++++++-- crates/networking/p2p/rlpx/eth/transactions.rs | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/networking/p2p/rlpx/connection/server.rs b/crates/networking/p2p/rlpx/connection/server.rs index 03c01c2c84f..a7bb05e0f0d 100644 --- a/crates/networking/p2p/rlpx/connection/server.rs +++ b/crates/networking/p2p/rlpx/connection/server.rs @@ -933,8 +933,12 @@ async fn handle_incoming_message( for tx in &txs.transactions { // Reject blob transactions in L2 mode #[cfg(feature = "l2")] - if is_l2_mode && matches!(tx, Transaction::EIP4844Transaction(_)) { - debug!(peer=%state.node, "Rejecting blob transaction in L2 mode - blob transactions are not supported in L2"); + if is_l2_mode + && (matches!(tx, Transaction::EIP4844Transaction(_)) + || matches!(tx, Transaction::PrivilegedL2Transaction(_))) + { + let tx_type = tx.tx_type(); + debug!(peer=%state.node, "Rejecting transaction in L2 mode - {tx_type} transactions are not broadcasted in L2"); continue; } diff --git a/crates/networking/p2p/rlpx/eth/transactions.rs b/crates/networking/p2p/rlpx/eth/transactions.rs index 748c936849b..126eaa5b725 100644 --- a/crates/networking/p2p/rlpx/eth/transactions.rs +++ b/crates/networking/p2p/rlpx/eth/transactions.rs @@ -295,6 +295,13 @@ impl PooledTransactions { continue; } } else { + if matches!(tx, P2PTransaction::PrivilegedL2Transaction(_)) && is_l2_mode { + debug!( + peer=%node, + "Rejecting privileged L2 transaction in L2 mode - privileged L2 transactions are not broadcasted", + ); + continue; + } let regular_tx = tx .try_into() .map_err(|error| MempoolError::StoreError(StoreError::Custom(error)))?; From 5d49530d993f9aa0bed27f0de73c1c58cdea93de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Tue, 28 Oct 2025 18:04:58 -0300 Subject: [PATCH 2/6] add reject for NewPooledTransactionHashes --- crates/networking/p2p/rlpx/connection/server.rs | 3 +-- crates/networking/p2p/rlpx/eth/transactions.rs | 4 ++-- crates/networking/p2p/tx_broadcaster.rs | 7 +++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/networking/p2p/rlpx/connection/server.rs b/crates/networking/p2p/rlpx/connection/server.rs index a7bb05e0f0d..bc992157685 100644 --- a/crates/networking/p2p/rlpx/connection/server.rs +++ b/crates/networking/p2p/rlpx/connection/server.rs @@ -934,8 +934,7 @@ async fn handle_incoming_message( // Reject blob transactions in L2 mode #[cfg(feature = "l2")] if is_l2_mode - && (matches!(tx, Transaction::EIP4844Transaction(_)) - || matches!(tx, Transaction::PrivilegedL2Transaction(_))) + && (matches!(tx, Transaction::EIP4844Transaction(_)) || tx.is_privileged()) { let tx_type = tx.tx_type(); debug!(peer=%state.node, "Rejecting transaction in L2 mode - {tx_type} transactions are not broadcasted in L2"); diff --git a/crates/networking/p2p/rlpx/eth/transactions.rs b/crates/networking/p2p/rlpx/eth/transactions.rs index 126eaa5b725..51e93414444 100644 --- a/crates/networking/p2p/rlpx/eth/transactions.rs +++ b/crates/networking/p2p/rlpx/eth/transactions.rs @@ -295,10 +295,10 @@ impl PooledTransactions { continue; } } else { - if matches!(tx, P2PTransaction::PrivilegedL2Transaction(_)) && is_l2_mode { + if matches!(tx, P2PTransaction::PrivilegedL2Transaction(_)) { debug!( peer=%node, - "Rejecting privileged L2 transaction in L2 mode - privileged L2 transactions are not broadcasted", + "Rejecting privileged - privileged L2 transactions are not broadcasted", ); continue; } diff --git a/crates/networking/p2p/tx_broadcaster.rs b/crates/networking/p2p/tx_broadcaster.rs index 0c9a219386d..1f2c572374f 100644 --- a/crates/networking/p2p/tx_broadcaster.rs +++ b/crates/networking/p2p/tx_broadcaster.rs @@ -292,6 +292,13 @@ pub async fn send_tx_hashes( let tx_count = tx_chunk.len(); let mut txs_to_send = Vec::with_capacity(tx_count); for tx in tx_chunk { + if tx.is_privileged() { + debug!( + peer=%format!("{:#x}", peer_id), + "Not sending privileged transaction hash to peer", + ); + continue; + } txs_to_send.push((**tx).clone()); } let hashes_message = Message::NewPooledTransactionHashes( From b1560b6ce3971ba7141b11d261697375a7f50839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Tue, 28 Oct 2025 18:07:17 -0300 Subject: [PATCH 3/6] simpify if --- crates/networking/p2p/rlpx/connection/server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/networking/p2p/rlpx/connection/server.rs b/crates/networking/p2p/rlpx/connection/server.rs index bc992157685..805e3237e07 100644 --- a/crates/networking/p2p/rlpx/connection/server.rs +++ b/crates/networking/p2p/rlpx/connection/server.rs @@ -933,8 +933,8 @@ async fn handle_incoming_message( for tx in &txs.transactions { // Reject blob transactions in L2 mode #[cfg(feature = "l2")] - if is_l2_mode - && (matches!(tx, Transaction::EIP4844Transaction(_)) || tx.is_privileged()) + if (is_l2_mode && matches!(tx, Transaction::EIP4844Transaction(_))) + || tx.is_privileged() { let tx_type = tx.tx_type(); debug!(peer=%state.node, "Rejecting transaction in L2 mode - {tx_type} transactions are not broadcasted in L2"); From f27c4448a7eecf9d2de2124dc08597c69265db0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Tue, 28 Oct 2025 18:36:01 -0300 Subject: [PATCH 4/6] filter maps before chunking --- crates/networking/p2p/rlpx/connection/server.rs | 1 + crates/networking/p2p/tx_broadcaster.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/networking/p2p/rlpx/connection/server.rs b/crates/networking/p2p/rlpx/connection/server.rs index 805e3237e07..6576a922b3f 100644 --- a/crates/networking/p2p/rlpx/connection/server.rs +++ b/crates/networking/p2p/rlpx/connection/server.rs @@ -589,6 +589,7 @@ async fn send_all_pooled_tx_hashes( .get_all_txs_by_sender()? .into_values() .flatten() + .filter(|tx| !tx.is_privileged()) .collect(); if !txs.is_empty() { state diff --git a/crates/networking/p2p/tx_broadcaster.rs b/crates/networking/p2p/tx_broadcaster.rs index 1f2c572374f..f174c36be8a 100644 --- a/crates/networking/p2p/tx_broadcaster.rs +++ b/crates/networking/p2p/tx_broadcaster.rs @@ -193,7 +193,9 @@ impl TxBroadcaster { let full_txs = txs_to_broadcast .iter() .map(|tx| tx.transaction().clone()) - .filter(|tx| !matches!(tx, Transaction::EIP4844Transaction { .. })) + .filter(|tx| { + !matches!(tx, Transaction::EIP4844Transaction { .. }) && !tx.is_privileged() + }) .collect::>(); let blob_txs = txs_to_broadcast @@ -262,6 +264,7 @@ impl TxBroadcaster { .known_txs .get(&hash) .is_some_and(|record| record.peers.is_set(peer_idx)) + && !tx.is_privileged() }) .cloned() .collect::>(); @@ -292,13 +295,6 @@ pub async fn send_tx_hashes( let tx_count = tx_chunk.len(); let mut txs_to_send = Vec::with_capacity(tx_count); for tx in tx_chunk { - if tx.is_privileged() { - debug!( - peer=%format!("{:#x}", peer_id), - "Not sending privileged transaction hash to peer", - ); - continue; - } txs_to_send.push((**tx).clone()); } let hashes_message = Message::NewPooledTransactionHashes( From 02308eb9feb9d946f7f1f796f8925ec8d79cfd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Tue, 28 Oct 2025 18:39:41 -0300 Subject: [PATCH 5/6] remove priv tx from p2p enum --- crates/common/types/transaction.rs | 12 ------------ crates/networking/p2p/rlpx/eth/transactions.rs | 7 ------- 2 files changed, 19 deletions(-) diff --git a/crates/common/types/transaction.rs b/crates/common/types/transaction.rs index ffa2400e426..935392c8255 100644 --- a/crates/common/types/transaction.rs +++ b/crates/common/types/transaction.rs @@ -49,7 +49,6 @@ pub enum P2PTransaction { EIP1559Transaction(EIP1559Transaction), EIP4844TransactionWithBlobs(WrappedEIP4844Transaction), EIP7702Transaction(EIP7702Transaction), - PrivilegedL2Transaction(PrivilegedL2Transaction), } impl TryInto for P2PTransaction { @@ -61,9 +60,6 @@ impl TryInto for P2PTransaction { P2PTransaction::EIP2930Transaction(itx) => Ok(Transaction::EIP2930Transaction(itx)), P2PTransaction::EIP1559Transaction(itx) => Ok(Transaction::EIP1559Transaction(itx)), P2PTransaction::EIP7702Transaction(itx) => Ok(Transaction::EIP7702Transaction(itx)), - P2PTransaction::PrivilegedL2Transaction(itx) => { - Ok(Transaction::PrivilegedL2Transaction(itx)) - } _ => Err("Can't convert blob p2p transaction into regular transaction. Blob bundle would be lost.".to_string()), } } @@ -102,9 +98,6 @@ impl RLPDecode for P2PTransaction { // EIP7702 0x4 => EIP7702Transaction::decode_unfinished(tx_encoding) .map(|(tx, rem)| (P2PTransaction::EIP7702Transaction(tx), rem)), - // PrivilegedL2 - 0x7e => PrivilegedL2Transaction::decode_unfinished(tx_encoding) - .map(|(tx, rem)| (P2PTransaction::PrivilegedL2Transaction(tx), rem)), ty => Err(RLPDecodeError::Custom(format!( "Invalid transaction type: {ty}" ))), @@ -1439,7 +1432,6 @@ mod canonic_encoding { P2PTransaction::EIP1559Transaction(_) => TxType::EIP1559, P2PTransaction::EIP4844TransactionWithBlobs(_) => TxType::EIP4844, P2PTransaction::EIP7702Transaction(_) => TxType::EIP7702, - P2PTransaction::PrivilegedL2Transaction(_) => TxType::Privileged, } } @@ -1455,7 +1447,6 @@ mod canonic_encoding { P2PTransaction::EIP1559Transaction(t) => t.encode(buf), P2PTransaction::EIP4844TransactionWithBlobs(t) => t.encode(buf), P2PTransaction::EIP7702Transaction(t) => t.encode(buf), - P2PTransaction::PrivilegedL2Transaction(t) => t.encode(buf), }; } @@ -1482,9 +1473,6 @@ mod canonic_encoding { P2PTransaction::EIP7702Transaction(t) => { Transaction::EIP7702Transaction(t.clone()).compute_hash() } - P2PTransaction::PrivilegedL2Transaction(t) => { - Transaction::PrivilegedL2Transaction(t.clone()).compute_hash() - } } } } diff --git a/crates/networking/p2p/rlpx/eth/transactions.rs b/crates/networking/p2p/rlpx/eth/transactions.rs index 51e93414444..748c936849b 100644 --- a/crates/networking/p2p/rlpx/eth/transactions.rs +++ b/crates/networking/p2p/rlpx/eth/transactions.rs @@ -295,13 +295,6 @@ impl PooledTransactions { continue; } } else { - if matches!(tx, P2PTransaction::PrivilegedL2Transaction(_)) { - debug!( - peer=%node, - "Rejecting privileged - privileged L2 transactions are not broadcasted", - ); - continue; - } let regular_tx = tx .try_into() .map_err(|error| MempoolError::StoreError(StoreError::Custom(error)))?; From 63675e28d1aa971c2d533b9fd70e2a4039714679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Wed, 29 Oct 2025 09:36:56 -0300 Subject: [PATCH 6/6] add comment to say we exclude priv tx from p2p txs --- crates/common/types/transaction.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/common/types/transaction.rs b/crates/common/types/transaction.rs index 935392c8255..c3bc9243944 100644 --- a/crates/common/types/transaction.rs +++ b/crates/common/types/transaction.rs @@ -42,6 +42,7 @@ pub enum Transaction { /// The same as a Transaction enum, only that blob transactions are in wrapped format, including /// the blobs bundle. +/// PrivilegedL2Transaction is not included as it is not expected to be sent over P2P. #[derive(Clone, Debug, PartialEq, Eq)] pub enum P2PTransaction { LegacyTransaction(LegacyTransaction),