Skip to content

Commit

Permalink
chore(reth-primitives): use COMPACT_EXTENDED_IDENTIFIER_FLAG (#10926)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkysg authored Sep 18, 2024
1 parent 91eb50c commit e840238
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 44 deletions.
27 changes: 16 additions & 11 deletions crates/primitives/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ mod variant;
pub use op_alloy_consensus::TxDeposit;
#[cfg(feature = "optimism")]
pub use tx_type::DEPOSIT_TX_TYPE_ID;
#[cfg(any(test, feature = "reth-codec"))]
use tx_type::{
COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930,
COMPACT_IDENTIFIER_LEGACY,
};

#[cfg(test)]
use reth_codecs::Compact;
Expand Down Expand Up @@ -724,45 +729,45 @@ impl reth_codecs::Compact for Transaction {
}

// For backwards compatibility purposes, only 2 bits of the type are encoded in the identifier
// parameter. In the case of a 3, the full transaction type is read from the buffer as a
// single byte.
// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type
// is read from the buffer as a single byte.
//
// # Panics
//
// A panic will be triggered if an identifier larger than 3 is passed from the database. For
// optimism a identifier with value 126 is allowed.
// optimism a identifier with value [`DEPOSIT_TX_TYPE_ID`] is allowed.
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
match identifier {
0 => {
COMPACT_IDENTIFIER_LEGACY => {
let (tx, buf) = TxLegacy::from_compact(buf, buf.len());
(Self::Legacy(tx), buf)
}
1 => {
COMPACT_IDENTIFIER_EIP2930 => {
let (tx, buf) = TxEip2930::from_compact(buf, buf.len());
(Self::Eip2930(tx), buf)
}
2 => {
COMPACT_IDENTIFIER_EIP1559 => {
let (tx, buf) = TxEip1559::from_compact(buf, buf.len());
(Self::Eip1559(tx), buf)
}
3 => {
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
// An identifier of 3 indicates that the transaction type did not fit into
// the backwards compatible 2 bit identifier, their transaction types are
// larger than 2 bits (eg. 4844 and Deposit Transactions). In this case,
// we need to read the concrete transaction type from the buffer by
// reading the full 8 bits (single byte) and match on this transaction type.
let identifier = buf.get_u8() as usize;
let identifier = buf.get_u8();
match identifier {
3 => {
EIP4844_TX_TYPE_ID => {
let (tx, buf) = TxEip4844::from_compact(buf, buf.len());
(Self::Eip4844(tx), buf)
}
4 => {
EIP7702_TX_TYPE_ID => {
let (tx, buf) = TxEip7702::from_compact(buf, buf.len());
(Self::Eip7702(tx), buf)
}
#[cfg(feature = "optimism")]
126 => {
DEPOSIT_TX_TYPE_ID => {
let (tx, buf) = TxDeposit::from_compact(buf, buf.len());
(Self::Deposit(tx), buf)
}
Expand Down
78 changes: 45 additions & 33 deletions crates/primitives/src/transaction/tx_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@ use serde::{Deserialize, Serialize};
#[cfg(test)]
use reth_codecs::Compact;

/// Identifier parameter for legacy transaction
#[cfg(any(test, feature = "reth-codec"))]
pub(crate) const COMPACT_IDENTIFIER_LEGACY: usize = 0;

/// Identifier parameter for EIP-2930 transaction
#[cfg(any(test, feature = "reth-codec"))]
pub(crate) const COMPACT_IDENTIFIER_EIP2930: usize = 1;

/// Identifier parameter for EIP-1559 transaction
#[cfg(any(test, feature = "reth-codec"))]
pub(crate) const COMPACT_IDENTIFIER_EIP1559: usize = 2;

/// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier
/// parameter. In the case of a 3, the full transaction type is read from the buffer as a
/// single byte.
/// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type is
/// read from the buffer as a single byte.
#[cfg(any(test, feature = "reth-codec"))]
const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3;
pub(crate) const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3;

/// Identifier for legacy transaction, however [`TxLegacy`](crate::TxLegacy) this is technically not
/// typed.
Expand Down Expand Up @@ -144,35 +156,35 @@ impl reth_codecs::Compact for TxType {
B: bytes::BufMut + AsMut<[u8]>,
{
match self {
Self::Legacy => 0,
Self::Eip2930 => 1,
Self::Eip1559 => 2,
Self::Legacy => COMPACT_IDENTIFIER_LEGACY,
Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930,
Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559,
Self::Eip4844 => {
buf.put_u8(*self as u8);
buf.put_u8(EIP4844_TX_TYPE_ID);
COMPACT_EXTENDED_IDENTIFIER_FLAG
}
Self::Eip7702 => {
buf.put_u8(*self as u8);
buf.put_u8(EIP7702_TX_TYPE_ID);
COMPACT_EXTENDED_IDENTIFIER_FLAG
}
#[cfg(feature = "optimism")]
Self::Deposit => {
buf.put_u8(*self as u8);
buf.put_u8(DEPOSIT_TX_TYPE_ID);
COMPACT_EXTENDED_IDENTIFIER_FLAG
}
}
}

// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier
// parameter. In the case of a 3, the full transaction type is read from the buffer as a
// single byte.
// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type
// is read from the buffer as a single byte.
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
use bytes::Buf;
(
match identifier {
0 => Self::Legacy,
1 => Self::Eip2930,
2 => Self::Eip1559,
COMPACT_IDENTIFIER_LEGACY => Self::Legacy,
COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930,
COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559,
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
let extended_identifier = buf.get_u8();
match extended_identifier {
Expand Down Expand Up @@ -243,34 +255,34 @@ mod tests {
#[test]
fn test_u64_to_tx_type() {
// Test for Legacy transaction
assert_eq!(TxType::try_from(U64::from(0)).unwrap(), TxType::Legacy);
assert_eq!(TxType::try_from(U64::from(LEGACY_TX_TYPE_ID)).unwrap(), TxType::Legacy);

// Test for EIP2930 transaction
assert_eq!(TxType::try_from(U64::from(1)).unwrap(), TxType::Eip2930);
assert_eq!(TxType::try_from(U64::from(EIP2930_TX_TYPE_ID)).unwrap(), TxType::Eip2930);

// Test for EIP1559 transaction
assert_eq!(TxType::try_from(U64::from(2)).unwrap(), TxType::Eip1559);
assert_eq!(TxType::try_from(U64::from(EIP1559_TX_TYPE_ID)).unwrap(), TxType::Eip1559);

// Test for EIP4844 transaction
assert_eq!(TxType::try_from(U64::from(3)).unwrap(), TxType::Eip4844);
assert_eq!(TxType::try_from(U64::from(EIP4844_TX_TYPE_ID)).unwrap(), TxType::Eip4844);

// Test for EIP7702 transaction
assert_eq!(TxType::try_from(U64::from(4)).unwrap(), TxType::Eip7702);
assert_eq!(TxType::try_from(U64::from(EIP7702_TX_TYPE_ID)).unwrap(), TxType::Eip7702);

// Test for Deposit transaction
#[cfg(feature = "optimism")]
assert_eq!(TxType::try_from(U64::from(126)).unwrap(), TxType::Deposit);
assert_eq!(TxType::try_from(U64::from(DEPOSIT_TX_TYPE_ID)).unwrap(), TxType::Deposit);

// For transactions with unsupported values
assert!(TxType::try_from(U64::from(5)).is_err());
assert!(TxType::try_from(U64::from(EIP7702_TX_TYPE_ID + 1)).is_err());
}

#[test]
fn test_txtype_to_compat() {
let cases = vec![
(TxType::Legacy, 0, vec![]),
(TxType::Eip2930, 1, vec![]),
(TxType::Eip1559, 2, vec![]),
(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![]),
(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![]),
(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![]),
(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID]),
(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID]),
#[cfg(feature = "optimism")]
Expand All @@ -291,9 +303,9 @@ mod tests {
#[test]
fn test_txtype_from_compact() {
let cases = vec![
(TxType::Legacy, 0, vec![]),
(TxType::Eip2930, 1, vec![]),
(TxType::Eip1559, 2, vec![]),
(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![]),
(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![]),
(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![]),
(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID]),
(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID]),
#[cfg(feature = "optimism")]
Expand All @@ -317,29 +329,29 @@ mod tests {
assert_eq!(tx_type, TxType::Legacy);

// Test for EIP2930 transaction
let tx_type = TxType::decode(&mut &[1u8][..]).unwrap();
let tx_type = TxType::decode(&mut &[EIP2930_TX_TYPE_ID][..]).unwrap();
assert_eq!(tx_type, TxType::Eip2930);

// Test for EIP1559 transaction
let tx_type = TxType::decode(&mut &[2u8][..]).unwrap();
let tx_type = TxType::decode(&mut &[EIP1559_TX_TYPE_ID][..]).unwrap();
assert_eq!(tx_type, TxType::Eip1559);

// Test for EIP4844 transaction
let tx_type = TxType::decode(&mut &[3u8][..]).unwrap();
let tx_type = TxType::decode(&mut &[EIP4844_TX_TYPE_ID][..]).unwrap();
assert_eq!(tx_type, TxType::Eip4844);

// Test for EIP7702 transaction
let tx_type = TxType::decode(&mut &[4u8][..]).unwrap();
let tx_type = TxType::decode(&mut &[EIP7702_TX_TYPE_ID][..]).unwrap();
assert_eq!(tx_type, TxType::Eip7702);

// Test random byte not in range
let buf = [rand::thread_rng().gen_range(5..=u8::MAX)];
let buf = [rand::thread_rng().gen_range(EIP7702_TX_TYPE_ID + 1..=u8::MAX)];
assert!(TxType::decode(&mut &buf[..]).is_err());

// Test for Deposit transaction
#[cfg(feature = "optimism")]
{
let buf = [126u8];
let buf = [DEPOSIT_TX_TYPE_ID];
let tx_type = TxType::decode(&mut &buf[..]).unwrap();
assert_eq!(tx_type, TxType::Deposit);
}
Expand Down

0 comments on commit e840238

Please sign in to comment.