casper_types/chainspec/
accounts_config.rsmod account_config;
mod delegator_config;
mod genesis;
mod validator_config;
#[cfg(feature = "datasize")]
use datasize::DataSize;
use serde::{Deserialize, Deserializer, Serialize};
#[cfg(any(feature = "testing", test))]
use crate::testing::TestRng;
use crate::{
bytesrepr::{self, FromBytes, ToBytes},
PublicKey,
};
pub use account_config::AccountConfig;
pub use delegator_config::DelegatorConfig;
pub use genesis::{AdministratorAccount, GenesisAccount, GenesisValidator};
pub use validator_config::ValidatorConfig;
fn sorted_vec_deserializer<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
where
T: Deserialize<'de> + Ord,
D: Deserializer<'de>,
{
let mut vec = Vec::<T>::deserialize(deserializer)?;
vec.sort_unstable();
Ok(vec)
}
#[derive(PartialEq, Eq, Serialize, Deserialize, Debug, Clone, Default)]
#[cfg_attr(feature = "datasize", derive(DataSize))]
pub struct AccountsConfig {
#[serde(deserialize_with = "sorted_vec_deserializer")]
accounts: Vec<AccountConfig>,
#[serde(default, deserialize_with = "sorted_vec_deserializer")]
delegators: Vec<DelegatorConfig>,
#[serde(
default,
deserialize_with = "sorted_vec_deserializer",
skip_serializing_if = "Vec::is_empty"
)]
administrators: Vec<AdministratorAccount>,
}
impl AccountsConfig {
pub fn new(
accounts: Vec<AccountConfig>,
delegators: Vec<DelegatorConfig>,
administrators: Vec<AdministratorAccount>,
) -> Self {
Self {
accounts,
delegators,
administrators,
}
}
pub fn accounts(&self) -> &[AccountConfig] {
&self.accounts
}
pub fn delegators(&self) -> &[DelegatorConfig] {
&self.delegators
}
pub fn administrators(&self) -> &[AdministratorAccount] {
&self.administrators
}
pub fn account(&self, public_key: &PublicKey) -> Option<&AccountConfig> {
self.accounts
.iter()
.find(|account| &account.public_key == public_key)
}
pub fn validators(&self) -> impl Iterator<Item = &AccountConfig> {
self.accounts
.iter()
.filter(|account| account.validator.is_some())
}
pub fn is_genesis_validator(&self, public_key: &PublicKey) -> bool {
match self.account(public_key) {
None => false,
Some(account_config) => account_config.is_genesis_validator(),
}
}
#[cfg(any(feature = "testing", test))]
pub fn random(rng: &mut TestRng) -> Self {
use rand::Rng;
use crate::Motes;
let alpha = AccountConfig::random(rng);
let accounts = vec![
alpha.clone(),
AccountConfig::random(rng),
AccountConfig::random(rng),
AccountConfig::random(rng),
];
let mut delegator = DelegatorConfig::random(rng);
delegator.validator_public_key = alpha.public_key;
let delegators = vec![delegator];
let admin_balance: u32 = rng.gen();
let administrators = vec![AdministratorAccount::new(
PublicKey::random(rng),
Motes::new(admin_balance),
)];
AccountsConfig {
accounts,
delegators,
administrators,
}
}
}
impl ToBytes for AccountsConfig {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
let mut buffer = bytesrepr::allocate_buffer(self)?;
buffer.extend(self.accounts.to_bytes()?);
buffer.extend(self.delegators.to_bytes()?);
buffer.extend(self.administrators.to_bytes()?);
Ok(buffer)
}
fn serialized_length(&self) -> usize {
self.accounts.serialized_length()
+ self.delegators.serialized_length()
+ self.administrators.serialized_length()
}
}
impl FromBytes for AccountsConfig {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (accounts, remainder) = FromBytes::from_bytes(bytes)?;
let (delegators, remainder) = FromBytes::from_bytes(remainder)?;
let (administrators, remainder) = FromBytes::from_bytes(remainder)?;
let accounts_config = AccountsConfig::new(accounts, delegators, administrators);
Ok((accounts_config, remainder))
}
}
impl From<AccountsConfig> for Vec<GenesisAccount> {
fn from(accounts_config: AccountsConfig) -> Self {
let mut genesis_accounts = Vec::with_capacity(accounts_config.accounts.len());
for account_config in accounts_config.accounts {
let genesis_account = account_config.into();
genesis_accounts.push(genesis_account);
}
for delegator_config in accounts_config.delegators {
let genesis_account = delegator_config.into();
genesis_accounts.push(genesis_account);
}
for administrator_config in accounts_config.administrators {
let administrator_account = administrator_config.into();
genesis_accounts.push(administrator_account);
}
genesis_accounts
}
}
#[cfg(any(feature = "testing", test))]
mod tests {
#[cfg(test)]
use crate::{bytesrepr, testing::TestRng, AccountsConfig};
#[test]
fn serialization_roundtrip() {
let mut rng = TestRng::new();
let accounts_config = AccountsConfig::random(&mut rng);
bytesrepr::test_serialization_roundtrip(&accounts_config);
}
}