diff --git a/core/src/block_strider/provider.rs b/core/src/block_strider/provider.rs index 3ab1799f0..7ac728d67 100644 --- a/core/src/block_strider/provider.rs +++ b/core/src/block_strider/provider.rs @@ -102,7 +102,7 @@ impl BlockProvider for BlockchainClient { BlockFull::Empty => unreachable!(), }; - match BlockStuff::deserialize(block_id, data) { + match BlockStuff::deserialize_checked(block_id, data) { Ok(block) => { res.mark_response(true); Some(Ok(BlockStuffAug::new(block, data.clone()))) @@ -149,7 +149,7 @@ impl BlockProvider for BlockchainClient { block_id, block: data, .. - } => match BlockStuff::deserialize(*block_id, data) { + } => match BlockStuff::deserialize_checked(*block_id, data) { Ok(block) => Some(Ok(BlockStuffAug::new(block, data.clone()))), Err(e) => { res.mark_response(false); diff --git a/core/tests/block_strider.rs b/core/tests/block_strider.rs index c65424d9f..bfe176361 100644 --- a/core/tests/block_strider.rs +++ b/core/tests/block_strider.rs @@ -17,13 +17,18 @@ async fn storage_block_strider() -> anyhow::Result<()> { let (storage, tmp_dir) = common::storage::init_storage().await?; - let block_ids = common::storage::get_block_ids()?; - for block_id in block_ids { + let archive = common::storage::get_archive()?; + for (block_id, data) in archive.blocks { if block_id.shard.is_masterchain() { let block = storage.get_block(&block_id).await; - assert!(block.is_some()); - assert_eq!(&block_id, block.unwrap()?.id()); + + if let Some(block) = block { + let block = block?; + + assert_eq!(&block_id, block.id()); + assert_eq!(&data.block.unwrap().data, block.block()); + } } } @@ -116,15 +121,18 @@ async fn overlay_block_strider() -> anyhow::Result<()> { Default::default(), ); - let block_ids = common::storage::get_block_ids()?; - for block_id in block_ids { + let archive = common::storage::get_archive()?; + for (block_id, data) in archive.blocks { if block_id.shard.is_masterchain() { let block = client.get_block(&block_id).await; - assert!(block.is_some()); - assert_eq!(&block_id, block.unwrap()?.id()); - break; + if let Some(block) = block { + let block = block?; + + assert_eq!(&block_id, block.id()); + assert_eq!(&data.block.unwrap().data, block.block()); + } } } diff --git a/core/tests/common/archive.rs b/core/tests/common/archive.rs index c5a6fcf60..598f63dba 100644 --- a/core/tests/common/archive.rs +++ b/core/tests/common/archive.rs @@ -7,7 +7,7 @@ use everscale_types::cell::Load; use everscale_types::models::{Block, BlockId, BlockIdShort, BlockProof}; use sha2::Digest; -use tycho_block_util::archive::{ArchiveEntryId, ArchiveReader}; +use tycho_block_util::archive::{ArchiveEntryId, ArchiveReader, WithArchiveData}; pub struct Archive { pub blocks: BTreeMap, @@ -21,20 +21,23 @@ impl Archive { blocks: Default::default(), }; - for data in reader { - let entry = data?; + for entry_data in reader { + let entry = entry_data?; match ArchiveEntryId::from_filename(entry.name)? { ArchiveEntryId::Block(id) => { let block = deserialize_block(&id, entry.data)?; - res.blocks.entry(id).or_default().block = Some(block); + res.blocks.entry(id).or_default().block = + Some(WithArchiveData::new(block, entry.data.to_vec())); } ArchiveEntryId::Proof(id) if id.shard.workchain() == -1 => { let proof = deserialize_block_proof(&id, entry.data, false)?; - res.blocks.entry(id).or_default().proof = Some(proof); + res.blocks.entry(id).or_default().proof = + Some(WithArchiveData::new(proof, entry.data.to_vec())); } ArchiveEntryId::ProofLink(id) if id.shard.workchain() != -1 => { let proof = deserialize_block_proof(&id, entry.data, true)?; - res.blocks.entry(id).or_default().proof = Some(proof); + res.blocks.entry(id).or_default().proof = + Some(WithArchiveData::new(proof, entry.data.to_vec())); } _ => continue, } @@ -45,11 +48,11 @@ impl Archive { #[derive(Default)] pub struct ArchiveDataEntry { - pub block: Option, - pub proof: Option, + pub block: Option>, + pub proof: Option>, } -pub(crate) fn deserialize_block(id: &BlockId, data: &[u8]) -> Result { +pub fn deserialize_block(id: &BlockId, data: &[u8]) -> Result { let file_hash = sha2::Sha256::digest(data); if id.file_hash.as_slice() != file_hash.as_slice() { Err(ArchiveDataError::InvalidFileHash(id.as_short_id())) @@ -64,7 +67,7 @@ pub(crate) fn deserialize_block(id: &BlockId, data: &[u8]) -> Result Result<(Arc, TempDir)> { Ok((storage, tmp_dir)) } -pub(crate) fn get_block_ids() -> Result> { - let data = include_bytes!("../../tests/data/00001"); - let archive = archive::Archive::new(data)?; - - let block_ids = archive - .blocks - .into_iter() - .map(|(block_id, _)| block_id) - .collect(); - - Ok(block_ids) -} - pub(crate) fn get_archive() -> Result { let data = include_bytes!("../../tests/data/00001"); let archive = archive::Archive::new(data)?; @@ -78,9 +65,15 @@ pub(crate) async fn init_storage() -> Result<(Arc, TempDir)> { .context("Failed to process master ref")?, }; - let block_data = everscale_types::boc::BocRepr::encode(&block)?; - let block_stuff = - BlockStuffAug::new(BlockStuff::with_block(block_id, block.clone()), block_data); + let block_archive_data = match block.archive_data { + ArchiveData::New(archive_data) => archive_data, + ArchiveData::Existing => anyhow::bail!("invalid block archive data"), + }; + + let block_stuff = BlockStuffAug::new( + BlockStuff::with_block(block_id, block.data.clone()), + block_archive_data, + ); let block_result = storage .block_storage() @@ -102,18 +95,21 @@ pub(crate) async fn init_storage() -> Result<(Arc, TempDir)> { .await?; assert_eq!(bs.id(), &block_id); - assert_eq!(bs.block(), &block); + assert_eq!(bs.block(), &block.data); + + let proof_archive_data = match proof.archive_data { + ArchiveData::New(archive_data) => archive_data, + ArchiveData::Existing => anyhow::bail!("invalid proof archive data"), + }; let block_proof = BlockProofStuff::deserialize( block_id, - everscale_types::boc::BocRepr::encode(&proof)?.as_slice(), + everscale_types::boc::BocRepr::encode(&proof.data)?.as_slice(), false, )?; - let block_proof_with_data = BlockProofStuffAug::new( - block_proof.clone(), - everscale_types::boc::BocRepr::encode(&proof)?, - ); + let block_proof_with_data = + BlockProofStuffAug::new(block_proof.clone(), proof_archive_data); let handle = storage .block_storage() diff --git a/core/tests/overlay_server.rs b/core/tests/overlay_server.rs index 5d85d9977..a3223b813 100644 --- a/core/tests/overlay_server.rs +++ b/core/tests/overlay_server.rs @@ -12,6 +12,8 @@ use tycho_core::overlay_server::DEFAULT_ERROR_CODE; use tycho_core::proto::overlay::{BlockFull, KeyBlockIds, PersistentStatePart}; use tycho_network::PeerId; +use crate::common::archive::*; + mod common; #[tokio::test] @@ -243,24 +245,29 @@ async fn overlay_server_blocks() -> Result<()> { ); let archive = common::storage::get_archive()?; - for (block_id, block) in archive.blocks { + for (block_id, archive_data) in archive.blocks { if block_id.shard.is_masterchain() { let result = client.get_block_full(block_id.clone()).await; assert!(result.is_ok()); if let Ok(response) = &result { - let proof = everscale_types::boc::BocRepr::encode(block.proof.unwrap())?.into(); - let block = everscale_types::boc::BocRepr::encode(block.block.unwrap())?.into(); - - assert_eq!( - response.data(), - &BlockFull::Found { + match response.data() { + BlockFull::Found { block_id, block, proof, - is_link: false, + .. + } => { + let block = deserialize_block(block_id, block)?; + assert_eq!(block, archive_data.block.unwrap().data); + + let proof = deserialize_block_proof(block_id, proof, false)?; + let archive_proof = archive_data.proof.unwrap(); + assert_eq!(proof.proof_for, archive_proof.data.proof_for); + assert_eq!(proof.root, archive_proof.data.root); } - ); + _ => anyhow::bail!("block not found"), + } } } }