Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consensus: implement Arbitrary for Header #1235

Merged
merged 3 commits into from
Sep 4, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions crates/consensus/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,83 @@ impl Decodable for Header {
}
}

/// Generates a header which is valid __with respect to past and future forks__. This means, for
/// example, that if the withdrawals root is present, the base fee per gas is also present.
///
/// If blob gas used were present, then the excess blob gas and parent beacon block root are also
/// present. In this example, the withdrawals root would also be present.
///
/// This __does not, and should not guarantee__ that the header is valid with respect to __anything
/// else__.
#[cfg(any(test, feature = "arbitrary"))]
pub const fn generate_valid_header(
mut header: Header,
eip_4844_active: bool,
blob_gas_used: u128,
excess_blob_gas: u128,
parent_beacon_block_root: B256,
) -> Header {
// Clear all related fields if EIP-1559 is inactive
if header.base_fee_per_gas.is_none() {
header.withdrawals_root = None;
}

// Set fields based on EIP-4844 being active
if eip_4844_active {
header.blob_gas_used = Some(blob_gas_used);
header.excess_blob_gas = Some(excess_blob_gas);
header.parent_beacon_block_root = Some(parent_beacon_block_root);
} else {
header.blob_gas_used = None;
header.excess_blob_gas = None;
header.parent_beacon_block_root = None;
}

// Placeholder for future EIP adjustments
header.requests_root = None;

header
}

#[cfg(any(test, feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for Header {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
// Generate an arbitrary header, passing it to the generate_valid_header function to make
// sure it is valid _with respect to hardforks only_.
let base = Self {
parent_hash: u.arbitrary()?,
ommers_hash: u.arbitrary()?,
beneficiary: u.arbitrary()?,
state_root: u.arbitrary()?,
transactions_root: u.arbitrary()?,
receipts_root: u.arbitrary()?,
logs_bloom: u.arbitrary()?,
difficulty: u.arbitrary()?,
number: u.arbitrary()?,
gas_limit: u.arbitrary()?,
gas_used: u.arbitrary()?,
timestamp: u.arbitrary()?,
extra_data: u.arbitrary()?,
mix_hash: u.arbitrary()?,
nonce: u.arbitrary()?,
base_fee_per_gas: u.arbitrary()?,
blob_gas_used: u.arbitrary()?,
excess_blob_gas: u.arbitrary()?,
parent_beacon_block_root: u.arbitrary()?,
requests_root: u.arbitrary()?,
withdrawals_root: u.arbitrary()?,
};

Ok(generate_valid_header(
base,
u.arbitrary()?,
u.arbitrary()?,
u.arbitrary()?,
u.arbitrary()?,
))
}
}

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