diff --git a/ethers-core/src/types/block.rs b/ethers-core/src/types/block.rs index e43813eff..893acce9b 100644 --- a/ethers-core/src/types/block.rs +++ b/ethers-core/src/types/block.rs @@ -1,6 +1,6 @@ // Modified from -use crate::types::{Address, Bloom, Bytes, Transaction, TxHash, H256, U256, U64}; +use crate::types::{Address, Bloom, Bytes, Transaction, TxHash, Withdrawal, H256, U256, U64}; use chrono::{DateTime, TimeZone, Utc}; use serde::{ de::{MapAccess, Visitor}, @@ -84,6 +84,14 @@ pub struct Block { /// Base fee per unit of gas (if past London) #[serde(rename = "baseFeePerGas")] pub base_fee_per_gas: Option, + /// Withdrawals root hash (if past Shanghai) + #[serde(default, skip_serializing_if = "Option::is_none", rename = "withdrawalsRoot")] + #[cfg(not(feature = "celo"))] + pub withdrawals_root: Option, + /// Withdrawals (if past Shanghai) + #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg(not(feature = "celo"))] + pub withdrawals: Option>, #[cfg(feature = "celo")] #[cfg_attr(docsrs, doc(cfg(feature = "celo")))] @@ -218,6 +226,8 @@ impl Block { mix_hash, nonce, base_fee_per_gas, + withdrawals_root, + withdrawals, other, .. } = self; @@ -243,6 +253,8 @@ impl Block { mix_hash, nonce, base_fee_per_gas, + withdrawals_root, + withdrawals, transactions, other, } @@ -322,6 +334,8 @@ impl From> for Block { mix_hash, nonce, base_fee_per_gas, + withdrawals_root, + withdrawals, other, } = full; Block { @@ -346,6 +360,8 @@ impl From> for Block { mix_hash, nonce, base_fee_per_gas, + withdrawals_root, + withdrawals, transactions: transactions.iter().map(|tx| tx.hash).collect(), other, } diff --git a/ethers-core/src/types/mod.rs b/ethers-core/src/types/mod.rs index ae6a85e63..13bd610eb 100644 --- a/ethers-core/src/types/mod.rs +++ b/ethers-core/src/types/mod.rs @@ -81,3 +81,6 @@ pub use syncing::{SyncProgress, SyncingStatus}; mod opcode; pub use opcode::Opcode; + +mod withdrawal; +pub use withdrawal::Withdrawal; diff --git a/ethers-core/src/types/withdrawal.rs b/ethers-core/src/types/withdrawal.rs new file mode 100644 index 000000000..b63ada3d2 --- /dev/null +++ b/ethers-core/src/types/withdrawal.rs @@ -0,0 +1,30 @@ +use crate::types::{Address, U256, U64}; +use serde::{Deserialize, Serialize}; + +/// A validator withdrawal from the consensus layer. +/// See EIP-4895: Beacon chain push withdrawals as operations. +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct Withdrawal { + /// Monotonically increasing identifier issued by consensus layer + pub index: U64, + + /// Index of validator associated with withdrawal + #[serde(rename = "validatorIndex")] + pub validator_index: U64, + + /// Target address for withdrawn ether + pub address: Address, + + /// Value of withdrawal (in wei) + pub amount: U256, +} + +impl rlp::Encodable for Withdrawal { + fn rlp_append(&self, s: &mut rlp::RlpStream) { + s.begin_list(4); + s.append(&self.index); + s.append(&self.validator_index); + s.append(&self.address); + s.append(&self.amount); + } +}