feat: replace duplicate Withdrawal type with alloy (#7931)

This commit is contained in:
Matthias Seitz
2024-04-27 17:09:28 +02:00
committed by GitHub
parent 5f15af5401
commit 2deb259ead
7 changed files with 82 additions and 142 deletions

View File

@@ -1,51 +1,12 @@
use crate::{constants::GWEI_TO_WEI, serde_helper::u64_via_ruint, Address};
use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
//! [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) Withdrawal types.
use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper};
use reth_codecs::{main_codec, Compact};
use std::{
mem,
ops::{Deref, DerefMut},
};
use std::ops::{Deref, DerefMut};
/// Withdrawal represents a validator withdrawal from the consensus layer.
#[main_codec]
#[derive(Debug, Clone, PartialEq, Eq, Default, Hash, RlpEncodable, RlpDecodable)]
pub struct Withdrawal {
/// Monotonically increasing identifier issued by consensus layer.
#[serde(with = "u64_via_ruint")]
pub index: u64,
/// Index of validator associated with withdrawal.
#[serde(with = "u64_via_ruint", rename = "validatorIndex")]
pub validator_index: u64,
/// Target address for withdrawn ether.
pub address: Address,
/// Value of the withdrawal in gwei.
#[serde(with = "u64_via_ruint")]
pub amount: u64,
}
impl Withdrawal {
/// Return the withdrawal amount in wei.
pub fn amount_wei(&self) -> u128 {
self.amount as u128 * GWEI_TO_WEI as u128
}
/// Calculate a heuristic for the in-memory size of the [Withdrawal].
#[inline]
pub fn size(&self) -> usize {
mem::size_of::<Self>()
}
}
impl From<reth_rpc_types::Withdrawal> for Withdrawal {
fn from(withdrawal: reth_rpc_types::Withdrawal) -> Self {
Self {
index: withdrawal.index,
validator_index: withdrawal.index,
address: withdrawal.address,
amount: withdrawal.amount,
}
}
}
/// Re-export from `alloy_eips`.
#[doc(inline)]
pub use alloy_eips::eip4895::Withdrawal;
/// Represents a collection of Withdrawals.
#[main_codec]
@@ -61,13 +22,13 @@ impl Withdrawals {
/// Calculate the total size, including capacity, of the Withdrawals.
#[inline]
pub fn total_size(&self) -> usize {
self.size() + self.capacity() * std::mem::size_of::<Withdrawal>()
self.capacity() * std::mem::size_of::<Withdrawal>()
}
/// Calculate a heuristic for the in-memory size of the [Withdrawals].
#[inline]
pub fn size(&self) -> usize {
self.iter().map(Withdrawal::size).sum()
self.len() * std::mem::size_of::<Withdrawal>()
}
/// Get an iterator over the Withdrawals.
@@ -115,15 +76,45 @@ impl DerefMut for Withdrawals {
}
}
impl From<Vec<reth_rpc_types::Withdrawal>> for Withdrawals {
fn from(withdrawals: Vec<reth_rpc_types::Withdrawal>) -> Self {
Self(withdrawals.into_iter().map(Into::into).collect())
impl From<Vec<Withdrawal>> for Withdrawals {
fn from(withdrawals: Vec<Withdrawal>) -> Self {
Self(withdrawals)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{serde_helper::u64_via_ruint, Address};
use alloy_rlp::{RlpDecodable, RlpEncodable};
use proptest::proptest;
/// This type is kept for compatibility tests after the codec support was added to alloy-eips
/// Withdrawal type natively
#[main_codec]
#[derive(Debug, Clone, PartialEq, Eq, Default, Hash, RlpEncodable, RlpDecodable)]
struct RethWithdrawal {
/// Monotonically increasing identifier issued by consensus layer.
#[serde(with = "u64_via_ruint")]
index: u64,
/// Index of validator associated with withdrawal.
#[serde(with = "u64_via_ruint", rename = "validatorIndex")]
validator_index: u64,
/// Target address for withdrawn ether.
address: Address,
/// Value of the withdrawal in gwei.
#[serde(with = "u64_via_ruint")]
amount: u64,
}
impl PartialEq<Withdrawal> for RethWithdrawal {
fn eq(&self, other: &Withdrawal) -> bool {
self.index == other.index &&
self.validator_index == other.validator_index &&
self.address == other.address &&
self.amount == other.amount
}
}
// <https://github.com/paradigmxyz/reth/issues/1614>
#[test]
@@ -134,4 +125,23 @@ mod tests {
let s = serde_json::to_string(&withdrawals).unwrap();
assert_eq!(input, s);
}
proptest!(
#[test]
fn test_roundtrip_withdrawal_compat(withdrawal: RethWithdrawal) {
// Convert to buffer and then create alloy_access_list from buffer and
// compare
let mut compacted_reth_withdrawal = Vec::<u8>::new();
let len = withdrawal.clone().to_compact(&mut compacted_reth_withdrawal);
// decode the compacted buffer to AccessList
let alloy_withdrawal = Withdrawal::from_compact(&compacted_reth_withdrawal, len).0;
assert_eq!(withdrawal, alloy_withdrawal);
let mut compacted_alloy_withdrawal = Vec::<u8>::new();
let alloy_len = alloy_withdrawal.to_compact(&mut compacted_alloy_withdrawal);
assert_eq!(len, alloy_len);
assert_eq!(compacted_reth_withdrawal, compacted_alloy_withdrawal);
}
);
}