reth_primitives_traits/
withdrawal.rs

1//! [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) Withdrawal types.
2
3#[cfg(test)]
4mod tests {
5    use alloy_eips::eip4895::Withdrawal;
6    use alloy_primitives::Address;
7    use alloy_rlp::{RlpDecodable, RlpEncodable};
8    use proptest::proptest;
9    use proptest_arbitrary_interop::arb;
10    use reth_codecs::{add_arbitrary_tests, Compact};
11    use serde::{Deserialize, Serialize};
12
13    /// This type is kept for compatibility tests after the codec support was added to alloy-eips
14    /// Withdrawal type natively
15    #[derive(
16        Debug,
17        Clone,
18        PartialEq,
19        Eq,
20        Default,
21        Hash,
22        RlpEncodable,
23        RlpDecodable,
24        Serialize,
25        Deserialize,
26        Compact,
27    )]
28    #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
29    #[add_arbitrary_tests(compact)]
30    struct RethWithdrawal {
31        /// Monotonically increasing identifier issued by consensus layer.
32        index: u64,
33        /// Index of validator associated with withdrawal.
34        validator_index: u64,
35        /// Target address for withdrawn ether.
36        address: Address,
37        /// Value of the withdrawal in gwei.
38        amount: u64,
39    }
40
41    impl PartialEq<Withdrawal> for RethWithdrawal {
42        fn eq(&self, other: &Withdrawal) -> bool {
43            self.index == other.index &&
44                self.validator_index == other.validator_index &&
45                self.address == other.address &&
46                self.amount == other.amount
47        }
48    }
49
50    // <https://github.com/paradigmxyz/reth/issues/1614>
51    #[test]
52    fn test_withdrawal_serde_roundtrip() {
53        let input = r#"[{"index":"0x0","validatorIndex":"0x0","address":"0x0000000000000000000000000000000000001000","amount":"0x1"},{"index":"0x1","validatorIndex":"0x1","address":"0x0000000000000000000000000000000000001001","amount":"0x1"},{"index":"0x2","validatorIndex":"0x2","address":"0x0000000000000000000000000000000000001002","amount":"0x1"},{"index":"0x3","validatorIndex":"0x3","address":"0x0000000000000000000000000000000000001003","amount":"0x1"},{"index":"0x4","validatorIndex":"0x4","address":"0x0000000000000000000000000000000000001004","amount":"0x1"},{"index":"0x5","validatorIndex":"0x5","address":"0x0000000000000000000000000000000000001005","amount":"0x1"},{"index":"0x6","validatorIndex":"0x6","address":"0x0000000000000000000000000000000000001006","amount":"0x1"},{"index":"0x7","validatorIndex":"0x7","address":"0x0000000000000000000000000000000000001007","amount":"0x1"},{"index":"0x8","validatorIndex":"0x8","address":"0x0000000000000000000000000000000000001008","amount":"0x1"},{"index":"0x9","validatorIndex":"0x9","address":"0x0000000000000000000000000000000000001009","amount":"0x1"},{"index":"0xa","validatorIndex":"0xa","address":"0x000000000000000000000000000000000000100a","amount":"0x1"},{"index":"0xb","validatorIndex":"0xb","address":"0x000000000000000000000000000000000000100b","amount":"0x1"},{"index":"0xc","validatorIndex":"0xc","address":"0x000000000000000000000000000000000000100c","amount":"0x1"},{"index":"0xd","validatorIndex":"0xd","address":"0x000000000000000000000000000000000000100d","amount":"0x1"},{"index":"0xe","validatorIndex":"0xe","address":"0x000000000000000000000000000000000000100e","amount":"0x1"},{"index":"0xf","validatorIndex":"0xf","address":"0x000000000000000000000000000000000000100f","amount":"0x1"}]"#;
54
55        let withdrawals: Vec<Withdrawal> = serde_json::from_str(input).unwrap();
56        let s = serde_json::to_string(&withdrawals).unwrap();
57        assert_eq!(input, s);
58    }
59
60    proptest!(
61        #[test]
62        fn test_roundtrip_withdrawal_compat(withdrawal in arb::<RethWithdrawal>()) {
63            // Convert to buffer and then create alloy_access_list from buffer and
64            // compare
65            let mut compacted_reth_withdrawal = Vec::<u8>::new();
66            let len = withdrawal.to_compact(&mut compacted_reth_withdrawal);
67
68            // decode the compacted buffer to AccessList
69            let alloy_withdrawal = Withdrawal::from_compact(&compacted_reth_withdrawal, len).0;
70            assert_eq!(withdrawal, alloy_withdrawal);
71
72            let mut compacted_alloy_withdrawal = Vec::<u8>::new();
73            let alloy_len = alloy_withdrawal.to_compact(&mut compacted_alloy_withdrawal);
74            assert_eq!(len, alloy_len);
75            assert_eq!(compacted_reth_withdrawal, compacted_alloy_withdrawal);
76        }
77    );
78}