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}