1use std::sync::Arc;
5
6use futures::FutureExt;
7use tokio::sync::{mpsc, Notify};
8use tower::{BoxError, Service, ServiceExt};
9
10use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle};
11use cuprate_consensus::{generate_genesis_block, BlockchainContextService, ContextConfig};
12use cuprate_cryptonight::cryptonight_hash_v0;
13use cuprate_p2p::{block_downloader::BlockDownloaderConfig, NetworkInterface};
14use cuprate_p2p_core::{ClearNet, Network};
15use cuprate_types::{
16 blockchain::{BlockchainReadRequest, BlockchainWriteRequest},
17 VerifiedBlockInformation,
18};
19
20use crate::constants::PANIC_CRITICAL_SERVICE_ERROR;
21
22mod chain_service;
23mod fast_sync;
24pub mod interface;
25mod manager;
26mod syncer;
27mod types;
28
29pub use fast_sync::set_fast_sync_hashes;
30pub use manager::init_blockchain_manager;
31pub use types::ConsensusBlockchainReadHandle;
32
33pub async fn check_add_genesis(
35 blockchain_read_handle: &mut BlockchainReadHandle,
36 blockchain_write_handle: &mut BlockchainWriteHandle,
37 network: Network,
38) {
39 if blockchain_read_handle
41 .ready()
42 .await
43 .expect(PANIC_CRITICAL_SERVICE_ERROR)
44 .call(BlockchainReadRequest::ChainHeight)
45 .await
46 .is_ok()
47 {
48 return;
49 }
50
51 let genesis = generate_genesis_block(network);
52
53 assert_eq!(genesis.miner_transaction.prefix().outputs.len(), 1);
54 assert!(genesis.transactions.is_empty());
55
56 blockchain_write_handle
57 .ready()
58 .await
59 .expect(PANIC_CRITICAL_SERVICE_ERROR)
60 .call(BlockchainWriteRequest::WriteBlock(
61 VerifiedBlockInformation {
62 block_blob: genesis.serialize(),
63 txs: vec![],
64 block_hash: genesis.hash(),
65 pow_hash: cryptonight_hash_v0(&genesis.serialize_pow_hash()),
66 height: 0,
67 generated_coins: genesis.miner_transaction.prefix().outputs[0]
68 .amount
69 .unwrap(),
70 weight: genesis.miner_transaction.weight(),
71 long_term_weight: genesis.miner_transaction.weight(),
72 cumulative_difficulty: 1,
73 block: genesis,
74 },
75 ))
76 .await
77 .expect(PANIC_CRITICAL_SERVICE_ERROR);
78}
79
80pub async fn init_consensus(
82 blockchain_read_handle: BlockchainReadHandle,
83 context_config: ContextConfig,
84) -> Result<BlockchainContextService, BoxError> {
85 let read_handle = ConsensusBlockchainReadHandle::new(blockchain_read_handle, BoxError::from);
86
87 let ctx_service =
88 cuprate_consensus::initialize_blockchain_context(context_config, read_handle.clone())
89 .await?;
90
91 Ok(ctx_service)
92}