Contractless/src/records/unpack_block/unpack_header.rs

53 lines
1.6 KiB
Rust

use crate::blocks::block::{VrfBlock, VRF_BLOCK_BYTES};
use crate::common::network_paths_and_settings::block_extension_and_paths;
use crate::AsyncReadExt;
use crate::File;
use crate::PathBuf;
pub async fn load_block_header(block_number: u32) -> Result<VrfBlock, String> {
// Header-only loads avoid reading the full block when only chain metadata
// is needed.
let (
_network_name,
_padded_base_coin,
block_ext,
_torrent_path,
_wallet_path,
block_path,
_db_path,
_balance_path,
_log_path,
) = block_extension_and_paths();
let file_name = PathBuf::from(block_path)
.join(format!("{block_number}.{block_ext}"))
.to_string_lossy()
.into_owned();
let file = match File::open(&file_name).await {
Ok(file) => file,
Err(err) => {
return Err(format!(
"Error opening block file for height {block_number}: {err:?}"
));
}
};
let mut binary_data = Vec::with_capacity(VRF_BLOCK_BYTES);
// Only read the fixed VrfBlock prefix from the block file.
if let Err(err) = file
.take(VRF_BLOCK_BYTES as u64)
.read_to_end(&mut binary_data)
.await
{
return Err(format!(
"Error reading block header for height {block_number}: {err:?}"
));
}
// The stored header format is the same VrfBlock prefix used at the
// beginning of every block file.
match VrfBlock::from_bytes(&binary_data).await {
Ok(block) => Ok(block),
Err(err) => Err(format!("Error parsing block: {err:?}")),
}
}