reth_codecs/alloy/
withdrawal.rs
1use crate::Compact;
4use alloc::vec::Vec;
5use alloy_eips::eip4895::{Withdrawal as AlloyWithdrawal, Withdrawals};
6use alloy_primitives::Address;
7use reth_codecs_derive::add_arbitrary_tests;
8
9#[derive(Debug, Clone, PartialEq, Eq, Default, Compact)]
13#[cfg_attr(
14 any(test, feature = "test-utils"),
15 derive(arbitrary::Arbitrary, serde::Serialize, serde::Deserialize)
16)]
17#[reth_codecs(crate = "crate")]
18#[cfg_attr(feature = "test-utils", allow(unreachable_pub), visibility::make(pub))]
19#[add_arbitrary_tests(crate, compact)]
20pub(crate) struct Withdrawal {
21 index: u64,
23 validator_index: u64,
25 address: Address,
27 amount: u64,
29}
30
31impl Compact for AlloyWithdrawal {
32 fn to_compact<B>(&self, buf: &mut B) -> usize
33 where
34 B: bytes::BufMut + AsMut<[u8]>,
35 {
36 let withdrawal = Withdrawal {
37 index: self.index,
38 validator_index: self.validator_index,
39 address: self.address,
40 amount: self.amount,
41 };
42 withdrawal.to_compact(buf)
43 }
44
45 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
46 let (withdrawal, _) = Withdrawal::from_compact(buf, len);
47 let alloy_withdrawal = Self {
48 index: withdrawal.index,
49 validator_index: withdrawal.validator_index,
50 address: withdrawal.address,
51 amount: withdrawal.amount,
52 };
53 (alloy_withdrawal, buf)
54 }
55}
56
57impl Compact for Withdrawals {
58 fn to_compact<B>(&self, buf: &mut B) -> usize
59 where
60 B: bytes::BufMut + AsMut<[u8]>,
61 {
62 self.as_ref().to_compact(buf)
63 }
64
65 fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
66 let (withdrawals, new_buf) = Vec::from_compact(buf, buf.len());
67 buf = new_buf;
68 let alloy_withdrawals = Self::new(withdrawals);
69 (alloy_withdrawals, buf)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use proptest::proptest;
77 use proptest_arbitrary_interop::arb;
78
79 proptest! {
80 #[test]
81 fn roundtrip_withdrawal(withdrawal in arb::<AlloyWithdrawal>()) {
82 let mut compacted_withdrawal = Vec::<u8>::new();
83 let len = withdrawal.to_compact(&mut compacted_withdrawal);
84 let (decoded, _) = AlloyWithdrawal::from_compact(&compacted_withdrawal, len);
85 assert_eq!(withdrawal, decoded)
86 }
87
88 #[test]
89 fn roundtrip_withdrawals(withdrawals in arb::<Withdrawals>()) {
90 let mut compacted_withdrawals = Vec::<u8>::new();
91 let len = withdrawals.to_compact(&mut compacted_withdrawals);
92 let (decoded, _) = Withdrawals::from_compact(&compacted_withdrawals, len);
93 assert_eq!(withdrawals, decoded);
94 }
95 }
96
97 #[test]
103 fn test_ensure_backwards_compatibility() {
104 assert_eq!(Withdrawal::bitflag_encoded_bytes(), 2);
105 }
106}