feat: implement Compact for OpTxType (#12537)

This commit is contained in:
Krishang Shah
2024-11-15 21:35:19 +05:30
committed by GitHub
parent 5f66fa448e
commit ac5976ff51
5 changed files with 112 additions and 6 deletions

3
Cargo.lock generated
View File

@ -8381,7 +8381,10 @@ dependencies = [
"bytes",
"derive_more 1.0.0",
"op-alloy-consensus",
"reth-codecs",
"reth-primitives",
"reth-primitives-traits",
"rstest",
]
[[package]]

View File

@ -20,3 +20,13 @@ alloy-rlp.workspace = true
derive_more.workspace = true
bytes.workspace = true
reth-primitives-traits.workspace = true
reth-codecs = { workspace = true, optional = true }
reth-primitives = { workspace = true, features = ["reth-codec"], optional = true }
[features]
default = ["reth-codec"]
reth-codec = ["dep:reth-codecs", "dep:reth-primitives"]
[dev-dependencies]
reth-codecs = { workspace = true, features = ["test-utils"] }
rstest.workspace = true

View File

@ -15,6 +15,16 @@ use derive_more::{
use op_alloy_consensus::OpTxType as AlloyOpTxType;
use reth_primitives_traits::TxType;
#[cfg(feature = "reth-codec")]
use alloy_consensus::constants::EIP7702_TX_TYPE_ID;
#[cfg(feature = "reth-codec")]
use op_alloy_consensus::DEPOSIT_TX_TYPE_ID;
#[cfg(feature = "reth-codec")]
use reth_primitives::transaction::{
COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930,
COMPACT_IDENTIFIER_LEGACY,
};
/// Wrapper type for `AlloyOpTxType` to implement `TxType` trait.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Display, Ord, Hash, From, Into)]
#[into(u8)]
@ -123,10 +133,55 @@ impl Decodable for OpTxType {
}
}
#[cfg(any(test, feature = "reth-codec"))]
impl reth_codecs::Compact for OpTxType {
fn to_compact<B>(&self, buf: &mut B) -> usize
where
B: bytes::BufMut + AsMut<[u8]>,
{
match self.0 {
AlloyOpTxType::Legacy => COMPACT_IDENTIFIER_LEGACY,
AlloyOpTxType::Eip2930 => COMPACT_IDENTIFIER_EIP2930,
AlloyOpTxType::Eip1559 => COMPACT_IDENTIFIER_EIP1559,
AlloyOpTxType::Eip7702 => {
buf.put_u8(EIP7702_TX_TYPE_ID);
COMPACT_EXTENDED_IDENTIFIER_FLAG
}
AlloyOpTxType::Deposit => {
buf.put_u8(DEPOSIT_TX_TYPE_ID);
COMPACT_EXTENDED_IDENTIFIER_FLAG
}
}
}
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
use bytes::Buf;
(
match identifier {
COMPACT_IDENTIFIER_LEGACY => Self(AlloyOpTxType::Legacy),
COMPACT_IDENTIFIER_EIP2930 => Self(AlloyOpTxType::Eip2930),
COMPACT_IDENTIFIER_EIP1559 => Self(AlloyOpTxType::Eip1559),
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
let extended_identifier = buf.get_u8();
match extended_identifier {
EIP7702_TX_TYPE_ID => Self(AlloyOpTxType::Eip7702),
DEPOSIT_TX_TYPE_ID => Self(AlloyOpTxType::Deposit),
_ => panic!("Unsupported OpTxType identifier: {extended_identifier}"),
}
}
_ => panic!("Unknown identifier for OpTxType: {identifier}"),
},
buf,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use bytes::BytesMut;
use reth_codecs::Compact;
use rstest::rstest;
#[test]
fn test_from_alloy_op_tx_type() {
@ -215,4 +270,42 @@ mod tests {
let result = OpTxType::decode(&mut buf);
assert!(result.is_err());
}
#[rstest]
#[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])]
#[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])]
fn test_txtype_to_compact(
#[case] tx_type: OpTxType,
#[case] expected_identifier: usize,
#[case] expected_buf: Vec<u8>,
) {
let mut buf = vec![];
let identifier = tx_type.to_compact(&mut buf);
assert_eq!(
identifier, expected_identifier,
"Unexpected identifier for OpTxType {tx_type:?}",
);
assert_eq!(buf, expected_buf, "Unexpected buffer for OpTxType {tx_type:?}",);
}
#[rstest]
#[case(OpTxType(AlloyOpTxType::Legacy), COMPACT_IDENTIFIER_LEGACY, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip2930), COMPACT_IDENTIFIER_EIP2930, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip1559), COMPACT_IDENTIFIER_EIP1559, vec![])]
#[case(OpTxType(AlloyOpTxType::Eip7702), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])]
#[case(OpTxType(AlloyOpTxType::Deposit), COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![DEPOSIT_TX_TYPE_ID])]
fn test_txtype_from_compact(
#[case] expected_type: OpTxType,
#[case] identifier: usize,
#[case] buf: Vec<u8>,
) {
let (actual_type, remaining_buf) = OpTxType::from_compact(&buf, identifier);
assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}");
assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}");
}
}

View File

@ -62,7 +62,7 @@ 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::{
pub use tx_type::{
COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930,
COMPACT_IDENTIFIER_LEGACY,
};

View File

@ -9,21 +9,21 @@ use serde::{Deserialize, Serialize};
/// Identifier parameter for legacy transaction
#[cfg(any(test, feature = "reth-codec"))]
pub(crate) const COMPACT_IDENTIFIER_LEGACY: usize = 0;
pub 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;
pub 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;
pub 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 [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type is
/// read from the buffer as a single byte.
#[cfg(any(test, feature = "reth-codec"))]
pub(crate) const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3;
pub const COMPACT_EXTENDED_IDENTIFIER_FLAG: usize = 3;
/// Identifier for [`TxDeposit`](op_alloy_consensus::TxDeposit) transaction.
#[cfg(feature = "optimism")]