sc_consensus_nakamoto/
verifier.rs

1use 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
10/// Verifier used by the Substrate import queue.
11///
12/// Verifies the blocks received from the Substrate networking.
13pub struct SubstrateImportQueueVerifier<Block, Client> {
14    client: Arc<Client>,
15    btc_header_verifier: HeaderVerifier<Block, Client>,
16}
17
18impl<Block, Client> SubstrateImportQueueVerifier<Block, Client> {
19    /// Constructs a new instance of [`SubstrateImportQueueVerifier`].
20    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}