casper_storage/data_access_layer/
genesis.rs

1#[cfg(test)]
2use rand::{
3    distributions::{Distribution, Standard},
4    Rng,
5};
6
7use casper_types::{
8    execution::Effects, ChainspecRegistry, Digest, GenesisAccount, GenesisConfig, GenesisValidator,
9    ProtocolVersion, PublicKey,
10};
11
12use crate::system::genesis::GenesisError;
13
14/// Represents a configuration of a genesis process.
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct GenesisRequest {
17    chainspec_hash: Digest,
18    protocol_version: ProtocolVersion,
19    config: GenesisConfig,
20    chainspec_registry: ChainspecRegistry,
21}
22
23impl GenesisRequest {
24    /// Creates a new genesis config object.
25    pub fn new(
26        chainspec_hash: Digest,
27        protocol_version: ProtocolVersion,
28        config: GenesisConfig,
29        chainspec_registry: ChainspecRegistry,
30    ) -> Self {
31        GenesisRequest {
32            chainspec_hash,
33            protocol_version,
34            config,
35            chainspec_registry,
36        }
37    }
38
39    /// Set enable entity.
40    pub fn set_enable_entity(&mut self, enable: bool) {
41        self.config.set_enable_entity(enable);
42    }
43
44    /// Push genesis validator.
45    pub fn push_genesis_account(&mut self, genesis_account: GenesisAccount) {
46        self.config.push_account(genesis_account);
47    }
48
49    /// Push genesis validator.
50    pub fn push_genesis_validator(
51        &mut self,
52        public_key: &PublicKey,
53        genesis_validator: GenesisValidator,
54    ) {
55        self.config
56            .push_genesis_validator(public_key, genesis_validator);
57    }
58
59    /// Returns chainspec_hash.
60    pub fn chainspec_hash(&self) -> Digest {
61        self.chainspec_hash
62    }
63
64    /// Returns protocol version.
65    pub fn protocol_version(&self) -> ProtocolVersion {
66        self.protocol_version
67    }
68
69    /// Returns configuration details of the genesis process.
70    pub fn config(&self) -> &GenesisConfig {
71        &self.config
72    }
73
74    /// Returns chainspec registry.
75    pub fn chainspec_registry(&self) -> &ChainspecRegistry {
76        &self.chainspec_registry
77    }
78}
79
80#[cfg(test)]
81impl Distribution<GenesisRequest> for Standard {
82    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> GenesisRequest {
83        let input: [u8; 32] = rng.gen();
84        let chainspec_hash = Digest::hash(input);
85        let protocol_version = ProtocolVersion::from_parts(rng.gen(), rng.gen(), rng.gen());
86        let config = rng.gen();
87
88        let chainspec_file_bytes: [u8; 10] = rng.gen();
89        let genesis_account_file_bytes: [u8; 15] = rng.gen();
90        let chainspec_registry =
91            ChainspecRegistry::new_with_genesis(&chainspec_file_bytes, &genesis_account_file_bytes);
92        GenesisRequest::new(chainspec_hash, protocol_version, config, chainspec_registry)
93    }
94}
95
96/// Represents a result of a `genesis` request.
97#[derive(Debug, Clone)]
98pub enum GenesisResult {
99    /// Genesis fatal.
100    Fatal(String),
101    /// Genesis failure.
102    Failure(GenesisError),
103    /// Genesis success.
104    Success {
105        /// State hash after genesis is committed to the global state.
106        post_state_hash: Digest,
107        /// Effects of genesis.
108        effects: Effects,
109    },
110}
111
112impl GenesisResult {
113    /// Is success.
114    pub fn is_success(&self) -> bool {
115        matches!(self, GenesisResult::Success { .. })
116    }
117
118    /// Returns a Result matching the original api for this functionality.
119    pub fn as_legacy(self) -> Result<(Digest, Effects), Box<GenesisError>> {
120        match self {
121            GenesisResult::Fatal(_) => Err(Box::new(GenesisError::StateUninitialized)),
122            GenesisResult::Failure(err) => Err(Box::new(err)),
123            GenesisResult::Success {
124                post_state_hash,
125                effects,
126            } => Ok((post_state_hash, effects)),
127        }
128    }
129}