casper_types/chainspec/
accounts_config.rs

1//! The accounts config is a set of configuration options that is used to create accounts at
2//! genesis, and set up auction contract with validators and delegators.
3mod account_config;
4mod delegator_config;
5mod genesis;
6mod validator_config;
7#[cfg(feature = "datasize")]
8use datasize::DataSize;
9use serde::{Deserialize, Deserializer, Serialize};
10
11#[cfg(any(feature = "testing", test))]
12use crate::testing::TestRng;
13use crate::{
14    bytesrepr::{self, FromBytes, ToBytes},
15    PublicKey,
16};
17
18pub use account_config::AccountConfig;
19pub use delegator_config::DelegatorConfig;
20pub use genesis::{AdministratorAccount, GenesisAccount, GenesisValidator};
21pub use validator_config::ValidatorConfig;
22
23fn sorted_vec_deserializer<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
24where
25    T: Deserialize<'de> + Ord,
26    D: Deserializer<'de>,
27{
28    let mut vec = Vec::<T>::deserialize(deserializer)?;
29    vec.sort_unstable();
30    Ok(vec)
31}
32
33/// Configuration values associated with accounts.toml
34#[derive(PartialEq, Eq, Serialize, Deserialize, Debug, Clone, Default)]
35#[cfg_attr(feature = "datasize", derive(DataSize))]
36pub struct AccountsConfig {
37    #[serde(deserialize_with = "sorted_vec_deserializer")]
38    accounts: Vec<AccountConfig>,
39    #[serde(default, deserialize_with = "sorted_vec_deserializer")]
40    delegators: Vec<DelegatorConfig>,
41    #[serde(
42        default,
43        deserialize_with = "sorted_vec_deserializer",
44        skip_serializing_if = "Vec::is_empty"
45    )]
46    administrators: Vec<AdministratorAccount>,
47}
48
49impl AccountsConfig {
50    /// Create new accounts config instance.
51    pub fn new(
52        accounts: Vec<AccountConfig>,
53        delegators: Vec<DelegatorConfig>,
54        administrators: Vec<AdministratorAccount>,
55    ) -> Self {
56        Self {
57            accounts,
58            delegators,
59            administrators,
60        }
61    }
62
63    /// Accounts.
64    pub fn accounts(&self) -> &[AccountConfig] {
65        &self.accounts
66    }
67
68    /// Delegators.
69    pub fn delegators(&self) -> &[DelegatorConfig] {
70        &self.delegators
71    }
72
73    /// Administrators.
74    pub fn administrators(&self) -> &[AdministratorAccount] {
75        &self.administrators
76    }
77
78    /// Account.
79    pub fn account(&self, public_key: &PublicKey) -> Option<&AccountConfig> {
80        self.accounts
81            .iter()
82            .find(|account| &account.public_key == public_key)
83    }
84
85    /// All of the validators.
86    pub fn validators(&self) -> impl Iterator<Item = &AccountConfig> {
87        self.accounts
88            .iter()
89            .filter(|account| account.validator.is_some())
90    }
91
92    /// Is the provided public key in the set of genesis validator public keys.
93    pub fn is_genesis_validator(&self, public_key: &PublicKey) -> bool {
94        match self.account(public_key) {
95            None => false,
96            Some(account_config) => account_config.is_genesis_validator(),
97        }
98    }
99
100    #[cfg(any(feature = "testing", test))]
101    /// Generates a random instance using a `TestRng`.
102    pub fn random(rng: &mut TestRng) -> Self {
103        use rand::Rng;
104
105        use crate::Motes;
106
107        let alpha = AccountConfig::random(rng);
108        let accounts = vec![
109            alpha.clone(),
110            AccountConfig::random(rng),
111            AccountConfig::random(rng),
112            AccountConfig::random(rng),
113        ];
114
115        let mut delegator = DelegatorConfig::random(rng);
116        delegator.validator_public_key = alpha.public_key;
117
118        let delegators = vec![delegator];
119
120        let admin_balance: u32 = rng.gen();
121        let administrators = vec![AdministratorAccount::new(
122            PublicKey::random(rng),
123            Motes::new(admin_balance),
124        )];
125
126        AccountsConfig {
127            accounts,
128            delegators,
129            administrators,
130        }
131    }
132}
133
134impl ToBytes for AccountsConfig {
135    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
136        let mut buffer = bytesrepr::allocate_buffer(self)?;
137        buffer.extend(self.accounts.to_bytes()?);
138        buffer.extend(self.delegators.to_bytes()?);
139        buffer.extend(self.administrators.to_bytes()?);
140        Ok(buffer)
141    }
142
143    fn serialized_length(&self) -> usize {
144        self.accounts.serialized_length()
145            + self.delegators.serialized_length()
146            + self.administrators.serialized_length()
147    }
148}
149
150impl FromBytes for AccountsConfig {
151    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
152        let (accounts, remainder) = FromBytes::from_bytes(bytes)?;
153        let (delegators, remainder) = FromBytes::from_bytes(remainder)?;
154        let (administrators, remainder) = FromBytes::from_bytes(remainder)?;
155        let accounts_config = AccountsConfig::new(accounts, delegators, administrators);
156        Ok((accounts_config, remainder))
157    }
158}
159
160impl From<AccountsConfig> for Vec<GenesisAccount> {
161    fn from(accounts_config: AccountsConfig) -> Self {
162        let mut genesis_accounts = Vec::with_capacity(accounts_config.accounts.len());
163        for account_config in accounts_config.accounts {
164            let genesis_account = account_config.into();
165            genesis_accounts.push(genesis_account);
166        }
167        for delegator_config in accounts_config.delegators {
168            let genesis_account = delegator_config.into();
169            genesis_accounts.push(genesis_account);
170        }
171
172        for administrator_config in accounts_config.administrators {
173            let administrator_account = administrator_config.into();
174            genesis_accounts.push(administrator_account);
175        }
176
177        genesis_accounts
178    }
179}
180
181#[cfg(any(feature = "testing", test))]
182mod tests {
183    #[cfg(test)]
184    use crate::{bytesrepr, testing::TestRng, AccountsConfig};
185
186    #[test]
187    fn serialization_roundtrip() {
188        let mut rng = TestRng::new();
189        let accounts_config = AccountsConfig::random(&mut rng);
190        bytesrepr::test_serialization_roundtrip(&accounts_config);
191    }
192}