Skip to main content

ethrex_common/types/
tx_fields.rs

1use crate::{Address, H256, U256};
2use ethrex_rlp::{
3    decode::RLPDecode,
4    encode::RLPEncode,
5    error::RLPDecodeError,
6    structs::{Decoder, Encoder},
7};
8use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize};
9use serde::{Deserialize, Serialize};
10/// A list of addresses and storage keys that the transaction plans to access.
11/// See [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)
12pub type AccessList = Vec<AccessListItem>;
13pub type AccessListItem = (Address, Vec<H256>);
14
15/// Used in Type-4 transactions. Added in [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)
16pub type AuthorizationList = Vec<AuthorizationTuple>;
17#[derive(
18    Debug,
19    Clone,
20    Default,
21    Copy,
22    PartialEq,
23    Eq,
24    PartialOrd,
25    Ord,
26    Serialize,
27    Deserialize,
28    RSerialize,
29    RDeserialize,
30    Archive,
31)]
32#[serde(rename_all = "camelCase")]
33/// Used in Type-4 transactions. Added in [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)
34pub struct AuthorizationTuple {
35    #[rkyv(with = crate::rkyv_utils::U256Wrapper)]
36    pub chain_id: U256,
37    #[rkyv(with = crate::rkyv_utils::H160Wrapper)]
38    pub address: Address,
39    #[serde(
40        default,
41        deserialize_with = "crate::serde_utils::u64::deser_hex_or_dec_str"
42    )]
43    pub nonce: u64,
44    #[rkyv(with = crate::rkyv_utils::U256Wrapper)]
45    pub y_parity: U256,
46    #[serde(rename = "r")]
47    #[rkyv(with = crate::rkyv_utils::U256Wrapper)]
48    pub r_signature: U256,
49    #[serde(rename = "s")]
50    #[rkyv(with = crate::rkyv_utils::U256Wrapper)]
51    pub s_signature: U256,
52}
53
54impl RLPEncode for AuthorizationTuple {
55    fn encode(&self, buf: &mut dyn bytes::BufMut) {
56        Encoder::new(buf)
57            .encode_field(&self.chain_id)
58            .encode_field(&self.address)
59            .encode_field(&self.nonce)
60            .encode_field(&self.y_parity)
61            .encode_field(&self.r_signature)
62            .encode_field(&self.s_signature)
63            .finish();
64    }
65}
66
67impl RLPDecode for AuthorizationTuple {
68    fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
69        let decoder = Decoder::new(rlp)?;
70        let (chain_id, decoder) = decoder.decode_field("chain_id")?;
71        let (address, decoder) = decoder.decode_field("address")?;
72        let (nonce, decoder) = decoder.decode_field("nonce")?;
73        let (y_parity, decoder) = decoder.decode_field("y_parity")?;
74        // EIP-7702 bounds y_parity to < 2**8 (geth models it as a u8). Reject
75        // out-of-range values at decode so a type-4 tx carrying one is rejected on L1
76        // as it is by other clients. The field stays U256 to keep the JSON-RPC and
77        // rkyv wire formats unchanged.
78        if y_parity > U256::from(u8::MAX) {
79            return Err(RLPDecodeError::Custom(
80                "EIP-7702 authorization y_parity must be < 2**8".to_string(),
81            ));
82        }
83        let (r_signature, decoder) = decoder.decode_field("r_signature")?;
84        let (s_signature, decoder) = decoder.decode_field("s_signature")?;
85        let rest = decoder.finish()?;
86        Ok((
87            AuthorizationTuple {
88                chain_id,
89                address,
90                nonce,
91                y_parity,
92                r_signature,
93                s_signature,
94            },
95            rest,
96        ))
97    }
98}