casper_storage/data_access_layer/
step.rs

1//! Support for a step method.
2//!
3//! A step request executes auction code, slashes validators, evicts validators and distributes
4//! rewards.
5
6use std::vec::Vec;
7use thiserror::Error;
8
9use casper_types::{execution::Effects, CLValueError, Digest, EraId, ProtocolVersion, PublicKey};
10
11use crate::{
12    global_state::error::Error as GlobalStateError,
13    system::runtime_native::{Config, TransferConfig},
14    tracking_copy::TrackingCopyError,
15};
16
17/// The definition of a slash item.
18#[derive(Debug, Clone)]
19pub struct SlashItem {
20    /// The public key of the validator that will be slashed.
21    pub validator_id: PublicKey,
22}
23
24impl SlashItem {
25    /// Creates a new slash item.
26    pub fn new(validator_id: PublicKey) -> Self {
27        Self { validator_id }
28    }
29}
30
31/// The definition of a reward item.
32#[derive(Debug, Clone)]
33pub struct RewardItem {
34    /// The public key of the validator that will be rewarded.
35    pub validator_id: PublicKey,
36    /// Amount of motes that will be distributed as rewards.
37    pub value: u64,
38}
39
40impl RewardItem {
41    /// Creates new reward item.
42    pub fn new(validator_id: PublicKey, value: u64) -> Self {
43        Self {
44            validator_id,
45            value,
46        }
47    }
48}
49
50/// The definition of an evict item.
51#[derive(Debug, Clone)]
52pub struct EvictItem {
53    /// The public key of the validator that will be evicted.
54    pub validator_id: PublicKey,
55}
56
57impl EvictItem {
58    /// Creates new evict item.
59    pub fn new(validator_id: PublicKey) -> Self {
60        Self { validator_id }
61    }
62}
63
64/// Representation of a step request.
65#[derive(Debug)]
66pub struct StepRequest {
67    /// Config
68    config: Config,
69
70    /// State root hash.
71    state_hash: Digest,
72
73    /// Protocol version for this request.
74    protocol_version: ProtocolVersion,
75    /// List of validators to be slashed.
76    ///
77    /// A slashed validator is removed from the next validator set.
78    slash_items: Vec<SlashItem>,
79    /// List of validators to be evicted.
80    ///
81    /// Compared to a slashing, evictions are deactivating a given validator, but his stake is
82    /// unchanged. A further re-activation is possible.
83    evict_items: Vec<EvictItem>,
84    /// Specifies which era validators will be returned based on `next_era_id`.
85    ///
86    /// Intended use is to always specify the current era id + 1 which will return computed era at
87    /// the end of this step request.
88    next_era_id: EraId,
89
90    /// Timestamp in milliseconds representing end of the current era.
91    era_end_timestamp_millis: u64,
92}
93
94impl StepRequest {
95    /// Creates new step request.
96    #[allow(clippy::too_many_arguments)]
97    pub fn new(
98        config: Config,
99        state_hash: Digest,
100        protocol_version: ProtocolVersion,
101        slash_items: Vec<SlashItem>,
102        evict_items: Vec<EvictItem>,
103        next_era_id: EraId,
104        era_end_timestamp_millis: u64,
105    ) -> Self {
106        Self {
107            config,
108            state_hash,
109            protocol_version,
110            slash_items,
111            evict_items,
112            next_era_id,
113            era_end_timestamp_millis,
114        }
115    }
116
117    /// Returns the config.
118    pub fn config(&self) -> &Config {
119        &self.config
120    }
121
122    /// Returns the transfer config.
123    pub fn transfer_config(&self) -> TransferConfig {
124        self.config.transfer_config().clone()
125    }
126
127    /// Returns list of slashed validators.
128    pub fn slashed_validators(&self) -> Vec<PublicKey> {
129        self.slash_items
130            .iter()
131            .map(|si| si.validator_id.clone())
132            .collect()
133    }
134
135    /// Returns pre_state_hash.
136    pub fn state_hash(&self) -> Digest {
137        self.state_hash
138    }
139
140    /// Returns protocol_version.
141    pub fn protocol_version(&self) -> ProtocolVersion {
142        self.protocol_version
143    }
144
145    /// Returns slash_items.
146    pub fn slash_items(&self) -> &Vec<SlashItem> {
147        &self.slash_items
148    }
149
150    /// Returns evict_items.
151    pub fn evict_items(&self) -> &Vec<EvictItem> {
152        &self.evict_items
153    }
154    /// Returns next_era_id.
155    pub fn next_era_id(&self) -> EraId {
156        self.next_era_id
157    }
158
159    /// Returns era_end_timestamp_millis.
160    pub fn era_end_timestamp_millis(&self) -> u64 {
161        self.era_end_timestamp_millis
162    }
163}
164
165/// Representation of all possible failures of a step request.
166#[derive(Clone, Error, Debug)]
167pub enum StepError {
168    /// Error using the auction contract.
169    #[error("Auction error")]
170    Auction,
171    /// Error executing a slashing operation.
172    #[error("Slashing error")]
173    SlashingError,
174    /// Tracking copy error.
175    #[error("{0}")]
176    TrackingCopy(TrackingCopyError),
177    /// Failed to find auction contract.
178    #[error("Auction not found")]
179    AuctionNotFound,
180    /// Failed to find mint contract.
181    #[error("Mint not found")]
182    MintNotFound,
183}
184
185impl From<TrackingCopyError> for StepError {
186    fn from(tce: TrackingCopyError) -> Self {
187        Self::TrackingCopy(tce)
188    }
189}
190
191impl From<GlobalStateError> for StepError {
192    fn from(gse: GlobalStateError) -> Self {
193        Self::TrackingCopy(TrackingCopyError::Storage(gse))
194    }
195}
196
197impl From<CLValueError> for StepError {
198    fn from(cve: CLValueError) -> Self {
199        StepError::TrackingCopy(TrackingCopyError::CLValue(cve))
200    }
201}
202
203/// Outcome of running step process.
204#[derive(Debug)]
205pub enum StepResult {
206    /// Global state root not found.
207    RootNotFound,
208    /// Step process ran successfully.
209    Success {
210        /// State hash after step outcome is committed to the global state.
211        post_state_hash: Digest,
212        /// Effects of the step process.
213        effects: Effects,
214    },
215    /// Failed to execute step.
216    Failure(StepError),
217}
218
219impl StepResult {
220    /// Returns if step is successful.
221    pub fn is_success(&self) -> bool {
222        matches!(self, StepResult::Success { .. })
223    }
224}