massa_pos_exports/
controller_traits.rs

1// Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3//! This module exports generic traits representing interfaces for interacting
4//! with the PoS selector worker.
5
6use std::collections::BTreeMap;
7
8use crate::PosResult;
9use massa_hash::Hash;
10use massa_models::{address::Address, prehash::PreHashSet, slot::Slot};
11
12#[cfg(feature = "test-exports")]
13use std::collections::{HashMap, VecDeque};
14
15/// Selections of endorsements and producer
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct Selection {
18    /// Chosen endorsements
19    pub endorsements: Vec<Address>,
20    /// Chosen block producer
21    pub producer: Address,
22}
23
24#[cfg_attr(feature = "test-exports", mockall_wrap::wrap, mockall::automock)]
25/// interface that communicates with the selector worker thread
26pub trait SelectorController: Send + Sync {
27    /// Waits for draws to reach at least a given cycle number.
28    /// Returns the latest cycle number reached (can be higher than `cycle`).
29    /// Errors can occur if the thread stopped.
30    fn wait_for_draws(&self, cycle: u64) -> PosResult<u64>;
31
32    /// Feed cycle to the selector
33    ///
34    /// # Arguments
35    /// * `cycle`: cycle number to be drawn
36    /// * `lookback_rolls`: look back rolls used for the draw (cycle - 3)
37    /// * `lookback_seed`: look back seed hash for the draw (cycle - 2)
38    fn feed_cycle(
39        &self,
40        cycle: u64,
41        lookback_rolls: BTreeMap<Address, u64>,
42        lookback_seed: Hash,
43    ) -> PosResult<()>;
44
45    /// Get [Selection] computed for a slot
46    fn get_selection(&self, slot: Slot) -> PosResult<Selection>;
47
48    /// Get [Address] of the selected block producer for a given slot
49    fn get_producer(&self, slot: Slot) -> PosResult<Address>;
50
51    /// Get selections computed for a slot range (only returns available selections):
52    /// # Arguments
53    /// * `slot_range`: range of slots to get the selection for
54    /// * `restrict_to_addresses`: optionally restrict only to slots involving a given address
55    #[allow(clippy::needless_lifetimes)] // lifetime elision conflicts with Mockall
56    fn get_available_selections_in_range<'a>(
57        &self,
58        slot_range: std::ops::RangeInclusive<Slot>,
59        restrict_to_addresses: Option<&'a PreHashSet<Address>>,
60    ) -> PosResult<BTreeMap<Slot, Selection>>;
61
62    /// Returns a boxed clone of self.
63    /// Useful to allow cloning `Box<dyn SelectorController>`.
64    fn clone_box(&self) -> Box<dyn SelectorController>;
65
66    /// Get every [Selection]
67    ///
68    /// Only used in tests for post-bootstrap selection matching.
69    #[cfg(feature = "test-exports")]
70    fn get_entire_selection(&self) -> VecDeque<(u64, HashMap<Slot, Selection>)> {
71        unimplemented!("mock implementation only")
72    }
73}
74
75/// Allow cloning `Box<dyn SelectorController>`
76/// Uses `ExecutionController::clone_box` internally
77impl Clone for Box<dyn SelectorController> {
78    fn clone(&self) -> Box<dyn SelectorController> {
79        self.clone_box()
80    }
81}
82
83/// Selector manager used to stop the selector thread
84pub trait SelectorManager {
85    /// Stop the selector thread
86    /// Note that we do not take self by value to consume it
87    /// because it is not allowed to move out of `Box<dyn SelectorManager>`
88    /// This will improve if the `unsized_fn_params` feature stabilizes enough to be safely usable.
89    fn stop(&mut self);
90}