create_fs_file/
create.rs
1#![expect(
2 unused_crate_dependencies,
3 reason = "binary shares same Cargo.toml as library"
4)]
5
6use std::fs::write;
7
8use clap::Parser;
9use tower::{Service, ServiceExt};
10
11use cuprate_blockchain::{
12 config::ConfigBuilder, cuprate_database::DbResult, service::BlockchainReadHandle,
13};
14use cuprate_hex::Hex;
15use cuprate_types::{
16 blockchain::{BlockchainReadRequest, BlockchainResponse},
17 Chain,
18};
19
20use cuprate_fast_sync::FAST_SYNC_BATCH_LEN;
21
22async fn read_batch(
23 handle: &mut BlockchainReadHandle,
24 height_from: usize,
25) -> DbResult<Vec<[u8; 32]>> {
26 let request = BlockchainReadRequest::BlockHashInRange(
27 height_from..(height_from + FAST_SYNC_BATCH_LEN),
28 Chain::Main,
29 );
30 let response_channel = handle.ready().await?.call(request);
31 let response = response_channel.await?;
32
33 let BlockchainResponse::BlockHashInRange(block_ids) = response else {
34 unreachable!()
35 };
36
37 Ok(block_ids)
38}
39
40#[derive(Parser)]
41#[command(version, about, long_about = None)]
42struct Args {
43 #[arg(long)]
44 height: usize,
45}
46
47#[tokio::main]
48async fn main() {
49 let args = Args::parse();
50 let height_target = args.height;
51
52 let config = ConfigBuilder::new().build();
53
54 let (mut read_handle, _, _) = cuprate_blockchain::service::init(config).unwrap();
55
56 let mut hashes_of_hashes = Vec::new();
57
58 let mut height = 0_usize;
59
60 while (height + FAST_SYNC_BATCH_LEN) < height_target {
61 if let Ok(block_ids) = read_batch(&mut read_handle, height).await {
62 let hash = hash_of_hashes(block_ids.as_slice());
63 hashes_of_hashes.push(Hex(hash));
64 } else {
65 println!("Failed to read next batch from database");
66 break;
67 }
68 height += FAST_SYNC_BATCH_LEN;
69
70 println!("height: {height}");
71 }
72
73 drop(read_handle);
74
75 write(
76 "fast_sync_hashes.json",
77 serde_json::to_string_pretty(&hashes_of_hashes).unwrap(),
78 )
79 .unwrap();
80
81 println!("Generated hashes up to block height {height}");
82}
83
84pub fn hash_of_hashes(hashes: &[[u8; 32]]) -> [u8; 32] {
85 blake3::hash(hashes.concat().as_slice()).into()
86}