1#[cfg(any(feature = "testing", test))]
4use std::iter;
5
6use num_rational::Ratio;
7#[cfg(any(feature = "testing", test))]
8use rand::{
9 distributions::{Distribution, Standard},
10 Rng,
11};
12use serde::{Deserialize, Serialize};
13
14use crate::{
15 AdministratorAccount, Chainspec, GenesisAccount, GenesisValidator, HoldBalanceHandling, Motes,
16 PublicKey, SystemConfig, WasmConfig,
17};
18
19use super::StorageCosts;
20
21#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
23pub struct GenesisConfig {
24 accounts: Vec<GenesisAccount>,
25 wasm_config: WasmConfig,
26 system_config: SystemConfig,
27 validator_slots: u32,
28 auction_delay: u64,
29 locked_funds_period_millis: u64,
30 round_seigniorage_rate: Ratio<u64>,
31 unbonding_delay: u64,
32 genesis_timestamp_millis: u64,
33 gas_hold_balance_handling: HoldBalanceHandling,
34 gas_hold_interval_millis: u64,
35 enable_addressable_entity: bool,
36 storage_costs: StorageCosts,
37}
38
39impl GenesisConfig {
40 #[allow(clippy::too_many_arguments)]
42 pub fn new(
43 accounts: Vec<GenesisAccount>,
44 wasm_config: WasmConfig,
45 system_config: SystemConfig,
46 validator_slots: u32,
47 auction_delay: u64,
48 locked_funds_period_millis: u64,
49 round_seigniorage_rate: Ratio<u64>,
50 unbonding_delay: u64,
51 genesis_timestamp_millis: u64,
52 gas_hold_balance_handling: HoldBalanceHandling,
53 gas_hold_interval_millis: u64,
54 enable_addressable_entity: bool,
55 storage_costs: StorageCosts,
56 ) -> GenesisConfig {
57 GenesisConfig {
58 accounts,
59 wasm_config,
60 system_config,
61 validator_slots,
62 auction_delay,
63 locked_funds_period_millis,
64 round_seigniorage_rate,
65 unbonding_delay,
66 genesis_timestamp_millis,
67 gas_hold_balance_handling,
68 gas_hold_interval_millis,
69 enable_addressable_entity,
70 storage_costs,
71 }
72 }
73
74 pub fn wasm_config(&self) -> &WasmConfig {
76 &self.wasm_config
77 }
78
79 pub fn system_config(&self) -> &SystemConfig {
81 &self.system_config
82 }
83
84 pub fn get_bonded_validators(&self) -> impl Iterator<Item = &GenesisAccount> {
86 self.accounts_iter()
87 .filter(|&genesis_account| genesis_account.is_validator())
88 }
89
90 pub fn get_bonded_delegators(
92 &self,
93 ) -> impl Iterator<Item = (&PublicKey, &PublicKey, &Motes, &Motes)> {
94 self.accounts
95 .iter()
96 .filter_map(|genesis_account| genesis_account.as_delegator())
97 }
98
99 pub fn accounts(&self) -> &[GenesisAccount] {
101 self.accounts.as_slice()
102 }
103
104 pub fn accounts_iter(&self) -> impl Iterator<Item = &GenesisAccount> {
106 self.accounts.iter()
107 }
108
109 pub fn administrative_accounts(&self) -> impl Iterator<Item = &AdministratorAccount> {
111 self.accounts
112 .iter()
113 .filter_map(GenesisAccount::as_administrator_account)
114 }
115
116 pub fn push_account(&mut self, account: GenesisAccount) {
118 self.accounts.push(account)
119 }
120
121 pub fn validator_slots(&self) -> u32 {
123 self.validator_slots
124 }
125
126 pub fn auction_delay(&self) -> u64 {
128 self.auction_delay
129 }
130
131 pub fn locked_funds_period_millis(&self) -> u64 {
133 self.locked_funds_period_millis
134 }
135
136 pub fn round_seigniorage_rate(&self) -> Ratio<u64> {
138 self.round_seigniorage_rate
139 }
140
141 pub fn unbonding_delay(&self) -> u64 {
143 self.unbonding_delay
144 }
145
146 pub fn genesis_timestamp_millis(&self) -> u64 {
148 self.genesis_timestamp_millis
149 }
150
151 pub fn gas_hold_balance_handling(&self) -> HoldBalanceHandling {
153 self.gas_hold_balance_handling
154 }
155
156 pub fn gas_hold_interval_millis(&self) -> u64 {
158 self.gas_hold_interval_millis
159 }
160
161 pub fn enable_entity(&self) -> bool {
163 self.enable_addressable_entity
164 }
165
166 pub fn set_enable_entity(&mut self, enable: bool) {
168 self.enable_addressable_entity = enable
169 }
170
171 pub fn push_genesis_validator(
173 &mut self,
174 public_key: &PublicKey,
175 genesis_validator: GenesisValidator,
176 ) {
177 if let Some(genesis_account) = self
178 .accounts
179 .iter_mut()
180 .find(|x| &x.public_key() == public_key)
181 {
182 genesis_account.try_set_validator(genesis_validator);
183 }
184 }
185}
186
187#[cfg(any(feature = "testing", test))]
188impl Distribution<GenesisConfig> for Standard {
189 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> GenesisConfig {
190 let count = rng.gen_range(1..10);
191
192 let accounts = iter::repeat(()).map(|_| rng.gen()).take(count).collect();
193
194 let wasm_config = rng.gen();
195
196 let system_config = rng.gen();
197
198 let validator_slots = rng.gen();
199
200 let auction_delay = rng.gen();
201
202 let locked_funds_period_millis = rng.gen();
203
204 let round_seigniorage_rate = Ratio::new(
205 rng.gen_range(1..1_000_000_000),
206 rng.gen_range(1..1_000_000_000),
207 );
208
209 let unbonding_delay = rng.gen();
210
211 let genesis_timestamp_millis = rng.gen();
212 let gas_hold_balance_handling = rng.gen();
213 let gas_hold_interval_millis = rng.gen();
214 let storage_costs = rng.gen();
215
216 GenesisConfig {
217 accounts,
218 wasm_config,
219 system_config,
220 validator_slots,
221 auction_delay,
222 locked_funds_period_millis,
223 round_seigniorage_rate,
224 unbonding_delay,
225 genesis_timestamp_millis,
226 gas_hold_balance_handling,
227 gas_hold_interval_millis,
228 enable_addressable_entity: false,
229 storage_costs,
230 }
231 }
232}
233
234impl From<&Chainspec> for GenesisConfig {
235 fn from(chainspec: &Chainspec) -> Self {
236 let genesis_timestamp_millis = chainspec
237 .protocol_config
238 .activation_point
239 .genesis_timestamp()
240 .map_or(0, |timestamp| timestamp.millis());
241 let gas_hold_interval_millis = chainspec.core_config.gas_hold_interval.millis();
242 let gas_hold_balance_handling = chainspec.core_config.gas_hold_balance_handling;
243 let storage_costs = chainspec.storage_costs;
244 GenesisConfig {
245 accounts: chainspec.network_config.accounts_config.clone().into(),
246 wasm_config: chainspec.wasm_config,
247 system_config: chainspec.system_costs_config,
248 validator_slots: chainspec.core_config.validator_slots,
249 auction_delay: chainspec.core_config.auction_delay,
250 locked_funds_period_millis: chainspec.core_config.locked_funds_period.millis(),
251 round_seigniorage_rate: chainspec.core_config.round_seigniorage_rate,
252 unbonding_delay: chainspec.core_config.unbonding_delay,
253 genesis_timestamp_millis,
254 gas_hold_balance_handling,
255 gas_hold_interval_millis,
256 enable_addressable_entity: chainspec.core_config.enable_addressable_entity,
257 storage_costs,
258 }
259 }
260}