massa_execution_exports/
controller_traits.rs

1// Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3//! This module exports generic traits representing interfaces for interacting with the Execution worker
4
5use crate::types::{
6    ExecutionBlockMetadata, ExecutionQueryRequest, ExecutionQueryResponse, ReadOnlyExecutionRequest,
7};
8
9use crate::ExecutionError;
10use crate::{ExecutionAddressInfo, ReadOnlyExecutionOutput};
11use massa_models::address::Address;
12use massa_models::amount::Amount;
13use massa_models::block_id::BlockId;
14use massa_models::denunciation::DenunciationIndex;
15use massa_models::execution::EventFilter;
16use massa_models::operation::OperationId;
17use massa_models::output_event::SCOutputEvent;
18use massa_models::prehash::PreHashMap;
19use massa_models::slot::Slot;
20use massa_models::stats::ExecutionStats;
21use std::collections::BTreeMap;
22use std::collections::HashMap;
23
24#[cfg(feature = "execution-trace")]
25use crate::types_trace_info::{AbiTrace, SlotAbiCallStack, Transfer};
26
27#[cfg_attr(feature = "test-exports", mockall::automock)]
28/// interface that communicates with the execution worker thread
29pub trait ExecutionController: Send + Sync {
30    /// Updates blockclique status by signaling newly finalized blocks and the latest blockclique.
31    ///
32    /// # Arguments
33    /// * `finalized_blocks`: newly finalized blocks indexed by slot.
34    /// * `blockclique`: new blockclique (if changed). Indexed by slot.
35    /// * `block_metadata`: storage instances and metadata for new blocks. Each storage owns refs to the block and its ops/endorsements.
36    fn update_blockclique_status(
37        &self,
38        finalized_blocks: HashMap<Slot, BlockId>,
39        new_blockclique: Option<HashMap<Slot, BlockId>>,
40        block_metadata: PreHashMap<BlockId, ExecutionBlockMetadata>,
41    );
42
43    /// Atomically query the execution state with multiple requests
44    fn query_state(&self, req: ExecutionQueryRequest) -> ExecutionQueryResponse;
45
46    /// Get execution events optionally filtered by:
47    /// * start slot
48    /// * end slot
49    /// * emitter address
50    /// * original caller address
51    /// * operation id
52    fn get_filtered_sc_output_event(&self, filter: EventFilter) -> Vec<SCOutputEvent>;
53
54    /// Get the final and active values of balance.
55    ///
56    /// # Return value
57    /// * `(final_balance, active_balance)`
58    fn get_final_and_candidate_balance(
59        &self,
60        addresses: &[Address],
61    ) -> Vec<(Option<Amount>, Option<Amount>)>;
62
63    /// Get the execution status of a batch of operations.
64    ///
65    ///  Return value: vector of
66    ///  `(Option<speculative_status>, Option<final_status>)`
67    ///  If an Option is None it means that the op execution was not found.
68    ///  Note that old op executions are forgotten.
69    /// Otherwise, the status is a boolean indicating whether the execution was successful (true) or if there was an error (false.)
70    fn get_ops_exec_status(&self, batch: &[OperationId]) -> Vec<(Option<bool>, Option<bool>)>;
71
72    /// Get a copy of a single datastore entry with its final and active values
73    ///
74    /// # Return value
75    /// * `(final_data_entry, active_data_entry)`
76    #[allow(clippy::type_complexity)]
77    fn get_final_and_active_data_entry(
78        &self,
79        input: Vec<(Address, Vec<u8>)>,
80    ) -> Vec<(Option<Vec<u8>>, Option<Vec<u8>>)>;
81
82    /// Returns for a given cycle the stakers taken into account
83    /// by the selector. That correspond to the `roll_counts` in `cycle - 3`.
84    ///
85    /// By default it returns an empty map.
86    fn get_cycle_active_rolls(&self, cycle: u64) -> BTreeMap<Address, u64>;
87
88    /// Execute read-only SC function call without causing modifications to the consensus state
89    ///
90    /// # arguments
91    /// * `req`: an instance of `ReadOnlyCallRequest` describing the parameters of the execution
92    ///
93    /// # returns
94    /// An instance of `ExecutionOutput` containing a summary of the effects of the execution,
95    /// or an error if the execution failed.
96    fn execute_readonly_request(
97        &self,
98        req: ReadOnlyExecutionRequest,
99    ) -> Result<ReadOnlyExecutionOutput, ExecutionError>;
100
101    /// Check if a denunciation has been executed given a `DenunciationIndex`
102    /// (speculative, final)
103    fn get_denunciation_execution_status(
104        &self,
105        denunciation_index: &DenunciationIndex,
106    ) -> (bool, bool);
107
108    /// Gets information about a batch of addresses.
109    /// `max_keys` caps the datastore keys listed per address (`None` = unbounded);
110    /// callers must pass their configured cap, never `None` on a transport path.
111    fn get_addresses_infos(
112        &self,
113        addresses: &[Address],
114        deferred_credits_max_slot: std::ops::Bound<Slot>,
115        max_keys: Option<u32>,
116    ) -> Vec<ExecutionAddressInfo>;
117
118    /// Get execution statistics
119    fn get_stats(&self) -> ExecutionStats;
120
121    /// Get the current module LRU cache size
122    fn get_module_lru_cache_memory_usage(&self) -> usize;
123
124    /// Get the number of events currently in the active history
125    fn get_active_history_total_event_len(&self) -> usize;
126
127    #[cfg(feature = "execution-trace")]
128    /// Get the abi call stack for a given operation id
129    fn get_operation_abi_call_stack(&self, operation_id: OperationId) -> Option<Vec<AbiTrace>>;
130
131    #[cfg(feature = "execution-trace")]
132    /// Get the abi call stack for a given slot
133    fn get_slot_abi_call_stack(&self, slot: Slot) -> Option<SlotAbiCallStack>;
134
135    #[cfg(feature = "execution-trace")]
136    /// Get the all transfers of MAS for a given slot
137    fn get_transfers_for_slot(&self, slot: Slot) -> Option<Vec<Transfer>>;
138
139    #[cfg(feature = "execution-trace")]
140    /// Get both the ABI call stack and the direct transfers for a given slot, read from a
141    /// single consistent snapshot of the execution trace history.
142    ///
143    /// Callers that need both datasets for a slot must use this instead of combining
144    /// `get_slot_abi_call_stack` and `get_transfers_for_slot`: those are two separate reads,
145    /// and a slot re-execution occurring between them can yield a response mixing data from
146    /// two different executions of the same slot.
147    fn get_slot_abi_call_stack_and_transfers(
148        &self,
149        slot: Slot,
150    ) -> (Option<SlotAbiCallStack>, Option<Vec<Transfer>>);
151
152    #[cfg(feature = "execution-trace")]
153    /// Get the transfer of MAS for a given operation id
154    fn get_transfer_for_op(&self, op_id: &OperationId) -> Option<Transfer>;
155
156    /// Returns a boxed clone of self.
157    /// Useful to allow cloning `Box<dyn ExecutionController>`.
158    fn clone_box(&self) -> Box<dyn ExecutionController>;
159}
160
161/// Allow cloning `Box<dyn ExecutionController>`
162/// Uses `ExecutionController::clone_box` internally
163impl Clone for Box<dyn ExecutionController> {
164    fn clone(&self) -> Box<dyn ExecutionController> {
165        self.clone_box()
166    }
167}
168
169/// Execution manager used to stop the execution thread
170pub trait ExecutionManager {
171    /// Stop the execution thread
172    /// Note that we do not take self by value to consume it
173    /// because it is not allowed to move out of `Box<dyn ExecutionManager>`
174    /// This will improve if the `unsized_fn_params` feature stabilizes enough to be safely usable.
175    fn stop(&mut self);
176}