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_types::{
15    blockchain::{BlockchainReadRequest, BlockchainResponse},
16    Chain,
17};
18
19use cuprate_fast_sync::FAST_SYNC_BATCH_LEN;
20
21async fn read_batch(
22    handle: &mut BlockchainReadHandle,
23    height_from: usize,
24) -> DbResult<Vec<[u8; 32]>> {
25    let request = BlockchainReadRequest::BlockHashInRange(
26        height_from..(height_from + FAST_SYNC_BATCH_LEN),
27        Chain::Main,
28    );
29    let response_channel = handle.ready().await?.call(request);
30    let response = response_channel.await?;
31
32    let BlockchainResponse::BlockHashInRange(block_ids) = response else {
33        unreachable!()
34    };
35
36    Ok(block_ids)
37}
38
39#[derive(Parser)]
40#[command(version, about, long_about = None)]
41struct Args {
42    #[arg(long)]
43    height: usize,
44}
45
46#[tokio::main]
47async fn main() {
48    let args = Args::parse();
49    let height_target = args.height;
50
51    let config = ConfigBuilder::new().build();
52
53    let (mut read_handle, _, _) = cuprate_blockchain::service::init(config).unwrap();
54
55    let mut hashes_of_hashes = Vec::new();
56
57    let mut height = 0_usize;
58
59    while (height + FAST_SYNC_BATCH_LEN) < height_target {
60        if let Ok(block_ids) = read_batch(&mut read_handle, height).await {
61            let hash = hash_of_hashes(block_ids.as_slice());
62            hashes_of_hashes.push(hash);
63        } else {
64            println!("Failed to read next batch from database");
65            break;
66        }
67        height += FAST_SYNC_BATCH_LEN;
68
69        println!("height: {height}");
70    }
71
72    drop(read_handle);
73
74    write("fast_sync_hashes.bin", hashes_of_hashes.concat().as_slice())
75        .expect("Could not write file");
76
77    println!("Generated hashes up to block height {height}");
78}
79
80pub fn hash_of_hashes(hashes: &[[u8; 32]]) -> [u8; 32] {
81    blake3::hash(hashes.concat().as_slice()).into()
82}