kona_protocol/batch/tx_data/
eip2930.rs

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