feat: withdrawals (#1322)

Co-authored-by: rakita <rakita@users.noreply.github.com>
This commit is contained in:
Roman Krasiuk
2023-02-16 14:44:05 +02:00
committed by GitHub
parent 94674f9c16
commit e97753c768
35 changed files with 648 additions and 264 deletions

View File

@ -85,12 +85,17 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> EngineApi<Client> {
.map(|tx| TransactionSigned::decode(&mut tx.as_ref()))
.collect::<std::result::Result<Vec<_>, _>>()?;
let transactions_root = proofs::calculate_transaction_root(transactions.iter());
let withdrawals_root =
payload.withdrawals.as_ref().map(|w| proofs::calculate_withdrawals_root(w.iter()));
let header = Header {
parent_hash: payload.parent_hash,
beneficiary: payload.fee_recipient,
state_root: payload.state_root,
transactions_root,
receipts_root: payload.receipts_root,
withdrawals_root,
logs_bloom: payload.logs_bloom,
number: payload.block_number.as_u64(),
gas_limit: payload.gas_limit.as_u64(),
@ -113,7 +118,12 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> EngineApi<Client> {
})
}
Ok(SealedBlock { header, body: transactions, ommers: Default::default() })
Ok(SealedBlock {
header,
body: transactions,
withdrawals: payload.withdrawals,
ommers: Default::default(),
})
}
/// Called to retrieve the latest state of the network, validate new blocks, and maintain
@ -333,6 +343,7 @@ mod tests {
header: transformed.header.seal(),
body: transformed.body,
ommers: transformed.ommers.into_iter().map(Header::seal).collect(),
withdrawals: transformed.withdrawals,
}
}

View File

@ -1,7 +1,8 @@
//! Contains types that represent ethereum types in [reth_primitives] when used in RPC
use crate::Transaction;
use reth_primitives::{
Address, Block as PrimitiveBlock, Bloom, Bytes, Header as RethHeader, H256, H64, U256,
Address, Block as PrimitiveBlock, Bloom, Bytes, Header as RethHeader, Withdrawal, H256, H64,
U256,
};
use reth_rlp::Encodable;
use serde::{ser::Error, Deserialize, Serialize, Serializer};
@ -43,6 +44,8 @@ pub struct Block {
/// Base Fee for post-EIP1559 blocks.
#[serde(skip_serializing_if = "Option::is_none")]
pub base_fee_per_gas: Option<U256>,
/// Withdrawals
pub withdrawals: Option<Vec<Withdrawal>>,
}
impl Block {
@ -74,6 +77,7 @@ impl Block {
nonce,
base_fee_per_gas,
extra_data,
withdrawals_root,
} = block.header;
let header = Header {
@ -85,6 +89,7 @@ impl Block {
state_root,
transactions_root,
receipts_root,
withdrawals_root,
number: Some(U256::from(number)),
gas_used: U256::from(gas_used),
gas_limit: U256::from(gas_limit),
@ -115,6 +120,7 @@ impl Block {
base_fee_per_gas: base_fee_per_gas.map(U256::from),
total_difficulty,
size: Some(U256::from(block_length)),
withdrawals: block.withdrawals,
})
}
}
@ -140,6 +146,8 @@ pub struct Header {
pub transactions_root: H256,
/// Transactions receipts root hash
pub receipts_root: H256,
/// Withdrawals root hash
pub withdrawals_root: Option<H256>,
/// Block number
pub number: Option<U256>,
/// Gas Used

View File

@ -3,7 +3,7 @@
#![allow(missing_docs)]
use bytes::BytesMut;
use reth_primitives::{Address, Bloom, Bytes, SealedBlock, H256, H64, U256, U64};
use reth_primitives::{Address, Bloom, Bytes, SealedBlock, Withdrawal, H256, H64, U256, U64};
use reth_rlp::Encodable;
use serde::{Deserialize, Serialize};
@ -30,7 +30,7 @@ pub struct ExecutionPayload {
/// Array of [`Withdrawal`] enabled with V2
/// See <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#executionpayloadv2>
#[serde(default, skip_serializing_if = "Option::is_none")]
pub withdrawal: Option<Withdrawal>,
pub withdrawals: Option<Vec<Withdrawal>>,
}
impl From<SealedBlock> for ExecutionPayload {
@ -59,26 +59,11 @@ impl From<SealedBlock> for ExecutionPayload {
base_fee_per_gas: U256::from(value.base_fee_per_gas.unwrap_or_default()),
block_hash: value.hash(),
transactions,
withdrawal: None,
withdrawals: value.withdrawals,
}
}
}
/// This structure maps onto the validator withdrawal object from the beacon chain spec.
///
/// See also: <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#withdrawalv1>
#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Withdrawal {
pub index: U64,
pub validator_index: U64,
pub address: Address,
/// Note: the amount value is represented on the beacon chain as a little-endian value in units
/// of Gwei, whereas the amount in this structure MUST be converted to a big-endian value in
/// units of Wei.
pub amount: U256,
}
/// This structure encapsulates the fork choice state
#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -99,7 +84,7 @@ pub struct PayloadAttributes {
/// Array of [`Withdrawal`] enabled with V2
/// See <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#executionpayloadv2>
#[serde(default, skip_serializing_if = "Option::is_none")]
pub withdrawal: Option<Withdrawal>, // TODO: should be a vec
pub withdrawals: Option<Vec<Withdrawal>>,
}
/// This structure contains the result of processing a payload