Skip to content

Commit

Permalink
fix(derive): refactor tx enveloped
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell authored and clabby committed Apr 3, 2024
1 parent 1bb9bbc commit 616c666
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 93 deletions.
48 changes: 47 additions & 1 deletion crates/derive/src/types/batch/span_batch/tx_data/eip1559.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! This module contains the eip1559 transaction data type for a span batch.
use crate::types::eip2930::AccessList;
use alloy_primitives::U256;
use crate::types::{
network::Signed, SpanBatchError, SpanDecodingError, Transaction, TxEip1559, TxEnvelope, TxKind,
};
use alloy_primitives::{Address, Signature, U256};
use alloy_rlp::{Bytes, Decodable, Encodable, Header};

/// The transaction data for an EIP-1559 transaction within a span batch.
Expand All @@ -19,6 +22,49 @@ pub struct SpanBatchEip1559TransactionData {
pub access_list: AccessList,
}

impl SpanBatchEip1559TransactionData {
/// Converts [SpanBatchEip1559TransactionData] into a [TxEnvelope].
pub fn to_enveloped_tx(
&self,
nonce: u64,
gas: u64,
to: Option<Address>,
chain_id: u64,
signature: Signature,
) -> Result<TxEnvelope, SpanBatchError> {
let eip1559_tx = TxEip1559 {
chain_id,
nonce,
max_fee_per_gas: u128::from_be_bytes(
self.max_fee_per_gas.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
max_priority_fee_per_gas: u128::from_be_bytes(
self.max_priority_fee_per_gas.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: self.value,
input: self.data.clone().into(),
access_list: self.access_list.clone(),
};
let signature_hash = eip1559_tx.signature_hash();
let signed_eip1559_tx = Signed::new_unchecked(eip1559_tx, signature, signature_hash);
Ok(TxEnvelope::Eip1559(signed_eip1559_tx))
}
}

impl Encodable for SpanBatchEip1559TransactionData {
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
let payload_length = self.value.length()
Expand Down
42 changes: 41 additions & 1 deletion crates/derive/src/types/batch/span_batch/tx_data/eip2930.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! This module contains the eip2930 transaction data type for a span batch.
use crate::types::eip2930::AccessList;
use alloy_primitives::U256;
use crate::types::{
network::Signed, SpanBatchError, SpanDecodingError, Transaction, TxEip2930, TxEnvelope, TxKind,
};
use alloy_primitives::{Address, Signature, U256};
use alloy_rlp::{Bytes, Decodable, Encodable, Header};

/// The transaction data for an EIP-2930 transaction within a span batch.
Expand All @@ -17,6 +20,43 @@ pub struct SpanBatchEip2930TransactionData {
pub access_list: AccessList,
}

impl SpanBatchEip2930TransactionData {
/// Converts [SpanBatchEip1559TransactionData] into a [TxEnvelope].
pub fn to_enveloped_tx(
&self,
nonce: u64,
gas: u64,
to: Option<Address>,
chain_id: u64,
signature: Signature,
) -> Result<TxEnvelope, SpanBatchError> {
let access_list_tx = TxEip2930 {
chain_id,
nonce,
gas_price: u128::from_be_bytes(
self.gas_price.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: self.value,
input: self.data.clone().into(),
access_list: self.access_list.clone(),
};
let signature_hash = access_list_tx.signature_hash();
let signed_access_list_tx =
Signed::new_unchecked(access_list_tx, signature, signature_hash);
Ok(TxEnvelope::Eip2930(signed_access_list_tx))
}
}

impl Encodable for SpanBatchEip2930TransactionData {
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
let payload_length = self.value.length()
Expand Down
77 changes: 73 additions & 4 deletions crates/derive/src/types/batch/span_batch/tx_data/legacy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! This module contains the legacy transaction data type for a span batch.
use alloy_primitives::U256;
use crate::types::{
network::Signed, SpanBatchError, SpanDecodingError, Transaction, TxEnvelope, TxKind, TxLegacy,
};
use alloy_primitives::{Address, Signature, U256};
use alloy_rlp::{Bytes, Decodable, Encodable, Header};

/// The transaction data for a legacy transaction within a span batch.
Expand All @@ -14,6 +17,41 @@ pub struct SpanBatchLegacyTransactionData {
pub data: Bytes,
}

impl SpanBatchLegacyTransactionData {
/// Converts [SpanBatchLegacyTransactionData] into a [TxEnvelope].
pub fn to_enveloped_tx(
&self,
nonce: u64,
gas: u64,
to: Option<Address>,
chain_id: u64,
signature: Signature,
) -> Result<TxEnvelope, SpanBatchError> {
let legacy_tx = TxLegacy {
chain_id: Some(chain_id),
nonce,
gas_price: u128::from_be_bytes(
self.gas_price.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: self.value,
input: self.data.clone().into(),
};
let signature_hash = legacy_tx.signature_hash();
let signed_legacy_tx = Signed::new_unchecked(legacy_tx, signature, signature_hash);
Ok(TxEnvelope::Legacy(signed_legacy_tx))
}
}

impl Encodable for SpanBatchLegacyTransactionData {
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
let payload_length = self.value.length() + self.gas_price.length() + self.data.length();
Expand Down Expand Up @@ -57,11 +95,42 @@ impl Decodable for SpanBatchLegacyTransactionData {

#[cfg(test)]
mod test {
use super::SpanBatchLegacyTransactionData;
use super::*;
use crate::types::SpanBatchTransactionData;
use alloc::vec::Vec;
use alloy_primitives::U256;
use alloy_rlp::{Bytes, Decodable, Encodable};
// use alloy_primitives::B256;

// #[test]
// fn to_enveloped_tx() {
// let legacy_tx = SpanBatchLegacyTransactionData {
// value: U256::from(0xFF),
// gas_price: U256::from(0xEE),
// data: Bytes::from(alloc::vec![0x01, 0x02, 0x03]),
// };
// let nonce = 0x1234;
// let gas = 0x5678;
// let to = None;
// let chain_id = 0x9ABC;
// let signature = &[0x01; 65];
// let signature = Signature::decode(&mut &signature[..]).unwrap();
// let enveloped_tx = legacy_tx
// .to_enveloped_tx(nonce, gas, to, chain_id, signature)
// .unwrap();
// let expected = TxEnvelope::Legacy(crate::types::network::Signed::new_unchecked(
// crate::types::TxLegacy {
// chain_id: Some(chain_id),
// nonce,
// gas_price: 0xEE,
// gas_limit: gas,
// to: crate::types::TxKind::Create,
// value: U256::from(0xFF),
// input: Bytes::from(alloc::vec![0x01, 0x02, 0x03]).into(),
// },
// signature,
// B256::from([0x01; 32]),
// ));
// assert_eq!(enveloped_tx, expected);
// }

#[test]
fn encode_legacy_tx_data_roundtrip() {
Expand Down
91 changes: 4 additions & 87 deletions crates/derive/src/types/batch/span_batch/tx_data/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ use super::{
SpanBatchEip1559TransactionData, SpanBatchEip2930TransactionData,
SpanBatchLegacyTransactionData,
};
use crate::types::{
network::Signed, SpanBatchError, SpanDecodingError, Transaction, TxEip1559, TxEip2930,
TxEnvelope, TxKind, TxLegacy,
};
use crate::types::{SpanBatchError, SpanDecodingError, Transaction, TxEnvelope};
use alloy_primitives::{Address, Signature, U256};
use alloy_rlp::{Bytes, Decodable, Encodable};

Expand Down Expand Up @@ -126,89 +123,9 @@ impl SpanBatchTransactionData {
signature: Signature,
) -> Result<TxEnvelope, SpanBatchError> {
match self {
Self::Legacy(data) => {
let legacy_tx = TxLegacy {
chain_id: Some(chain_id),
nonce,
gas_price: u128::from_be_bytes(
data.gas_price.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: data.value,
input: data.data.clone().into(),
};
let signature_hash = legacy_tx.signature_hash();
let signed_legacy_tx = Signed::new_unchecked(legacy_tx, signature, signature_hash);
Ok(TxEnvelope::Legacy(signed_legacy_tx))
}
Self::Eip2930(data) => {
let access_list_tx = TxEip2930 {
chain_id,
nonce,
gas_price: u128::from_be_bytes(
data.gas_price.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: data.value,
input: data.data.clone().into(),
access_list: data.access_list.clone(),
};
let signature_hash = access_list_tx.signature_hash();
let signed_access_list_tx =
Signed::new_unchecked(access_list_tx, signature, signature_hash);
Ok(TxEnvelope::Eip2930(signed_access_list_tx))
}
Self::Eip1559(data) => {
let eip1559_tx = TxEip1559 {
chain_id,
nonce,
max_fee_per_gas: u128::from_be_bytes(
data.max_fee_per_gas.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
max_priority_fee_per_gas: u128::from_be_bytes(
data.max_priority_fee_per_gas.to_be_bytes::<32>()[16..]
.try_into()
.map_err(|_| {
SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
})?,
),
gas_limit: gas,
to: if let Some(to) = to {
TxKind::Call(to)
} else {
TxKind::Create
},
value: data.value,
input: data.data.clone().into(),
access_list: data.access_list.clone(),
};
let signature_hash = eip1559_tx.signature_hash();
let signed_eip1559_tx =
Signed::new_unchecked(eip1559_tx, signature, signature_hash);
Ok(TxEnvelope::Eip1559(signed_eip1559_tx))
}
Self::Legacy(data) => data.to_enveloped_tx(nonce, gas, to, chain_id, signature),
Self::Eip2930(data) => data.to_enveloped_tx(nonce, gas, to, chain_id, signature),
Self::Eip1559(data) => data.to_enveloped_tx(nonce, gas, to, chain_id, signature),
}
}
}

0 comments on commit 616c666

Please sign in to comment.