1extern crate alloc;
18
19use crate::{
20 currency::GLMR, currency::SUPPLY_FACTOR, AccountId, AuthorFilterConfig, AuthorMappingConfig,
21 Balance, Balances, BalancesConfig, BridgeKusamaGrandpaConfig, BridgeKusamaMessagesConfig,
22 BridgeKusamaParachainsConfig, BridgeXcmOverMoonriverConfig, EVMConfig, EligibilityValue,
23 EthereumChainIdConfig, EthereumConfig, EvmForeignAssetsConfig, InflationInfo,
24 MaintenanceModeConfig, OpenTechCommitteeCollectiveConfig, ParachainInfoConfig,
25 ParachainStakingConfig, PolkadotXcmConfig, Precompiles, Range, RuntimeGenesisConfig,
26 TransactionPaymentConfig, TreasuryCouncilCollectiveConfig, XcmWeightTraderConfig, HOURS,
27};
28use alloc::{vec, vec::Vec};
29use bp_messages::MessagesOperatingMode;
30use bp_runtime::BasicOperatingMode;
31use cumulus_primitives_core::ParaId;
32use fp_evm::GenesisAccount;
33use frame_support::pallet_prelude::PalletInfoAccess;
34use nimbus_primitives::NimbusId;
35use pallet_moonbeam_foreign_assets::EvmForeignAssetInfo;
36use pallet_transaction_payment::Multiplier;
37use pallet_xcm_weight_trader::XcmWeightTraderAssetInfo;
38use sp_genesis_builder::PresetId;
39use sp_keyring::Sr25519Keyring;
40use sp_runtime::{Perbill, Percent};
41use xcm::prelude::{GlobalConsensus, Junctions, Location, NetworkId, PalletInstance, Parachain};
42
43const COLLATOR_COMMISSION: Perbill = Perbill::from_percent(20);
44const PARACHAIN_BOND_RESERVE_PERCENT: Percent = Percent::from_percent(30);
45const BLOCKS_PER_ROUND: u32 = 6 * HOURS;
46const BLOCKS_PER_YEAR: u32 = 31_557_600 / 12;
47const NUM_SELECTED_CANDIDATES: u32 = 8;
48
49pub fn moonbeam_inflation_config() -> InflationInfo<Balance> {
50 fn to_round_inflation(annual: Range<Perbill>) -> Range<Perbill> {
51 use pallet_parachain_staking::inflation::perbill_annual_to_perbill_round;
52 perbill_annual_to_perbill_round(
53 annual,
54 BLOCKS_PER_YEAR / BLOCKS_PER_ROUND,
56 )
57 }
58 let annual = Range {
59 min: Perbill::from_percent(4),
60 ideal: Perbill::from_percent(5),
61 max: Perbill::from_percent(5),
62 };
63 InflationInfo {
64 expect: Range {
66 min: 100_000 * GLMR * SUPPLY_FACTOR,
67 ideal: 200_000 * GLMR * SUPPLY_FACTOR,
68 max: 500_000 * GLMR * SUPPLY_FACTOR,
69 },
70 annual,
72 round: to_round_inflation(annual),
73 }
74}
75
76pub fn testnet_genesis(
77 treasury_council_members: Vec<AccountId>,
78 open_tech_committee_members: Vec<AccountId>,
79 candidates: Vec<(AccountId, NimbusId, Balance)>,
80 delegations: Vec<(AccountId, AccountId, Balance, Percent)>,
81 endowed_accounts: Vec<AccountId>,
82 para_id: ParaId,
83 chain_id: u64,
84) -> serde_json::Value {
85 let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
90
91 let config = RuntimeGenesisConfig {
92 system: Default::default(),
93 balances: BalancesConfig {
94 balances: endowed_accounts
95 .iter()
96 .cloned()
97 .map(|k| (k, 1 << 110))
98 .collect(),
99 dev_accounts: Default::default(),
100 },
101 parachain_info: ParachainInfoConfig {
102 parachain_id: para_id,
103 ..Default::default()
104 },
105 ethereum_chain_id: EthereumChainIdConfig {
106 chain_id,
107 ..Default::default()
108 },
109 evm: EVMConfig {
110 accounts: Precompiles::used_addresses()
113 .map(|addr| {
114 (
115 addr.into(),
116 GenesisAccount {
117 nonce: Default::default(),
118 balance: Default::default(),
119 storage: Default::default(),
120 code: revert_bytecode.clone(),
121 },
122 )
123 })
124 .collect(),
125 ..Default::default()
126 },
127 ethereum: EthereumConfig {
128 ..Default::default()
129 },
130 parachain_staking: ParachainStakingConfig {
131 candidates: candidates
132 .iter()
133 .cloned()
134 .map(|(account, _, bond)| (account, bond))
135 .collect(),
136 delegations,
137 inflation_config: moonbeam_inflation_config(),
138 collator_commission: COLLATOR_COMMISSION,
139 parachain_bond_reserve_percent: PARACHAIN_BOND_RESERVE_PERCENT,
140 blocks_per_round: BLOCKS_PER_ROUND,
141 num_selected_candidates: NUM_SELECTED_CANDIDATES,
142 },
143 treasury_council_collective: TreasuryCouncilCollectiveConfig {
144 phantom: Default::default(),
145 members: treasury_council_members,
146 },
147 open_tech_committee_collective: OpenTechCommitteeCollectiveConfig {
148 phantom: Default::default(),
149 members: open_tech_committee_members,
150 },
151 author_filter: AuthorFilterConfig {
152 eligible_count: EligibilityValue::new_unchecked(50),
153 ..Default::default()
154 },
155 author_mapping: AuthorMappingConfig {
156 mappings: candidates
157 .iter()
158 .cloned()
159 .map(|(account_id, author_id, _)| (author_id, account_id))
160 .collect(),
161 },
162 proxy_genesis_companion: Default::default(),
163 treasury: Default::default(),
164 maintenance_mode: MaintenanceModeConfig {
165 start_in_maintenance_mode: false,
166 ..Default::default()
167 },
168 polkadot_xcm: PolkadotXcmConfig {
169 supported_version: vec![
170 (
172 bp_moonriver::GlobalConsensusLocation::get(),
173 xcm::latest::VERSION,
174 ),
175 ],
176 ..Default::default()
177 },
178 transaction_payment: TransactionPaymentConfig {
179 multiplier: Multiplier::from(8u128),
180 ..Default::default()
181 },
182 evm_foreign_assets: EvmForeignAssetsConfig {
183 assets: vec![EvmForeignAssetInfo {
184 asset_id: 1001,
185 name: b"xcMOVR".to_vec().try_into().expect("Invalid asset name"),
186 symbol: b"xcMOVR".to_vec().try_into().expect("Invalid asset symbol"),
187 decimals: 18,
188 xcm_location: Location::new(
189 2,
190 [
191 GlobalConsensus(crate::bridge_config::KusamaGlobalConsensusNetwork::get()),
192 Parachain(<bp_moonriver::Moonriver as bp_runtime::Parachain>::PARACHAIN_ID),
193 PalletInstance(<Balances as PalletInfoAccess>::index() as u8),
194 ],
195 ),
196 }],
197 _phantom: Default::default(),
198 },
199 xcm_weight_trader: XcmWeightTraderConfig {
200 assets: vec![XcmWeightTraderAssetInfo {
201 location: Location::new(
202 2,
203 [
204 GlobalConsensus(crate::bridge_config::KusamaGlobalConsensusNetwork::get()),
205 Parachain(<bp_moonriver::Moonriver as bp_runtime::Parachain>::PARACHAIN_ID),
206 PalletInstance(<Balances as PalletInfoAccess>::index() as u8),
207 ],
208 ),
209 relative_price: GLMR,
210 }],
211 _phantom: Default::default(),
212 },
213 bridge_kusama_grandpa: BridgeKusamaGrandpaConfig {
214 owner: Some(endowed_accounts[0]),
215 init_data: None,
216 },
217 bridge_kusama_parachains: BridgeKusamaParachainsConfig {
218 owner: Some(endowed_accounts[0]),
219 operating_mode: BasicOperatingMode::Normal,
220 ..Default::default()
221 },
222 bridge_kusama_messages: BridgeKusamaMessagesConfig {
223 owner: Some(endowed_accounts[0]),
224 opened_lanes: vec![],
225 operating_mode: MessagesOperatingMode::Basic(BasicOperatingMode::Normal),
226 _phantom: Default::default(),
227 },
228 bridge_xcm_over_moonriver: BridgeXcmOverMoonriverConfig {
229 opened_bridges: vec![(
230 Location::new(
231 1,
232 [Parachain(
233 <bp_moonbeam::Moonbeam as bp_runtime::Parachain>::PARACHAIN_ID,
234 )],
235 ),
236 Junctions::from([
237 NetworkId::Kusama.into(),
238 Parachain(<bp_moonriver::Moonriver as bp_runtime::Parachain>::PARACHAIN_ID),
239 ]),
240 Some(Default::default()),
241 )],
242 _phantom: Default::default(),
243 },
244 };
245
246 serde_json::to_value(&config).expect("Could not build genesis config.")
247}
248
249pub fn development() -> serde_json::Value {
251 testnet_genesis(
252 vec![
254 AccountId::from(sp_core::hex2array!(
255 "3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0"
256 )),
257 AccountId::from(sp_core::hex2array!(
258 "798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc"
259 )),
260 AccountId::from(sp_core::hex2array!(
261 "773539d4Ac0e786233D90A233654ccEE26a613D9"
262 )),
263 ],
264 vec![
266 AccountId::from(sp_core::hex2array!(
267 "f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
268 )),
269 AccountId::from(sp_core::hex2array!(
270 "3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0"
271 )),
272 ],
273 vec![(
275 AccountId::from(sp_core::hex2array!(
276 "f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
277 )),
278 NimbusId::from(Sr25519Keyring::Alice.public()),
279 20_000 * GLMR * SUPPLY_FACTOR,
280 )],
281 vec![],
283 vec![
284 AccountId::from(sp_core::hex2array!(
285 "f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac"
286 )),
287 AccountId::from(sp_core::hex2array!(
288 "3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0"
289 )),
290 AccountId::from(sp_core::hex2array!(
291 "798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc"
292 )),
293 AccountId::from(sp_core::hex2array!(
294 "773539d4Ac0e786233D90A233654ccEE26a613D9"
295 )),
296 ],
297 Default::default(), 1281, )
300}
301
302pub fn get_preset(id: &PresetId) -> Option<Vec<u8>> {
304 let patch = match id.as_str() {
305 sp_genesis_builder::DEV_RUNTIME_PRESET => development(),
306 _ => return None,
307 };
308 Some(
309 serde_json::to_string(&patch)
310 .expect("serialization to json is expected to work. qed.")
311 .into_bytes(),
312 )
313}
314
315pub fn preset_names() -> Vec<PresetId> {
317 vec![PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET)]
318}