1#![allow(unused_imports)]
3
4use std::{
5 cell::RefCell,
6 collections::{BTreeMap, BTreeSet},
7 fmt, iter,
8 rc::Rc,
9};
10
11use itertools::Itertools;
12use num::Zero;
13use num_rational::Ratio;
14use rand::{
15 distributions::{Distribution, Standard},
16 Rng,
17};
18use serde::{Deserialize, Serialize};
19
20use casper_types::{
21 addressable_entity::{
22 ActionThresholds, EntityKind, EntityKindTag, MessageTopics, NamedKeyAddr, NamedKeyValue,
23 },
24 bytesrepr,
25 contracts::NamedKeys,
26 execution::Effects,
27 system::{
28 auction::{
29 self, BidAddr, BidKind, DelegationRate, Delegator, SeigniorageRecipientV2,
30 SeigniorageRecipients, SeigniorageRecipientsSnapshot, SeigniorageRecipientsSnapshotV2,
31 SeigniorageRecipientsV2, Staking, ValidatorBid, AUCTION_DELAY_KEY,
32 DEFAULT_SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION, DELEGATION_RATE_DENOMINATOR,
33 ERA_END_TIMESTAMP_MILLIS_KEY, ERA_ID_KEY, INITIAL_ERA_END_TIMESTAMP_MILLIS,
34 INITIAL_ERA_ID, LOCKED_FUNDS_PERIOD_KEY, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY,
35 SEIGNIORAGE_RECIPIENTS_SNAPSHOT_VERSION_KEY, UNBONDING_DELAY_KEY, VALIDATOR_SLOTS_KEY,
36 },
37 handle_payment::{self, ACCUMULATION_PURSE_KEY},
38 mint::{
39 self, ARG_ROUND_SEIGNIORAGE_RATE, MINT_GAS_HOLD_HANDLING_KEY,
40 MINT_GAS_HOLD_INTERVAL_KEY, ROUND_SEIGNIORAGE_RATE_KEY, TOTAL_SUPPLY_KEY,
41 },
42 SystemEntityType, AUCTION, HANDLE_PAYMENT, MINT,
43 },
44 AccessRights, AddressableEntity, AddressableEntityHash, AdministratorAccount, BlockGlobalAddr,
45 BlockTime, ByteCode, ByteCodeAddr, ByteCodeHash, ByteCodeKind, CLValue, Chainspec,
46 ChainspecRegistry, Digest, EntityAddr, EntityVersions, EntryPointAddr, EntryPointValue,
47 EntryPoints, EraId, FeeHandling, GenesisAccount, GenesisConfig, Groups, HashAddr, Key, Motes,
48 Package, PackageHash, PackageStatus, Phase, ProtocolVersion, PublicKey, RefundHandling,
49 StoredValue, SystemConfig, SystemHashRegistry, Tagged, TimeDiff, URef, WasmConfig, U512,
50};
51
52use crate::{
53 global_state::state::StateProvider,
54 system::genesis::{
55 account_contract_installer::AccountContractInstaller,
56 entity_installer::EntityGenesisInstaller,
57 },
58 tracking_copy::{TrackingCopy, TrackingCopyError},
59 AddressGenerator,
60};
61
62mod account_contract_installer;
63mod entity_installer;
64
65const DEFAULT_ADDRESS: [u8; 32] = [0; 32];
66
67const NO_WASM: bool = true;
68
69#[derive(Clone, Debug)]
71pub enum GenesisError {
72 StateUninitialized,
74 InvalidMintKey,
76 MissingMintContract,
78 UnexpectedStoredValue,
80 MintError(mint::Error),
82 CLValue(String),
84 OrphanedDelegator {
86 validator_public_key: PublicKey,
88 delegator_public_key: PublicKey,
90 },
91 DuplicatedDelegatorEntry {
93 validator_public_key: PublicKey,
95 delegator_public_key: PublicKey,
97 },
98 InvalidDelegationRate {
100 public_key: PublicKey,
102 delegation_rate: DelegationRate,
104 },
105 InvalidBondAmount {
107 public_key: PublicKey,
109 },
110 InvalidDelegatedAmount {
112 public_key: PublicKey,
114 },
115 FailedToCreateSystemRegistry,
117 MissingSystemContractHash(String),
119 InvalidValidatorSlots {
121 validators: usize,
123 validator_slots: u32,
125 },
126 MissingChainspecRegistryEntry,
128 DuplicatedAdministratorEntry,
132 Bytesrepr(bytesrepr::Error),
134 MissingGenesisAccounts,
136 TrackingCopy(TrackingCopyError),
138}
139
140impl fmt::Display for GenesisError {
141 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
142 write!(f, "GenesisError: {:?}", self)
143 }
144}
145
146pub enum GenesisInstaller<S>
148where
149 S: StateProvider,
150{
151 AccountContract(AccountContractInstaller<S>),
153 Entity(EntityGenesisInstaller<S>),
155}
156impl<S> GenesisInstaller<S>
157where
158 S: StateProvider,
159{
160 pub fn new(
162 genesis_config_hash: Digest,
163 protocol_version: ProtocolVersion,
164 config: GenesisConfig,
165 tracking_copy: Rc<RefCell<TrackingCopy<<S as StateProvider>::Reader>>>,
166 ) -> Self {
167 if config.enable_entity() {
168 GenesisInstaller::Entity(EntityGenesisInstaller::new(
169 genesis_config_hash,
170 protocol_version,
171 config,
172 tracking_copy,
173 ))
174 } else {
175 GenesisInstaller::AccountContract(AccountContractInstaller::new(
176 genesis_config_hash,
177 protocol_version,
178 config,
179 tracking_copy,
180 ))
181 }
182 }
183
184 pub fn finalize(self) -> Effects {
186 match self {
187 GenesisInstaller::AccountContract(installer) => installer.finalize(),
188 GenesisInstaller::Entity(installer) => installer.finalize(),
189 }
190 }
191
192 pub fn install(
194 &mut self,
195 chainspec_registry: ChainspecRegistry,
196 ) -> Result<(), Box<GenesisError>> {
197 match self {
198 GenesisInstaller::AccountContract(installer) => installer.install(chainspec_registry),
199 GenesisInstaller::Entity(installer) => installer.install(chainspec_registry),
200 }
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207 use casper_types::AsymmetricType;
208 use rand::RngCore;
209
210 use casper_types::{bytesrepr, SecretKey};
211
212 #[test]
213 fn bytesrepr_roundtrip() {
214 let mut rng = rand::thread_rng();
215 let genesis_account: GenesisAccount = rng.gen();
216 bytesrepr::test_serialization_roundtrip(&genesis_account);
217 }
218
219 #[test]
220 fn system_account_bytesrepr_roundtrip() {
221 let genesis_account = GenesisAccount::system();
222
223 bytesrepr::test_serialization_roundtrip(&genesis_account);
224 }
225
226 #[test]
227 fn genesis_account_bytesrepr_roundtrip() {
228 let mut rng = rand::thread_rng();
229 let mut bytes = [0u8; 32];
230 rng.fill_bytes(&mut bytes[..]);
231 let secret_key = SecretKey::ed25519_from_bytes(bytes).unwrap();
232 let public_key: PublicKey = PublicKey::from(&secret_key);
233
234 let genesis_account_1 = GenesisAccount::account(public_key.clone(), Motes::new(100), None);
235
236 bytesrepr::test_serialization_roundtrip(&genesis_account_1);
237
238 let genesis_account_2 =
239 GenesisAccount::account(public_key, Motes::new(100), Some(rng.gen()));
240
241 bytesrepr::test_serialization_roundtrip(&genesis_account_2);
242 }
243
244 #[test]
245 fn delegator_bytesrepr_roundtrip() {
246 let mut rng = rand::thread_rng();
247 let mut validator_bytes = [0u8; 32];
248 let mut delegator_bytes = [0u8; 32];
249 rng.fill_bytes(&mut validator_bytes[..]);
250 rng.fill_bytes(&mut delegator_bytes[..]);
251 let validator_secret_key = SecretKey::ed25519_from_bytes(validator_bytes).unwrap();
252 let delegator_secret_key = SecretKey::ed25519_from_bytes(delegator_bytes).unwrap();
253
254 let validator_public_key = PublicKey::from(&validator_secret_key);
255 let delegator_public_key = PublicKey::from(&delegator_secret_key);
256
257 let genesis_account = GenesisAccount::delegator(
258 validator_public_key,
259 delegator_public_key,
260 Motes::new(100),
261 Motes::zero(),
262 );
263
264 bytesrepr::test_serialization_roundtrip(&genesis_account);
265 }
266
267 #[test]
268 fn administrator_account_bytesrepr_roundtrip() {
269 let administrator_account = AdministratorAccount::new(
270 PublicKey::ed25519_from_bytes([123u8; 32]).unwrap(),
271 Motes::new(U512::MAX),
272 );
273 bytesrepr::test_serialization_roundtrip(&administrator_account);
274 }
275}