kona_protocol/batch/tx_data/
legacy.rs

1//! This module contains the legacy transaction data type for a span batch.
2
3use crate::{SpanBatchError, SpanDecodingError};
4use alloy_consensus::{SignableTransaction, Signed, TxLegacy};
5use alloy_primitives::{Address, PrimitiveSignature as Signature, TxKind, U256};
6use alloy_rlp::{Bytes, RlpDecodable, RlpEncodable};
7
8/// The transaction data for a legacy transaction within a span batch.
9#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)]
10pub struct SpanBatchLegacyTransactionData {
11    /// The ETH value of the transaction.
12    pub value: U256,
13    /// The gas price of the transaction.
14    pub gas_price: U256,
15    /// Transaction calldata.
16    pub data: Bytes,
17}
18
19impl SpanBatchLegacyTransactionData {
20    /// Converts [SpanBatchLegacyTransactionData] into a signed [`TxLegacy`].
21    pub fn to_signed_tx(
22        &self,
23        nonce: u64,
24        gas: u64,
25        to: Option<Address>,
26        chain_id: u64,
27        signature: Signature,
28        is_protected: bool,
29    ) -> Result<Signed<TxLegacy>, SpanBatchError> {
30        let legacy_tx = TxLegacy {
31            chain_id: is_protected.then_some(chain_id),
32            nonce,
33            gas_price: u128::from_be_bytes(
34                self.gas_price.to_be_bytes::<32>()[16..].try_into().map_err(|_| {
35                    SpanBatchError::Decoding(SpanDecodingError::InvalidTransactionData)
36                })?,
37            ),
38            gas_limit: gas,
39            to: to.map_or(TxKind::Create, TxKind::Call),
40            value: self.value,
41            input: self.data.clone().into(),
42        };
43        let signature_hash = legacy_tx.signature_hash();
44        Ok(Signed::new_unchecked(legacy_tx, signature, signature_hash))
45    }
46}
47
48#[cfg(test)]
49mod test {
50    use super::*;
51    use crate::SpanBatchTransactionData;
52    use alloc::vec::Vec;
53    use alloy_rlp::{Decodable, Encodable as _};
54
55    #[test]
56    fn encode_legacy_tx_data_roundtrip() {
57        let legacy_tx = SpanBatchLegacyTransactionData {
58            value: U256::from(0xFF),
59            gas_price: U256::from(0xEE),
60            data: Bytes::from(alloc::vec![0x01, 0x02, 0x03]),
61        };
62
63        let mut encoded_buf = Vec::new();
64        SpanBatchTransactionData::Legacy(legacy_tx.clone()).encode(&mut encoded_buf);
65
66        let decoded = SpanBatchTransactionData::decode(&mut encoded_buf.as_slice()).unwrap();
67        let SpanBatchTransactionData::Legacy(legacy_decoded) = decoded else {
68            panic!("Expected SpanBatchLegacyTransactionData, got {:?}", decoded);
69        };
70
71        assert_eq!(legacy_tx, legacy_decoded);
72    }
73}