blockgen/
lib.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4mod assembler;
5mod mine_session;
6mod miner;
7mod test_api;
8
9pub use crate::test_api::BlockGeneratorTestApi;
10
11use crate::{
12    assembler::BlockAssembler, mine_session::MiningSession, miner::MineWorker,
13};
14
15use cfx_types::Address;
16use cfxcore::{
17    consensus::pos_handler::PosVerifier, pow::*, ConsensusGraph,
18    SharedSynchronizationGraph, SharedSynchronizationService,
19    SharedTransactionPool, Stopable,
20};
21use parking_lot::RwLock;
22use primitives::Block;
23use std::sync::{mpsc, Arc};
24use txgen::SharedTransactionGenerator;
25
26enum MiningStatus {
27    Start,
28    Stop,
29}
30
31type SolutionReceiver = mpsc::Receiver<ProofOfWorkSolution>;
32
33/// The interface for a conflux block generator
34pub struct BlockGenerator {
35    pub(crate) pow_config: ProofOfWorkConfig,
36    pub(crate) pow: Arc<PowComputer>,
37    consensus: Arc<ConsensusGraph>,
38    sync: SharedSynchronizationService,
39    status: RwLock<MiningStatus>,
40    assembler: BlockAssembler,
41}
42
43impl BlockGenerator {
44    #[allow(clippy::too_many_arguments)]
45    pub fn new(
46        graph: SharedSynchronizationGraph, txpool: SharedTransactionPool,
47        sync: SharedSynchronizationService,
48        maybe_txgen: Option<SharedTransactionGenerator>,
49        pow_config: ProofOfWorkConfig, pow: Arc<PowComputer>,
50        mining_author: Address, pos_verifier: Arc<PosVerifier>,
51    ) -> Self {
52        let consensus = graph.consensus.clone();
53        let assembler = BlockAssembler::new(
54            graph,
55            txpool,
56            maybe_txgen,
57            mining_author,
58            pos_verifier,
59        );
60        BlockGenerator {
61            pow_config,
62            pow,
63            consensus,
64            sync,
65            assembler,
66            status: RwLock::new(MiningStatus::Start),
67        }
68    }
69
70    fn is_running(&self) -> bool {
71        matches!(*self.status.read(), MiningStatus::Start)
72    }
73
74    /// Stop mining
75    pub fn stop(&self) {
76        {
77            let mut write = self.status.write();
78            *write = MiningStatus::Stop;
79        }
80        self.assembler.stop();
81    }
82
83    /// Update and sync a new block
84    fn on_mined_block(&self, block: Block) {
85        // FIXME: error handling.
86        self.sync.on_mined_block(block).ok();
87    }
88
89    pub fn test_api(self: &Arc<Self>) -> BlockGeneratorTestApi {
90        BlockGeneratorTestApi::new(self.clone())
91    }
92
93    pub fn mine(self: &Arc<Self>) {
94        let miner_type = if self.pow_config.use_stratum() {
95            miner::MinerType::Stratum
96        } else {
97            miner::MinerType::Cpu(1)
98        };
99
100        let (miner, solution_rx) = miner::spawn(self.clone(), miner_type);
101
102        MiningSession::new(self, &*miner, solution_rx).run();
103    }
104}
105
106impl Stopable for BlockGenerator {
107    fn stop(&self) { BlockGenerator::stop(self) }
108}