Skip to content

Commit

Permalink
feat: derive serde for header (#902)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jun 15, 2024
1 parent 899b8b9 commit b857ea5
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions crates/consensus/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub const EMPTY_ROOT_HASH: B256 =

/// Ethereum Block header
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Header {
/// The Keccak 256-bit hash of the parent
/// block’s header, in its entirety; formally Hp.
Expand All @@ -42,6 +44,7 @@ pub struct Header {
pub receipts_root: B256,
/// The Keccak 256-bit hash of the withdrawals list portion of this block.
/// <https://eips.ethereum.org/EIPS/eip-4895>
#[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
pub withdrawals_root: Option<B256>,
/// The Bloom filter composed from indexable information (logger address and log topics)
/// contained in each log entry from the receipt of each transaction in the transactions list;
Expand All @@ -52,13 +55,17 @@ pub struct Header {
pub difficulty: U256,
/// A scalar value equal to the number of ancestor blocks. The genesis block has a number of
/// zero; formally Hi.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
pub number: BlockNumber,
/// A scalar value equal to the current limit of gas expenditure per block; formally Hl.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
pub gas_limit: u128,
/// A scalar value equal to the total gas used in transactions in this block; formally Hg.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
pub gas_used: u128,
/// A scalar value equal to the reasonable output of Unix’s time() at this block’s inception;
/// formally Hs.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
pub timestamp: u64,
/// A 256-bit hash which, combined with the
/// nonce, proves that a sufficient amount of computation has been carried out on this block;
Expand All @@ -73,13 +80,37 @@ pub struct Header {
/// The algorithm results in the base fee per gas increasing when blocks are
/// above the gas target, and decreasing when blocks are below the gas target. The base fee per
/// gas is burned.
#[cfg_attr(
feature = "serde",
serde(
default,
with = "alloy_serde::quantity::opt",
skip_serializing_if = "Option::is_none"
)
)]
pub base_fee_per_gas: Option<u128>,
/// The total amount of blob gas consumed by the transactions within the block, added in
/// EIP-4844.
#[cfg_attr(
feature = "serde",
serde(
default,
with = "alloy_serde::quantity::opt",
skip_serializing_if = "Option::is_none"
)
)]
pub blob_gas_used: Option<u128>,
/// A running total of blob gas consumed in excess of the target, prior to the block. Blocks
/// with above-target blob gas consumption increase this value, blocks with below-target blob
/// gas consumption decrease it (bounded at 0). This was added in EIP-4844.
#[cfg_attr(
feature = "serde",
serde(
default,
with = "alloy_serde::quantity::opt",
skip_serializing_if = "Option::is_none"
)
)]
pub excess_blob_gas: Option<u128>,
/// The hash of the parent beacon block's root is included in execution blocks, as proposed by
/// EIP-4788.
Expand All @@ -88,11 +119,13 @@ pub struct Header {
/// and more.
///
/// The beacon roots contract handles root storage, enhancing Ethereum's functionalities.
#[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
pub parent_beacon_block_root: Option<B256>,
/// The Keccak 256-bit hash of the root node of the trie structure populated with each
/// [EIP-7685] request in the block body.
///
/// [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685
#[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
pub requests_root: Option<B256>,
/// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
/// fewer; formally Hx.
Expand Down Expand Up @@ -492,3 +525,25 @@ impl Decodable for Header {
Ok(this)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[cfg(feature = "serde")]
#[test]
fn header_serde() {
let raw = r#"{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","ommersHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","beneficiary":"0x0000000000000000000000000000000000000000","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x0","number":"0x0","gasLimit":"0x0","gasUsed":"0x0","timestamp":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":"0x1","extraData":"0x"}"#;
let header = Header {
base_fee_per_gas: Some(1),
withdrawals_root: Some(EMPTY_ROOT_HASH),
..Default::default()
};

let json = serde_json::to_string(&header).unwrap();
assert_eq!(json, raw);

let decoded: Header = serde_json::from_str(&json).unwrap();
assert_eq!(decoded, header);
}
}

0 comments on commit b857ea5

Please # to comment.