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}