chore: Header::seal and Header::seal_slow distinction (#1409)

This commit is contained in:
Roman Krasiuk
2023-02-16 18:55:58 +02:00
committed by GitHub
parent 9dae54a3ed
commit 9b81b4f20d
16 changed files with 65 additions and 79 deletions

View File

@ -179,7 +179,7 @@ impl Command {
)
}
let header = response.into_iter().next().unwrap().seal();
let header = response.into_iter().next().unwrap().seal_slow();
let valid = match id {
BlockHashOrNumber::Hash(hash) => header.hash() == hash,

View File

@ -77,28 +77,26 @@ pub struct Header {
impl From<Header> for SealedHeader {
fn from(value: Header) -> Self {
SealedHeader::new(
RethHeader {
base_fee_per_gas: value.base_fee_per_gas.map(|v| v.0.to::<u64>()),
beneficiary: value.coinbase,
difficulty: value.difficulty.0,
extra_data: value.extra_data,
gas_limit: value.gas_limit.0.to::<u64>(),
gas_used: value.gas_used.0.to::<u64>(),
mix_hash: value.mix_hash,
nonce: value.nonce.into_uint().as_u64(),
number: value.number.0.to::<u64>(),
timestamp: value.timestamp.0.to::<u64>(),
transactions_root: value.transactions_trie,
receipts_root: value.receipt_trie,
ommers_hash: value.uncle_hash,
state_root: value.state_root,
parent_hash: value.parent_hash,
logs_bloom: value.bloom,
withdrawals_root: value.withdrawals_root,
},
value.hash,
)
let header = RethHeader {
base_fee_per_gas: value.base_fee_per_gas.map(|v| v.0.to::<u64>()),
beneficiary: value.coinbase,
difficulty: value.difficulty.0,
extra_data: value.extra_data,
gas_limit: value.gas_limit.0.to::<u64>(),
gas_used: value.gas_used.0.to::<u64>(),
mix_hash: value.mix_hash,
nonce: value.nonce.into_uint().as_u64(),
number: value.number.0.to::<u64>(),
timestamp: value.timestamp.0.to::<u64>(),
transactions_root: value.transactions_trie,
receipts_root: value.receipt_trie,
ommers_hash: value.uncle_hash,
state_root: value.state_root,
parent_hash: value.parent_hash,
logs_bloom: value.bloom,
withdrawals_root: value.withdrawals_root,
};
header.seal(value.hash)
}
}

View File

@ -352,7 +352,7 @@ pub fn validate_block_regarding_chain<PROV: HeaderProvider>(
.ok_or(Error::ParentUnknown { hash: block.parent_hash })?;
// Return parent header.
Ok(parent.seal())
Ok(parent.seal(block.parent_hash))
}
/// Full validation of block before execution.
@ -519,7 +519,7 @@ mod tests {
let ommers = Vec::new();
let body = Vec::new();
(SealedBlock { header: header.seal(), body, ommers, withdrawals: None }, parent)
(SealedBlock { header: header.seal_slow(), body, ommers, withdrawals: None }, parent)
}
#[test]
@ -610,7 +610,7 @@ mod tests {
withdrawals_root: Some(proofs::calculate_withdrawals_root(withdrawals.iter())),
..Default::default()
}
.seal(),
.seal_slow(),
withdrawals: Some(withdrawals),
..Default::default()
}

View File

@ -36,7 +36,7 @@ pub fn random_header(number: u64, parent: Option<H256>) -> SealedHeader {
parent_hash: parent.unwrap_or_default(),
..Default::default()
};
header.seal()
header.seal_slow()
}
/// Generates a random legacy [Transaction].
@ -133,9 +133,9 @@ pub fn random_block(
base_fee_per_gas: Some(rng.gen()),
..Default::default()
}
.seal(),
.seal_slow(),
body: transactions,
ommers: ommers.into_iter().map(|ommer| ommer.seal()).collect(),
ommers: ommers.into_iter().map(Header::seal_slow).collect(),
withdrawals: None,
}
}

View File

@ -168,7 +168,7 @@ impl Stream for TestDownload {
Ok(resp) => {
// Skip head and seal headers
let mut headers =
resp.1.into_iter().skip(1).map(|h| h.seal()).collect::<Vec<_>>();
resp.1.into_iter().skip(1).map(Header::seal_slow).collect::<Vec<_>>();
headers.sort_unstable_by_key(|h| h.number);
headers.into_iter().for_each(|h| this.buffer.push(h));
this.done = true;

View File

@ -144,7 +144,7 @@ where
}
// Add header to the result collection
headers.push(SealedHeader::new(header, hash));
headers.push(header.seal(hash));
// Increment current block number
current_block_num += 1;

View File

@ -170,7 +170,7 @@ where
let block = SealedBlock {
header: next_header,
body: next_body.transactions,
ommers: next_body.ommers.into_iter().map(|header| header.seal()).collect(),
ommers: next_body.ommers.into_iter().map(|h| h.seal_slow()).collect(),
withdrawals: next_body.withdrawals,
};

View File

@ -25,7 +25,7 @@ pub(crate) fn zip_blocks<'a>(
BlockResponse::Full(SealedBlock {
header: header.clone(),
body: body.transactions,
ommers: body.ommers.into_iter().map(|o| o.seal()).collect(),
ommers: body.ommers.into_iter().map(|o| o.seal_slow()).collect(),
withdrawals: body.withdrawals,
})
}

View File

@ -201,7 +201,7 @@ where
let mut validated = Vec::with_capacity(headers.len());
for parent in headers {
let parent = parent.seal();
let parent = parent.seal_slow();
// Validate that the header is the parent header of the last validated header.
if let Some(validated_header) =
@ -297,7 +297,7 @@ where
})
}
let target = headers.remove(0).seal();
let target = headers.remove(0).seal_slow();
if target.hash() != sync_target_hash {
return Err(HeadersResponseError {
@ -1008,7 +1008,7 @@ mod tests {
assert!(downloader.sync_target_request.is_some());
downloader.sync_target_request.take();
let target = SyncTarget::Gap(SealedHeader::new(Default::default(), H256::random()));
let target = SyncTarget::Gap(Header::default().seal(H256::random()));
downloader.update_sync_target(target);
assert!(downloader.sync_target_request.is_none());
assert_matches!(
@ -1032,7 +1032,7 @@ mod tests {
downloader.queued_validated_headers.push(header.clone());
let mut next = header.as_ref().clone();
next.number += 1;
downloader.update_local_head(SealedHeader::new(next, H256::random()));
downloader.update_local_head(next.seal(H256::random()));
assert!(downloader.queued_validated_headers.is_empty());
}

View File

@ -7,6 +7,5 @@ pub(crate) fn child_header(parent: &SealedHeader) -> SealedHeader {
let mut child = parent.as_ref().clone();
child.number += 1;
child.parent_hash = parent.hash_slow();
let hash = child.hash_slow();
SealedHeader::new(child, hash)
child.seal_slow()
}

View File

@ -145,12 +145,19 @@ impl Header {
self.transactions_root == EMPTY_ROOT
}
/// Calculate hash and seal the Header so that it can't be changed.
pub fn seal(self) -> SealedHeader {
let hash = self.hash_slow();
/// Seal the header with a known hash.
///
/// WARNING: This method does not perform validation whether the hash is correct.
pub fn seal(self, hash: H256) -> SealedHeader {
SealedHeader { header: self, hash }
}
/// Calculate hash and seal the Header so that it can't be changed.
pub fn seal_slow(self) -> SealedHeader {
let hash = self.hash_slow();
self.seal(hash)
}
fn header_payload_length(&self) -> usize {
let mut length = 0;
length += self.parent_hash.length();
@ -290,21 +297,14 @@ impl proptest::arbitrary::Arbitrary for SealedHeader {
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
use proptest::prelude::{any, Strategy};
any::<(Header, BlockHash)>()
.prop_map(move |(header, _)| {
let hash = header.hash_slow();
SealedHeader { header, hash }
})
.boxed()
any::<(Header, BlockHash)>().prop_map(move |(header, _)| header.seal_slow()).boxed()
}
}
#[cfg(any(test, feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for SealedHeader {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
let header = Header::arbitrary(u)?;
let hash = header.hash_slow();
Ok(SealedHeader { header, hash })
Ok(Header::arbitrary(u)?.seal_slow())
}
}
@ -323,19 +323,16 @@ impl From<Block<EthersH256>> for SealedHeader {
base_fee_per_gas: block.base_fee_per_gas.map(|fee| fee.as_u64()),
..Default::default()
};
let hash = match block.hash {
Some(hash) => hash.0.into(),
None => header.hash_slow(),
};
SealedHeader::new(header, hash)
match block.hash {
Some(hash) => header.seal(hash.0.into()),
None => header.seal_slow(),
}
}
}
impl Default for SealedHeader {
fn default() -> Self {
let header = Header::default();
let hash = header.hash_slow();
Self { header, hash }
Header::default().seal_slow()
}
}
@ -351,8 +348,7 @@ impl Decodable for SealedHeader {
// TODO make this more performant, we are not encoding again for a hash.
// But i dont know how much of buf is the header or if takeing rlp::Header will
// going to consume those buf bytes.
let hash = header.hash_slow();
Ok(SealedHeader { header, hash })
Ok(header.seal_slow())
}
}
@ -371,13 +367,6 @@ impl Deref for SealedHeader {
}
impl SealedHeader {
/// Construct a new sealed header.
///
/// Applicable when hash is known from the database provided it's not corrupted.
pub fn new(header: Header, hash: H256) -> Self {
Self { header, hash }
}
/// Extract raw header that can be modified.
pub fn unseal(self) -> Header {
self.header

View File

@ -108,8 +108,8 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> EngineApi<Client> {
ommers_hash: EMPTY_LIST_HASH,
difficulty: Default::default(),
nonce: Default::default(),
};
let header = header.seal();
}
.seal_slow();
if payload.block_hash != header.hash() {
return Err(EngineApiError::PayloadBlockHash {
@ -340,9 +340,9 @@ mod tests {
transformed.header.ommers_hash =
proofs::calculate_ommers_root(transformed.ommers.iter());
SealedBlock {
header: transformed.header.seal(),
header: transformed.header.seal_slow(),
body: transformed.body,
ommers: transformed.ommers.into_iter().map(Header::seal).collect(),
ommers: transformed.ommers.into_iter().map(Header::seal_slow).collect(),
withdrawals: transformed.withdrawals,
}
}

View File

@ -103,7 +103,7 @@ async fn init_geth() -> (CliqueGethInstance, ChainSpec) {
.into();
let remote_genesis = SealedHeader::from(clique.provider.remote_genesis_block().await.unwrap());
let local_genesis = chainspec.genesis_header().seal();
let local_genesis = chainspec.genesis_header().seal(chainspec.genesis_hash());
assert_eq!(local_genesis, remote_genesis, "genesis blocks should match, we computed {local_genesis:#?} but geth computed {remote_genesis:#?}");
// === create many blocks ===

View File

@ -765,7 +765,7 @@ mod tests {
let (num, hash) = entry?;
let (_, header) =
header_cursor.seek_exact(num)?.expect("missing header");
headers.push(SealedHeader::new(header, hash));
headers.push(header.seal(hash));
}
Ok(headers)
})??);
@ -792,7 +792,7 @@ mod tests {
response.push(BlockResponse::Full(SealedBlock {
header,
body: body.transactions,
ommers: body.ommers.into_iter().map(|h| h.seal()).collect(),
ommers: body.ommers.into_iter().map(|h| h.seal_slow()).collect(),
withdrawals: body.withdrawals,
}));
}

View File

@ -85,7 +85,7 @@ where
let (_, head) = header_cursor
.seek_exact(head_num)?
.ok_or(ProviderError::Header { number: head_num })?;
let local_head = SealedHeader::new(head, head_hash);
let local_head = head.seal(head_hash);
// Look up the next header
let next_header = cursor
@ -94,7 +94,7 @@ where
let (_, next) = header_cursor
.seek_exact(next_num)?
.ok_or(ProviderError::Header { number: next_num })?;
Ok(SealedHeader::new(next, next_hash))
Ok(next.seal(next_hash))
})
.transpose()?;
@ -372,7 +372,7 @@ mod tests {
// validate the header
let header = tx.get::<tables::Headers>(block_num)?;
assert!(header.is_some());
let header = header.unwrap().seal();
let header = header.unwrap().seal_slow();
assert_eq!(header.hash(), hash);
}
Ok(())

View File

@ -282,7 +282,7 @@ mod tests {
random_block(stage_progress, None, Some(0), None);
let mut header = header.unseal();
header.state_root = self.generate_initial_trie(&accounts)?;
let sealed_head = SealedBlock { header: header.seal(), body, ommers, withdrawals };
let sealed_head = SealedBlock { header: header.seal_slow(), body, ommers, withdrawals };
let head_hash = sealed_head.hash();
let mut blocks = vec![sealed_head];