From 863c0b8fda9dd1c320e7e38ccf3534b43e15e25f Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 22 Nov 2024 09:48:43 -0500 Subject: [PATCH] chore(consensus): EIP-2718 Encoding Trait Impls (#300) ### Description Moves custom EIP-2718 encoding and decoding methods on `TxDeposit` into trait impls for the alloy eip traits. --- crates/consensus/src/hardforks/ecotone.rs | 3 +- crates/consensus/src/hardforks/fjord.rs | 3 +- crates/consensus/src/transaction/deposit.rs | 49 +++++++++++++++----- crates/consensus/src/transaction/envelope.rs | 2 +- crates/protocol/src/deposits.rs | 3 +- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/crates/consensus/src/hardforks/ecotone.rs b/crates/consensus/src/hardforks/ecotone.rs index fffb7e7b..144b2f59 100644 --- a/crates/consensus/src/hardforks/ecotone.rs +++ b/crates/consensus/src/hardforks/ecotone.rs @@ -3,6 +3,7 @@ //! [Transaction]: alloy_consensus::Transaction use alloc::{string::String, vec::Vec}; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{address, hex, Address, Bytes, TxKind, B256, U256}; use crate::{Hardfork, TxDeposit, UpgradeDepositSource}; @@ -160,7 +161,7 @@ impl Hardfork for Ecotone { fn txs(&self) -> impl Iterator + '_ { Self::deposits().map(|tx| { let mut encoded = Vec::new(); - tx.eip2718_encode(&mut encoded); + tx.encode_2718(&mut encoded); Bytes::from(encoded) }) } diff --git a/crates/consensus/src/hardforks/fjord.rs b/crates/consensus/src/hardforks/fjord.rs index 8238f0cf..1d4cf831 100644 --- a/crates/consensus/src/hardforks/fjord.rs +++ b/crates/consensus/src/hardforks/fjord.rs @@ -3,6 +3,7 @@ //! [Transaction]: alloy_consensus::Transaction use alloc::{string::String, vec::Vec}; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{address, hex, Address, Bytes, TxKind, B256, U256}; use crate::{Hardfork, TxDeposit, UpgradeDepositSource}; @@ -98,7 +99,7 @@ impl Hardfork for Fjord { fn txs(&self) -> impl Iterator + '_ { Self::deposits().map(|tx| { let mut encoded = Vec::new(); - tx.eip2718_encode(&mut encoded); + tx.encode_2718(&mut encoded); Bytes::from(encoded) }) } diff --git a/crates/consensus/src/transaction/deposit.rs b/crates/consensus/src/transaction/deposit.rs index a711f0f2..c3f6c06e 100644 --- a/crates/consensus/src/transaction/deposit.rs +++ b/crates/consensus/src/transaction/deposit.rs @@ -4,7 +4,10 @@ use super::OpTxType; use crate::DepositTransaction; use alloc::vec::Vec; use alloy_consensus::{Sealable, Transaction}; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, + eip2930::AccessList, +}; use alloy_primitives::{ keccak256, Address, Bytes, ChainId, PrimitiveSignature as Signature, TxHash, TxKind, B256, U256, }; @@ -192,13 +195,6 @@ impl TxDeposit { self.rlp_encoded_length() + 1 } - /// EIP-2718 encode the transaction with the given signature and the default - /// type flag. - pub fn eip2718_encode(&self, out: &mut dyn BufMut) { - out.put_u8(self.tx_type() as u8); - self.rlp_encode(out); - } - fn network_header(&self) -> Header { Header { list: false, payload_length: self.eip2718_encoded_length() } } @@ -212,13 +208,13 @@ impl TxDeposit { /// Network encode the transaction with the given signature. pub fn network_encode(&self, out: &mut dyn BufMut) { self.network_header().encode(out); - self.eip2718_encode(out); + self.encode_2718(out); } /// Calculate the transaction hash. pub fn tx_hash(&self) -> TxHash { let mut buf = Vec::with_capacity(self.eip2718_encoded_length()); - self.eip2718_encode(&mut buf); + self.encode_2718(&mut buf); keccak256(&buf) } @@ -299,6 +295,37 @@ impl Transaction for TxDeposit { } } +impl Encodable2718 for TxDeposit { + fn type_flag(&self) -> Option { + Some(OpTxType::Deposit as u8) + } + + fn encode_2718_len(&self) -> usize { + self.eip2718_encoded_length() + } + + fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { + out.put_u8(self.tx_type() as u8); + self.rlp_encode(out); + } +} + +impl Decodable2718 for TxDeposit { + fn typed_decode(ty: u8, data: &mut &[u8]) -> Eip2718Result { + let ty: OpTxType = ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))?; + if ty != OpTxType::Deposit as u8 { + return Err(Eip2718Error::UnexpectedType(ty as u8)); + } + let tx = Self::decode(data)?; + Ok(tx) + } + + fn fallback_decode(data: &mut &[u8]) -> Eip2718Result { + let tx = Self::decode(data)?; + Ok(tx) + } +} + impl Encodable for TxDeposit { fn encode(&self, out: &mut dyn BufMut) { Header { list: true, payload_length: self.rlp_encoded_fields_length() }.encode(out); @@ -495,7 +522,7 @@ mod tests { tx_deposit.network_encode(&mut buffer_with_header); let mut buffer_without_header = BytesMut::new(); - tx_deposit.eip2718_encode(&mut buffer_without_header); + tx_deposit.encode_2718(&mut buffer_without_header); assert!(buffer_with_header.len() > buffer_without_header.len()); } diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 67632804..fd8944d2 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -415,7 +415,7 @@ impl Encodable2718 for OpTxEnvelope { tx.eip2718_encode(out); } Self::Deposit(tx) => { - tx.eip2718_encode(out); + tx.encode_2718(out); } } } diff --git a/crates/protocol/src/deposits.rs b/crates/protocol/src/deposits.rs index 126dfd45..49a2c3d7 100644 --- a/crates/protocol/src/deposits.rs +++ b/crates/protocol/src/deposits.rs @@ -1,6 +1,7 @@ //! Contains deposit transaction types and helper methods. use alloc::{string::String, vec::Vec}; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{b256, keccak256, Address, Bytes, Log, TxKind, B256, U256, U64}; use core::fmt::Display; use op_alloy_consensus::TxDeposit; @@ -334,7 +335,7 @@ pub fn decode_deposit(block_hash: B256, index: usize, log: &Log) -> Result