#[cfg(test)]
use rand::{
distributions::{Distribution, Standard},
Rng,
};
use casper_types::{
execution::Effects, ChainspecRegistry, Digest, GenesisAccount, GenesisConfig, GenesisValidator,
ProtocolVersion, PublicKey,
};
use crate::system::genesis::GenesisError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GenesisRequest {
chainspec_hash: Digest,
protocol_version: ProtocolVersion,
config: GenesisConfig,
chainspec_registry: ChainspecRegistry,
}
impl GenesisRequest {
pub fn new(
chainspec_hash: Digest,
protocol_version: ProtocolVersion,
config: GenesisConfig,
chainspec_registry: ChainspecRegistry,
) -> Self {
GenesisRequest {
chainspec_hash,
protocol_version,
config,
chainspec_registry,
}
}
pub fn set_enable_entity(&mut self, enable: bool) {
self.config.set_enable_entity(enable);
}
pub fn push_genesis_account(&mut self, genesis_account: GenesisAccount) {
self.config.push_account(genesis_account);
}
pub fn push_genesis_validator(
&mut self,
public_key: &PublicKey,
genesis_validator: GenesisValidator,
) {
self.config
.push_genesis_validator(public_key, genesis_validator);
}
pub fn chainspec_hash(&self) -> Digest {
self.chainspec_hash
}
pub fn protocol_version(&self) -> ProtocolVersion {
self.protocol_version
}
pub fn config(&self) -> &GenesisConfig {
&self.config
}
pub fn chainspec_registry(&self) -> &ChainspecRegistry {
&self.chainspec_registry
}
}
#[cfg(test)]
impl Distribution<GenesisRequest> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> GenesisRequest {
let input: [u8; 32] = rng.gen();
let chainspec_hash = Digest::hash(input);
let protocol_version = ProtocolVersion::from_parts(rng.gen(), rng.gen(), rng.gen());
let config = rng.gen();
let chainspec_file_bytes: [u8; 10] = rng.gen();
let genesis_account_file_bytes: [u8; 15] = rng.gen();
let chainspec_registry =
ChainspecRegistry::new_with_genesis(&chainspec_file_bytes, &genesis_account_file_bytes);
GenesisRequest::new(chainspec_hash, protocol_version, config, chainspec_registry)
}
}
#[derive(Debug, Clone)]
pub enum GenesisResult {
Fatal(String),
Failure(GenesisError),
Success {
post_state_hash: Digest,
effects: Effects,
},
}
impl GenesisResult {
pub fn is_success(&self) -> bool {
matches!(self, GenesisResult::Success { .. })
}
pub fn as_legacy(self) -> Result<(Digest, Effects), Box<GenesisError>> {
match self {
GenesisResult::Fatal(_) => Err(Box::new(GenesisError::StateUninitialized)),
GenesisResult::Failure(err) => Err(Box::new(err)),
GenesisResult::Success {
post_state_hash,
effects,
} => Ok((post_state_hash, effects)),
}
}
}