mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: replace duplicate Withdrawal type with alloy (#7931)
This commit is contained in:
@ -11,8 +11,7 @@ use reth_rpc_types::engine::{
|
||||
PayloadId,
|
||||
};
|
||||
use reth_rpc_types_compat::engine::payload::{
|
||||
block_to_payload_v3, convert_block_to_payload_field_v2,
|
||||
convert_standalone_withdraw_to_withdrawal, try_block_to_payload_v1,
|
||||
block_to_payload_v3, convert_block_to_payload_field_v2, try_block_to_payload_v1,
|
||||
};
|
||||
use revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId};
|
||||
use std::convert::Infallible;
|
||||
@ -159,22 +158,13 @@ impl EthPayloadBuilderAttributes {
|
||||
pub fn new(parent: B256, attributes: PayloadAttributes) -> Self {
|
||||
let id = payload_id(&parent, &attributes);
|
||||
|
||||
let withdraw = attributes.withdrawals.map(|withdrawals| {
|
||||
Withdrawals::new(
|
||||
withdrawals
|
||||
.into_iter()
|
||||
.map(convert_standalone_withdraw_to_withdrawal) // Removed the parentheses here
|
||||
.collect(),
|
||||
)
|
||||
});
|
||||
|
||||
Self {
|
||||
id,
|
||||
parent,
|
||||
timestamp: attributes.timestamp,
|
||||
suggested_fee_recipient: attributes.suggested_fee_recipient,
|
||||
prev_randao: attributes.prev_randao,
|
||||
withdrawals: withdraw.unwrap_or_default(),
|
||||
withdrawals: attributes.withdrawals.unwrap_or_default().into(),
|
||||
parent_beacon_block_root: attributes.parent_beacon_block_root,
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,7 @@ use reth_rpc_types::engine::{
|
||||
OptimismPayloadAttributes, PayloadId,
|
||||
};
|
||||
use reth_rpc_types_compat::engine::payload::{
|
||||
block_to_payload_v3, convert_block_to_payload_field_v2,
|
||||
convert_standalone_withdraw_to_withdrawal, try_block_to_payload_v1,
|
||||
block_to_payload_v3, convert_block_to_payload_field_v2, try_block_to_payload_v1,
|
||||
};
|
||||
use revm::primitives::HandlerCfg;
|
||||
use std::sync::Arc;
|
||||
@ -54,19 +53,13 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
|
||||
(payload_id_optimism(&parent, &attributes, &transactions), transactions)
|
||||
};
|
||||
|
||||
let withdraw = attributes.payload_attributes.withdrawals.map(|withdrawals| {
|
||||
Withdrawals::new(
|
||||
withdrawals.into_iter().map(convert_standalone_withdraw_to_withdrawal).collect(),
|
||||
)
|
||||
});
|
||||
|
||||
let payload_attributes = EthPayloadBuilderAttributes {
|
||||
id,
|
||||
parent,
|
||||
timestamp: attributes.payload_attributes.timestamp,
|
||||
suggested_fee_recipient: attributes.payload_attributes.suggested_fee_recipient,
|
||||
prev_randao: attributes.payload_attributes.prev_randao,
|
||||
withdrawals: withdraw.unwrap_or_default(),
|
||||
withdrawals: attributes.payload_attributes.withdrawals.unwrap_or_default().into(),
|
||||
parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root,
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ pub fn insert_post_block_withdrawals_balance_increments(
|
||||
for withdrawal in withdrawals.iter() {
|
||||
if withdrawal.amount > 0 {
|
||||
*balance_increments.entry(withdrawal.address).or_default() +=
|
||||
withdrawal.amount_wei();
|
||||
withdrawal.amount_wei().to::<u128>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ use reth_rpc_types::engine::{
|
||||
ExecutionPayload, ExecutionPayloadBodyV1, ExecutionPayloadV1, PayloadError,
|
||||
};
|
||||
use reth_rpc_types_compat::engine::payload::{
|
||||
convert_standalone_withdraw_to_withdrawal, convert_to_payload_body_v1, try_block_to_payload,
|
||||
try_block_to_payload_v1, try_into_sealed_block, try_payload_v1_to_block,
|
||||
convert_to_payload_body_v1, try_block_to_payload, try_block_to_payload_v1,
|
||||
try_into_sealed_block, try_payload_v1_to_block,
|
||||
};
|
||||
|
||||
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> ExecutionPayload {
|
||||
@ -46,11 +46,7 @@ fn payload_body_roundtrip() {
|
||||
.map(|x| TransactionSigned::decode(&mut &x[..]))
|
||||
.collect::<Result<Vec<_>, _>>(),
|
||||
);
|
||||
let withdraw = payload_body.withdrawals.map(|withdrawals| {
|
||||
Withdrawals::new(
|
||||
withdrawals.into_iter().map(convert_standalone_withdraw_to_withdrawal).collect(),
|
||||
)
|
||||
});
|
||||
let withdraw = payload_body.withdrawals.map(Withdrawals::new);
|
||||
assert_eq!(block.withdrawals, withdraw);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
//! Standalone functions for engine specific rpc type conversions
|
||||
pub mod payload;
|
||||
pub use payload::{
|
||||
convert_standalone_withdraw_to_withdrawal, convert_withdrawal_to_standalone_withdraw,
|
||||
try_block_to_payload_v1, try_into_sealed_block, try_payload_v1_to_block,
|
||||
};
|
||||
pub use payload::{try_block_to_payload_v1, try_into_sealed_block, try_payload_v1_to_block};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
use reth_primitives::{
|
||||
constants::{EMPTY_OMMER_ROOT_HASH, MAXIMUM_EXTRA_DATA_SIZE, MIN_PROTOCOL_BASE_FEE_U256},
|
||||
proofs::{self},
|
||||
Block, Header, SealedBlock, TransactionSigned, UintTryTo, Withdrawal, Withdrawals, B256, U256,
|
||||
Block, Header, SealedBlock, TransactionSigned, UintTryTo, Withdrawals, B256, U256,
|
||||
};
|
||||
use reth_rpc_types::engine::{
|
||||
payload::{ExecutionPayloadBodyV1, ExecutionPayloadFieldV2, ExecutionPayloadInputV2},
|
||||
@ -65,11 +65,8 @@ pub fn try_payload_v2_to_block(payload: ExecutionPayloadV2) -> Result<Block, Pay
|
||||
// this performs the same conversion as the underlying V1 payload, but calculates the
|
||||
// withdrawals root and adds withdrawals
|
||||
let mut base_sealed_block = try_payload_v1_to_block(payload.payload_inner)?;
|
||||
let withdrawals = Withdrawals::new(
|
||||
payload.withdrawals.iter().map(|w| convert_standalone_withdraw_to_withdrawal(*w)).collect(),
|
||||
);
|
||||
let withdrawals_root = proofs::calculate_withdrawals_root(&withdrawals);
|
||||
base_sealed_block.withdrawals = Some(withdrawals);
|
||||
let withdrawals_root = proofs::calculate_withdrawals_root(&payload.withdrawals);
|
||||
base_sealed_block.withdrawals = Some(payload.withdrawals.into());
|
||||
base_sealed_block.header.withdrawals_root = Some(withdrawals_root);
|
||||
Ok(base_sealed_block)
|
||||
}
|
||||
@ -124,13 +121,6 @@ pub fn try_block_to_payload_v1(value: SealedBlock) -> ExecutionPayloadV1 {
|
||||
/// Converts [SealedBlock] to [ExecutionPayloadV2]
|
||||
pub fn try_block_to_payload_v2(value: SealedBlock) -> ExecutionPayloadV2 {
|
||||
let transactions = value.raw_transactions();
|
||||
let standalone_withdrawals: Vec<reth_rpc_types::Withdrawal> = value
|
||||
.withdrawals
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(convert_withdrawal_to_standalone_withdraw)
|
||||
.collect();
|
||||
|
||||
ExecutionPayloadV2 {
|
||||
payload_inner: ExecutionPayloadV1 {
|
||||
@ -149,7 +139,7 @@ pub fn try_block_to_payload_v2(value: SealedBlock) -> ExecutionPayloadV2 {
|
||||
block_hash: value.hash(),
|
||||
transactions,
|
||||
},
|
||||
withdrawals: standalone_withdrawals,
|
||||
withdrawals: value.withdrawals.unwrap_or_default().into_inner(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,15 +147,9 @@ pub fn try_block_to_payload_v2(value: SealedBlock) -> ExecutionPayloadV2 {
|
||||
pub fn block_to_payload_v3(value: SealedBlock) -> ExecutionPayloadV3 {
|
||||
let transactions = value.raw_transactions();
|
||||
|
||||
let withdrawals: Vec<reth_rpc_types::Withdrawal> = value
|
||||
.withdrawals
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(convert_withdrawal_to_standalone_withdraw)
|
||||
.collect();
|
||||
|
||||
ExecutionPayloadV3 {
|
||||
blob_gas_used: value.blob_gas_used.unwrap_or_default(),
|
||||
excess_blob_gas: value.excess_blob_gas.unwrap_or_default(),
|
||||
payload_inner: ExecutionPayloadV2 {
|
||||
payload_inner: ExecutionPayloadV1 {
|
||||
parent_hash: value.parent_hash,
|
||||
@ -183,11 +167,8 @@ pub fn block_to_payload_v3(value: SealedBlock) -> ExecutionPayloadV3 {
|
||||
block_hash: value.hash(),
|
||||
transactions,
|
||||
},
|
||||
withdrawals,
|
||||
withdrawals: value.withdrawals.unwrap_or_default().into_inner(),
|
||||
},
|
||||
|
||||
blob_gas_used: value.blob_gas_used.unwrap_or_default(),
|
||||
excess_blob_gas: value.excess_blob_gas.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,11 +203,8 @@ pub fn convert_payload_input_v2_to_payload(value: ExecutionPayloadInputV2) -> Ex
|
||||
|
||||
/// Converts [SealedBlock] to [ExecutionPayloadInputV2]
|
||||
pub fn convert_block_to_payload_input_v2(value: SealedBlock) -> ExecutionPayloadInputV2 {
|
||||
let withdraw = value.withdrawals.clone().map(|withdrawals| {
|
||||
withdrawals.into_iter().map(convert_withdrawal_to_standalone_withdraw).collect::<Vec<_>>()
|
||||
});
|
||||
ExecutionPayloadInputV2 {
|
||||
withdrawals: withdraw,
|
||||
withdrawals: value.withdrawals.clone().map(Withdrawals::into_inner),
|
||||
execution_payload: try_block_to_payload_v1(value),
|
||||
}
|
||||
}
|
||||
@ -295,30 +273,6 @@ pub fn validate_block_hash(
|
||||
Ok(sealed_block)
|
||||
}
|
||||
|
||||
/// Converts [Withdrawal] to [reth_rpc_types::Withdrawal]
|
||||
pub fn convert_withdrawal_to_standalone_withdraw(
|
||||
withdrawal: Withdrawal,
|
||||
) -> reth_rpc_types::Withdrawal {
|
||||
reth_rpc_types::Withdrawal {
|
||||
index: withdrawal.index,
|
||||
validator_index: withdrawal.validator_index,
|
||||
address: withdrawal.address,
|
||||
amount: withdrawal.amount,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts [reth_rpc_types::Withdrawal] to [Withdrawal]
|
||||
pub fn convert_standalone_withdraw_to_withdrawal(
|
||||
standalone: reth_rpc_types::Withdrawal,
|
||||
) -> Withdrawal {
|
||||
Withdrawal {
|
||||
index: standalone.index,
|
||||
validator_index: standalone.validator_index,
|
||||
address: standalone.address,
|
||||
amount: standalone.amount,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts [Block] to [ExecutionPayloadBodyV1]
|
||||
pub fn convert_to_payload_body_v1(value: Block) -> ExecutionPayloadBodyV1 {
|
||||
let transactions = value.body.into_iter().map(|tx| {
|
||||
@ -326,10 +280,10 @@ pub fn convert_to_payload_body_v1(value: Block) -> ExecutionPayloadBodyV1 {
|
||||
tx.encode_enveloped(&mut out);
|
||||
out.into()
|
||||
});
|
||||
let withdraw: Option<Vec<reth_rpc_types::Withdrawal>> = value.withdrawals.map(|withdrawals| {
|
||||
withdrawals.into_iter().map(convert_withdrawal_to_standalone_withdraw).collect::<Vec<_>>()
|
||||
});
|
||||
ExecutionPayloadBodyV1 { transactions: transactions.collect(), withdrawals: withdraw }
|
||||
ExecutionPayloadBodyV1 {
|
||||
transactions: transactions.collect(),
|
||||
withdrawals: value.withdrawals.map(Withdrawals::into_inner),
|
||||
}
|
||||
}
|
||||
|
||||
/// Transforms a [SealedBlock] into a [ExecutionPayloadV1]
|
||||
|
||||
Reference in New Issue
Block a user