reth_codecs/alloy/
authorization_list.rs
1use crate::Compact;
4use alloy_eips::eip7702::{Authorization as AlloyAuthorization, SignedAuthorization};
5use alloy_primitives::{Address, U256};
6use bytes::Buf;
7use core::ops::Deref;
8use reth_codecs_derive::add_arbitrary_tests;
9
10#[derive(Debug, Clone, PartialEq, Eq, Default, Compact)]
14#[reth_codecs(crate = "crate")]
15#[cfg_attr(
16 any(test, feature = "test-utils"),
17 derive(arbitrary::Arbitrary, serde::Serialize, serde::Deserialize)
18)]
19#[cfg_attr(feature = "test-utils", allow(unreachable_pub), visibility::make(pub))]
20#[add_arbitrary_tests(crate, compact)]
21pub(crate) struct Authorization {
22 chain_id: U256,
23 address: Address,
24 nonce: u64,
25}
26
27impl Compact for AlloyAuthorization {
28 fn to_compact<B>(&self, buf: &mut B) -> usize
29 where
30 B: bytes::BufMut + AsMut<[u8]>,
31 {
32 let authorization =
33 Authorization { chain_id: self.chain_id, address: self.address, nonce: self.nonce() };
34 authorization.to_compact(buf)
35 }
36
37 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
38 let (authorization, buf) = Authorization::from_compact(buf, len);
39 let alloy_authorization = Self {
40 chain_id: authorization.chain_id,
41 address: authorization.address,
42 nonce: authorization.nonce,
43 };
44 (alloy_authorization, buf)
45 }
46}
47
48impl Compact for SignedAuthorization {
49 fn to_compact<B>(&self, buf: &mut B) -> usize
50 where
51 B: bytes::BufMut + AsMut<[u8]>,
52 {
53 buf.put_u8(self.y_parity());
54 buf.put_slice(self.r().as_le_slice());
55 buf.put_slice(self.s().as_le_slice());
56
57 1 + 32 + 32 + self.deref().to_compact(buf)
60 }
61
62 fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
63 let y_parity = buf.get_u8();
64 let r = U256::from_le_slice(&buf[0..32]);
65 buf.advance(32);
66 let s = U256::from_le_slice(&buf[0..32]);
67 buf.advance(32);
68
69 let (auth, buf) = AlloyAuthorization::from_compact(buf, len);
70
71 (Self::new_unchecked(auth, y_parity, r, s), buf)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use alloy_primitives::{address, b256};
79
80 #[test]
81 fn test_roundtrip_compact_authorization_list_item() {
82 let authorization = AlloyAuthorization {
83 chain_id: U256::from(1),
84 address: address!("0xdac17f958d2ee523a2206206994597c13d831ec7"),
85 nonce: 1,
86 }
87 .into_signed(alloy_primitives::PrimitiveSignature::new(
88 b256!("0x1fd474b1f9404c0c5df43b7620119ffbc3a1c3f942c73b6e14e9f55255ed9b1d").into(),
89 b256!("0x29aca24813279a901ec13b5f7bb53385fa1fc627b946592221417ff74a49600d").into(),
90 false,
91 ));
92 let mut compacted_authorization = Vec::<u8>::new();
93 let len = authorization.to_compact(&mut compacted_authorization);
94 let (decoded_authorization, _) =
95 SignedAuthorization::from_compact(&compacted_authorization, len);
96 assert_eq!(authorization, decoded_authorization);
97 }
98}