From b048e231afc46916dc7d67aab292bdb0724f2906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9COgnyan?= Date: Wed, 26 Feb 2025 14:27:58 +0200 Subject: [PATCH] feat: add block header by number content value --- .../src/types/content_value/history.rs | 2 + .../src/types/content_value/history_new.rs | 2 + crates/metrics/src/history_migration.rs | 3 +- .../history/src/storage_migration.rs | 132 +++++++++++++----- 4 files changed, 104 insertions(+), 35 deletions(-) diff --git a/crates/ethportal-api/src/types/content_value/history.rs b/crates/ethportal-api/src/types/content_value/history.rs index 4be2d505d..41ee30154 100644 --- a/crates/ethportal-api/src/types/content_value/history.rs +++ b/crates/ethportal-api/src/types/content_value/history.rs @@ -16,6 +16,7 @@ pub enum HistoryContentValue { BlockHeaderWithProof(HeaderWithProof), BlockBody(BlockBody), Receipts(Receipts), + BlockHeaderByNumber(HeaderWithProof), } impl ContentValue for HistoryContentValue { @@ -26,6 +27,7 @@ impl ContentValue for HistoryContentValue { Self::BlockHeaderWithProof(value) => value.as_ssz_bytes().into(), Self::BlockBody(value) => value.as_ssz_bytes().into(), Self::Receipts(value) => value.as_ssz_bytes().into(), + Self::BlockHeaderByNumber(value) => value.as_ssz_bytes().into(), } } diff --git a/crates/ethportal-api/src/types/content_value/history_new.rs b/crates/ethportal-api/src/types/content_value/history_new.rs index 1eb528d08..adce1f0cd 100644 --- a/crates/ethportal-api/src/types/content_value/history_new.rs +++ b/crates/ethportal-api/src/types/content_value/history_new.rs @@ -16,6 +16,7 @@ pub enum HistoryContentValue { BlockHeaderWithProof(HeaderWithProof), BlockBody(BlockBody), Receipts(Receipts), + BlockHeaderByNumber(HeaderWithProof), } impl ContentValue for HistoryContentValue { @@ -26,6 +27,7 @@ impl ContentValue for HistoryContentValue { Self::BlockHeaderWithProof(value) => value.as_ssz_bytes().into(), Self::BlockBody(value) => value.as_ssz_bytes().into(), Self::Receipts(value) => value.as_ssz_bytes().into(), + Self::BlockHeaderByNumber(value) => value.as_ssz_bytes().into(), } } diff --git a/crates/metrics/src/history_migration.rs b/crates/metrics/src/history_migration.rs index 435e5c80a..ae6a76f77 100644 --- a/crates/metrics/src/history_migration.rs +++ b/crates/metrics/src/history_migration.rs @@ -60,7 +60,8 @@ impl HistoryMigrationMetrics { pub fn get_content_value_label(&self, content_value: &HistoryContentValue) -> &str { match content_value { - HistoryContentValue::BlockHeaderWithProof(header_with_proof) => { + HistoryContentValue::BlockHeaderWithProof(header_with_proof) + | HistoryContentValue::BlockHeaderByNumber(header_with_proof) => { match &header_with_proof.proof { BlockHeaderProof::None(_) => "header_no_proof", BlockHeaderProof::PreMergeAccumulatorProof(_) => "header_pre_merge_accumulator", diff --git a/crates/subnetworks/history/src/storage_migration.rs b/crates/subnetworks/history/src/storage_migration.rs index 9f4d49f05..b2de4aa4a 100644 --- a/crates/subnetworks/history/src/storage_migration.rs +++ b/crates/subnetworks/history/src/storage_migration.rs @@ -5,7 +5,9 @@ use ethportal_api::{ history_new::HistoryContentValue as NewHistoryContentValue, }, execution::{ - header_with_proof::BlockHeaderProof as OldBlockHeaderProof, + header_with_proof::{ + BlockHeaderProof as OldBlockHeaderProof, HeaderWithProof as OldHeaderWithProof, + }, header_with_proof_new::{ BlockHeaderProof, BlockProofHistoricalHashesAccumulator, HeaderWithProof, }, @@ -157,30 +159,7 @@ fn convert_content_value( ) -> Option { match old_content_value { OldHistoryContentValue::BlockHeaderWithProof(old_header_with_proof) => { - let proof = match old_header_with_proof.proof { - OldBlockHeaderProof::None(_) => return None, - OldBlockHeaderProof::PreMergeAccumulatorProof(pre_merge_accumulator_proof) => { - let proof = BlockProofHistoricalHashesAccumulator::new( - pre_merge_accumulator_proof.proof.to_vec(), - ) - .expect("[B256; 15] should convert to FixedVector"); - BlockHeaderProof::HistoricalHashes(proof) - } - OldBlockHeaderProof::HistoricalRootsBlockProof(_) => { - warn!( - content_key = content_key.to_hex(), - "Unexpected HistoricalRootsBlockProof" - ); - return None; - } - OldBlockHeaderProof::HistoricalSummariesBlockProof(_) => { - warn!( - content_key = content_key.to_hex(), - "Unexpected HistoricalSummariesBlockProof" - ); - return None; - } - }; + let proof = get_header_proof(content_key, old_header_with_proof.clone())?; let new_content_value = NewHistoryContentValue::BlockHeaderWithProof(HeaderWithProof { header: old_header_with_proof.header, proof, @@ -191,9 +170,48 @@ fn convert_content_value( // TODO: consider whether to filter post-merge bodies and receipts Some(old_content_value.encode()) } + OldHistoryContentValue::BlockHeaderByNumber(old_header_with_proof) => { + let proof = get_header_proof(content_key, old_header_with_proof.clone())?; + let new_content_value = NewHistoryContentValue::BlockHeaderByNumber(HeaderWithProof { + header: old_header_with_proof.header, + proof, + }); + Some(new_content_value.encode()) + } } } +fn get_header_proof( + content_key: &HistoryContentKey, + old_header_with_proof: OldHeaderWithProof, +) -> Option { + let proof = match old_header_with_proof.proof { + OldBlockHeaderProof::None(_) => return None, + OldBlockHeaderProof::PreMergeAccumulatorProof(pre_merge_accumulator_proof) => { + let proof = BlockProofHistoricalHashesAccumulator::new( + pre_merge_accumulator_proof.proof.to_vec(), + ) + .expect("[B256; 15] should convert to FixedVector"); + BlockHeaderProof::HistoricalHashes(proof) + } + OldBlockHeaderProof::HistoricalRootsBlockProof(_) => { + warn!( + content_key = content_key.to_hex(), + "Unexpected HistoricalRootsBlockProof" + ); + return None; + } + OldBlockHeaderProof::HistoricalSummariesBlockProof(_) => { + warn!( + content_key = content_key.to_hex(), + "Unexpected HistoricalSummariesBlockProof" + ); + return None; + } + }; + Some(proof) +} + #[cfg(test)] mod tests { use std::{collections::HashMap, fs, str::FromStr}; @@ -312,6 +330,21 @@ mod tests { Ok(()) } + fn header_by_hash_to_number( + old_content_value: RawContentValue, + new_content_value: Option, + ) -> (HistoryContentKey, RawContentValue, Option) { + let block_number = OldHeaderWithProof::from_ssz_bytes(&old_content_value) + .unwrap() + .header + .number; + ( + HistoryContentKey::new_block_header_by_number(block_number), + old_content_value, + new_content_value, + ) + } + // Fixtures /// Migration shouldn't crash with undecodable content value. @@ -361,15 +394,7 @@ mod tests { headers_by_hash_with_proof_1000001_1000010 .into_iter() .map(|(_content_key, old_content_value, new_content_value)| { - let block_number = OldHeaderWithProof::from_ssz_bytes(&old_content_value) - .unwrap() - .header - .number; - ( - HistoryContentKey::new_block_header_by_number(block_number), - old_content_value, - new_content_value, - ) + header_by_hash_to_number(old_content_value, new_content_value) }) .collect() } @@ -410,6 +435,33 @@ mod tests { (content_key, content_value, None) } + #[fixture] + fn header_by_number_without_proof_15600000( + header_by_hash_without_proof_15600000: MigrationContentItem, + ) -> MigrationContentItem { + let (_content_key, old_content_value, new_content_value) = + header_by_hash_without_proof_15600000; + header_by_hash_to_number(old_content_value, new_content_value) + } + + #[fixture] + fn header_by_number_without_proof_17510000( + header_by_hash_without_proof_17510000: MigrationContentItem, + ) -> MigrationContentItem { + let (_content_key, old_content_value, new_content_value) = + header_by_hash_without_proof_17510000; + header_by_hash_to_number(old_content_value, new_content_value) + } + + #[fixture] + fn header_by_number_without_proof_19463337( + header_by_hash_without_proof_19463337: MigrationContentItem, + ) -> MigrationContentItem { + let (_content_key, old_content_value, new_content_value) = + header_by_hash_without_proof_19463337; + header_by_hash_to_number(old_content_value, new_content_value) + } + #[fixture] fn block_body_14764013() -> MigrationContentItem { let content_item: ContentItem = serde_yaml::from_str( @@ -461,11 +513,17 @@ mod tests { header_by_hash_without_proof_15600000: MigrationContentItem, header_by_hash_without_proof_17510000: MigrationContentItem, header_by_hash_without_proof_19463337: MigrationContentItem, + header_by_number_without_proof_15600000: MigrationContentItem, + header_by_number_without_proof_17510000: MigrationContentItem, + header_by_number_without_proof_19463337: MigrationContentItem, ) -> anyhow::Result<()> { verify_migration(&[ header_by_hash_without_proof_15600000, header_by_hash_without_proof_17510000, header_by_hash_without_proof_19463337, + header_by_number_without_proof_15600000, + header_by_number_without_proof_17510000, + header_by_number_without_proof_19463337, ])?; Ok(()) } @@ -491,6 +549,9 @@ mod tests { header_by_hash_without_proof_15600000: MigrationContentItem, header_by_hash_without_proof_17510000: MigrationContentItem, header_by_hash_without_proof_19463337: MigrationContentItem, + header_by_number_without_proof_15600000: MigrationContentItem, + header_by_number_without_proof_17510000: MigrationContentItem, + header_by_number_without_proof_19463337: MigrationContentItem, block_body_14764013: MigrationContentItem, block_receipt_14764013: MigrationContentItem, ) -> anyhow::Result<()> { @@ -501,6 +562,9 @@ mod tests { content.push(header_by_hash_without_proof_15600000); content.push(header_by_hash_without_proof_17510000); content.push(header_by_hash_without_proof_19463337); + content.push(header_by_number_without_proof_15600000); + content.push(header_by_number_without_proof_17510000); + content.push(header_by_number_without_proof_19463337); content.push(block_body_14764013); content.push(block_receipt_14764013); content.shuffle(&mut rand::thread_rng());