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