Skip to content

Commit

Permalink
feat(block-strider): use safe method BlockStuff::deserialize_checked …
Browse files Browse the repository at this point in the history
…to get Block
  • Loading branch information
pashinov committed Apr 24, 2024
1 parent d963e46 commit b90a341
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 53 deletions.
4 changes: 2 additions & 2 deletions core/src/block_strider/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())))
Expand Down Expand Up @@ -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);
Expand Down
26 changes: 17 additions & 9 deletions core/tests/block_strider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}

Expand Down Expand Up @@ -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());
}
}
}

Expand Down
23 changes: 13 additions & 10 deletions core/tests/common/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<BlockId, ArchiveDataEntry>,
Expand All @@ -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,
}
Expand All @@ -45,11 +48,11 @@ impl Archive {

#[derive(Default)]
pub struct ArchiveDataEntry {
pub block: Option<Block>,
pub proof: Option<BlockProof>,
pub block: Option<WithArchiveData<Block>>,
pub proof: Option<WithArchiveData<BlockProof>>,
}

pub(crate) fn deserialize_block(id: &BlockId, data: &[u8]) -> Result<Block, ArchiveDataError> {
pub fn deserialize_block(id: &BlockId, data: &[u8]) -> Result<Block, ArchiveDataError> {
let file_hash = sha2::Sha256::digest(data);
if id.file_hash.as_slice() != file_hash.as_slice() {
Err(ArchiveDataError::InvalidFileHash(id.as_short_id()))
Expand All @@ -64,7 +67,7 @@ pub(crate) fn deserialize_block(id: &BlockId, data: &[u8]) -> Result<Block, Arch
}
}

pub(crate) fn deserialize_block_proof(
pub fn deserialize_block_proof(
block_id: &BlockId,
data: &[u8],
is_link: bool,
Expand Down
42 changes: 19 additions & 23 deletions core/tests/common/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::sync::Arc;

use anyhow::{Context, Result};
use bytesize::ByteSize;
use everscale_types::models::BlockId;
use tempfile::TempDir;
use tycho_block_util::archive::ArchiveData;
use tycho_block_util::block::{BlockProofStuff, BlockProofStuffAug, BlockStuff, BlockStuffAug};
use tycho_storage::{BlockMetaData, Db, DbOptions, Storage};

Expand Down Expand Up @@ -31,19 +31,6 @@ pub(crate) async fn init_empty_storage() -> Result<(Arc<Storage>, TempDir)> {
Ok((storage, tmp_dir))
}

pub(crate) fn get_block_ids() -> Result<Vec<BlockId>> {
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<archive::Archive> {
let data = include_bytes!("../../tests/data/00001");
let archive = archive::Archive::new(data)?;
Expand Down Expand Up @@ -78,9 +65,15 @@ pub(crate) async fn init_storage() -> Result<(Arc<Storage>, 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()
Expand All @@ -102,18 +95,21 @@ pub(crate) async fn init_storage() -> Result<(Arc<Storage>, 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()
Expand Down
25 changes: 16 additions & 9 deletions core/tests/overlay_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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"),
}
}
}
}
Expand Down

0 comments on commit b90a341

Please sign in to comment.