sc_consensus_nakamoto/
verifier.rs1use crate::chain_params::ChainParams;
2use crate::verification::HeaderVerifier;
3use sc_client_api::{AuxStore, HeaderBackend};
4use sc_consensus::{BlockImportParams, Verifier};
5use sp_runtime::SaturatedConversion;
6use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
7use std::sync::Arc;
8use subcoin_primitives::{extract_bitcoin_block_hash, extract_bitcoin_block_header};
9
10pub struct SubstrateImportQueueVerifier<Block, Client> {
14 client: Arc<Client>,
15 btc_header_verifier: HeaderVerifier<Block, Client>,
16}
17
18impl<Block, Client> SubstrateImportQueueVerifier<Block, Client> {
19 pub fn new(client: Arc<Client>, network: bitcoin::Network) -> Self {
21 Self {
22 client: client.clone(),
23 btc_header_verifier: HeaderVerifier::new(client, ChainParams::new(network)),
24 }
25 }
26}
27
28#[async_trait::async_trait]
29impl<Block, Client> Verifier<Block> for SubstrateImportQueueVerifier<Block, Client>
30where
31 Block: BlockT,
32 Client: HeaderBackend<Block> + AuxStore,
33{
34 async fn verify(
35 &self,
36 mut block_import_params: BlockImportParams<Block>,
37 ) -> Result<BlockImportParams<Block>, String> {
38 let substrate_header = &block_import_params.header;
39
40 let btc_header = extract_bitcoin_block_header::<Block>(substrate_header)
41 .map_err(|err| format!("Failed to extract bitcoin header: {err:?}"))?;
42
43 self.btc_header_verifier
44 .verify(&btc_header)
45 .map_err(|err| format!("Invalid bitcoin header: {err:?}"))?;
46
47 let (chain_work, fork_choice) = crate::block_import::calculate_chain_work_and_fork_choice(
48 &self.client,
49 &btc_header,
50 (*substrate_header.number()).saturated_into::<u32>(),
51 )
52 .map_err(|err| format!("Failed to calculate cumulative work: {err:?}"))?;
53
54 block_import_params.fork_choice = Some(fork_choice);
55
56 let bitcoin_block_hash = extract_bitcoin_block_hash::<Block>(substrate_header)
57 .map_err(|err| format!("Failed to extract bitcoin block hash: {err:?}"))?;
58
59 let substrate_block_hash = substrate_header.hash();
60
61 crate::block_import::write_aux_storage::<Block>(
62 &mut block_import_params,
63 bitcoin_block_hash,
64 substrate_block_hash,
65 chain_work,
66 );
67
68 Ok(block_import_params)
69 }
70}