1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
use crate::block_graph_export::BlockGraphExport;
use crate::{bootstrapable_graph::BootstrapableGraph, error::ConsensusError};
use massa_models::prehash::PreHashSet;
use massa_models::streaming_step::StreamingStep;
use massa_models::{
block::BlockGraphStatus, block_header::BlockHeader, block_id::BlockId, clique::Clique,
secure_share::SecureShare, slot::Slot, stats::ConsensusStats,
};
use massa_storage::Storage;
#[cfg(feature = "test-exports")]
use std::sync::Arc;
/// Interface that communicates with the graph worker thread
#[cfg_attr(feature = "test-exports", mockall_wrap::wrap, mockall::automock)]
pub trait ConsensusController: Send + Sync {
/// Get an export of a part of the graph
///
/// # Arguments
/// * `start_slot`: the slot to start the export from, if None, the export starts from the genesis
/// * `end_slot`: the slot to end the export at, if None, the export ends at the current slot
///
/// # Returns
/// The export of the graph
fn get_block_graph_status(
&self,
start_slot: Option<Slot>,
end_slot: Option<Slot>,
) -> Result<BlockGraphExport, ConsensusError>;
/// Get statuses of a list of blocks
///
/// # Arguments
/// * `ids`: the list of block ids to get the status of
///
/// # Returns
/// The statuses of the blocks sorted by the order of the input list
fn get_block_statuses(&self, ids: &[BlockId]) -> Vec<BlockGraphStatus>;
/// Get all the cliques of the graph
///
/// # Returns
/// The list of cliques
fn get_cliques(&self) -> Vec<Clique>;
/// Get a part of the graph to send to a node for it to setup its graph.
/// Used for bootstrap.
///
/// # Arguments:
/// * `cursor`: streaming cursor containing the current state of bootstrap and what blocks have previously been sent to the client
/// * `execution_cursor`: streaming cursor of the final state to ensure that last slot of the bootstrap info match the slot of the execution
///
/// # Returns:
/// * A portion of the graph
/// * The list of outdated block ids
/// * The streaming step value after the current iteration to be saved to be able to use it as parameters and resume the bootstrap
#[allow(clippy::type_complexity)]
fn get_bootstrap_part(
&self,
cursor: StreamingStep<PreHashSet<BlockId>>,
execution_cursor: StreamingStep<Slot>,
) -> Result<
(
BootstrapableGraph,
PreHashSet<BlockId>,
StreamingStep<PreHashSet<BlockId>>,
),
ConsensusError,
>;
/// Get the stats of the consensus
///
/// # Returns
/// The stats of the consensus
fn get_stats(&self) -> Result<ConsensusStats, ConsensusError>;
/// Get the best parents for the next block to be produced
///
/// # Returns
/// The id of best parents for the next block to be produced along with their period
fn get_best_parents(&self) -> Vec<(BlockId, u64)>;
/// Get the block id of the block at a specific slot in the blockclique
///
/// # Arguments
/// * `slot`: the slot to get the block id of
///
/// # Returns
/// The block id of the block at the specified slot if exists
fn get_blockclique_block_at_slot(&self, slot: Slot) -> Option<BlockId>;
/// Get the latest block, that is in the blockclique, in the thread of the given slot and before this `slot`.
///
/// # Arguments:
/// * `slot`: the slot that will give us the thread and the upper bound
///
/// # Returns:
/// The block id of the latest block in the thread of the given slot and before this slot
fn get_latest_blockclique_block_at_slot(&self, slot: Slot) -> BlockId;
/// Register a block in the graph
///
/// # Arguments
/// * `block_id`: the id of the block to register
/// * `slot`: the slot of the block
/// * `block_storage`: the storage that contains all the objects of the block
/// * `created`: is the block created by our node ?
fn register_block(&self, block_id: BlockId, slot: Slot, block_storage: Storage, created: bool);
/// Register a block header in the graph
///
/// # Arguments
/// * `block_id`: the id of the block to register
/// * `header`: the header of the block to register
fn register_block_header(&self, block_id: BlockId, header: SecureShare<BlockHeader, BlockId>);
/// Mark a block as invalid in the graph
///
/// # Arguments
/// * `block_id`: the id of the block to mark as invalid
/// * `header`: the header of the block to mark as invalid
fn mark_invalid_block(&self, block_id: BlockId, header: SecureShare<BlockHeader, BlockId>);
/// Returns a boxed clone of self.
/// Useful to allow cloning `Box<dyn ConsensusController>`.
fn clone_box(&self) -> Box<dyn ConsensusController>;
}
/// Allow cloning `Box<dyn ConsensusController>`
/// Uses `ConsensusController::clone_box` internally
impl Clone for Box<dyn ConsensusController> {
fn clone(&self) -> Box<dyn ConsensusController> {
self.clone_box()
}
}
/// Consensus manager used to stop the consensus thread
pub trait ConsensusManager {
/// Stop the consensus thread
/// Note that we do not take self by value to consume it
/// because it is not allowed to move out of `Box<dyn ConsensusManager>`
/// This will improve if the `unsized_fn_params` feature stabilizes enough to be safely usable.
fn stop(&mut self);
}