1use crate::blueprints::account::AccountOwnerBadgeData;
2use crate::blueprints::identity::IdentityOwnerBadgeData;
3use crate::blueprints::native_schema::*;
4use crate::blueprints::package::*;
5use crate::blueprints::transaction_tracker::*;
6use crate::internal_prelude::*;
7use crate::system::system_db_reader::SystemDatabaseReader;
8use crate::transaction::*;
9use crate::updates::*;
10use crate::vm::VmBoot;
11use lazy_static::lazy_static;
12use radix_common::crypto::Secp256k1PublicKey;
13use radix_common::math::traits::*;
14use radix_common::types::ComponentAddress;
15use radix_engine_interface::blueprints::consensus_manager::*;
16use radix_engine_interface::blueprints::package::*;
17use radix_engine_interface::blueprints::resource::*;
18use radix_engine_interface::blueprints::transaction_tracker::*;
19use radix_engine_interface::object_modules::metadata::{MetadataValue, UncheckedUrl};
20use radix_engine_interface::object_modules::ModuleConfig;
21use radix_engine_interface::*;
22use radix_substate_store_interface::interface::*;
23use radix_transactions::model::*;
24use radix_transactions::prelude::*;
25
26lazy_static! {
27 pub static ref DEFAULT_TESTING_FAUCET_SUPPLY: Decimal = dec!("100000000000000000");
28 pub static ref DEFAULT_VALIDATOR_USD_COST: Decimal = dec!("100");
29 pub static ref DEFAULT_VALIDATOR_XRD_COST: Decimal = DEFAULT_VALIDATOR_USD_COST
30 .checked_mul(Decimal::try_from(USD_PRICE_IN_XRD).unwrap())
31 .unwrap(); }
35
36#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestEncode, ManifestCategorize)]
45pub struct GenesisValidator {
46 pub key: Secp256k1PublicKey,
47 pub accept_delegated_stake: bool,
48 pub is_registered: bool,
49 pub fee_factor: Decimal,
50 pub metadata: Vec<(String, MetadataValue)>,
51 pub owner: ComponentAddress,
52}
53
54impl From<Secp256k1PublicKey> for GenesisValidator {
55 fn from(key: Secp256k1PublicKey) -> Self {
56 let default_owner_address = ComponentAddress::preallocated_account_from_public_key(&key);
58 GenesisValidator {
59 key,
60 accept_delegated_stake: true,
61 is_registered: true,
62 fee_factor: Decimal::ONE,
63 metadata: vec![(
64 "url".to_string(),
65 MetadataValue::Url(UncheckedUrl::of(format!(
66 "http://test.local?validator={:?}",
67 key
68 ))),
69 )],
70 owner: default_owner_address,
71 }
72 }
73}
74
75#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor, ScryptoSbor)]
76pub struct GenesisStakeAllocation {
77 pub account_index: u32,
78 pub xrd_amount: Decimal,
79}
80
81#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor)]
83pub struct GenesisResource {
84 pub reserved_resource_address: ResourceAddress,
85 pub metadata: Vec<(String, MetadataValue)>,
86 pub owner: Option<ComponentAddress>,
87}
88
89#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor, ScryptoSbor)]
90pub struct GenesisResourceAllocation {
91 pub account_index: u32,
92 pub amount: Decimal,
93}
94
95#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor)]
97pub enum GenesisDataChunk {
98 Validators(Vec<GenesisValidator>),
99 Stakes {
100 accounts: Vec<ComponentAddress>,
101 allocations: Vec<(Secp256k1PublicKey, Vec<GenesisStakeAllocation>)>,
102 },
103 Resources(Vec<GenesisResource>),
104 ResourceBalances {
105 accounts: Vec<ComponentAddress>,
106 allocations: Vec<(ResourceAddress, Vec<GenesisResourceAllocation>)>,
107 },
108 XrdBalances(Vec<(ComponentAddress, Decimal)>),
109}
110
111#[derive(Debug, Clone, Eq, PartialEq, ManifestEncode, ManifestCategorize)]
117pub enum ManifestGenesisDataChunk {
118 Validators(Vec<GenesisValidator>),
119 Stakes {
120 accounts: Vec<ComponentAddress>,
121 allocations: Vec<(Secp256k1PublicKey, Vec<GenesisStakeAllocation>)>,
122 },
123 Resources(Vec<ManifestGenesisResource>),
124 ResourceBalances {
125 accounts: Vec<ComponentAddress>,
126 allocations: Vec<(ResourceAddress, Vec<GenesisResourceAllocation>)>,
127 },
128 XrdBalances(Vec<(ComponentAddress, Decimal)>),
129}
130
131#[derive(Debug, Clone, Eq, PartialEq, ManifestEncode, ManifestCategorize)]
132pub struct ManifestGenesisResource {
133 pub resource_address_reservation: ManifestAddressReservation,
134 pub metadata: Vec<(String, MetadataValue)>,
135 pub owner: Option<ComponentAddress>,
136}
137
138#[derive(Debug, Clone)]
144pub struct GenesisReceipts {
145 pub system_flash_receipt: TransactionReceipt,
146 pub system_bootstrap_receipt: TransactionReceipt,
147 pub data_ingestion_receipts: Vec<TransactionReceipt>,
148 pub wrap_up_receipt: TransactionReceipt,
149}
150
151#[derive(Default)]
152pub struct GenesisReceiptExtractionHooks {
153 bootstrap_receipts: Vec<TransactionReceipt>,
154 data_ingestion_receipts: Vec<TransactionReceipt>,
155 wrap_up_receipts: Vec<TransactionReceipt>,
156}
157
158impl GenesisReceiptExtractionHooks {
159 pub fn new() -> Self {
160 Default::default()
161 }
162
163 pub fn into_genesis_receipts(self) -> GenesisReceipts {
164 let [system_flash_receipt, system_bootstrap_receipt] = self
165 .bootstrap_receipts
166 .try_into()
167 .expect("Expected two bootstrap receipts (flash and transaction)");
168 let [wrap_up_receipt] = self
169 .wrap_up_receipts
170 .try_into()
171 .expect("Expected one wrap-up receipt");
172 GenesisReceipts {
173 system_flash_receipt,
174 system_bootstrap_receipt,
175 data_ingestion_receipts: self.data_ingestion_receipts,
176 wrap_up_receipt,
177 }
178 }
179}
180
181impl ProtocolUpdateExecutionHooks for GenesisReceiptExtractionHooks {
182 fn on_transaction_executed(&mut self, event: OnProtocolTransactionExecuted) {
183 let OnProtocolTransactionExecuted {
184 protocol_version,
185 batch_group_index,
186 receipt,
187 ..
188 } = event;
189 if protocol_version == ProtocolVersion::GENESIS {
190 match batch_group_index {
191 0 => self.bootstrap_receipts.push(receipt.clone()),
192 1 => self.data_ingestion_receipts.push(receipt.clone()),
193 2 => self.wrap_up_receipts.push(receipt.clone()),
194 _ => panic!("Unexpected bootstrap batch group index: {batch_group_index}"),
195 }
196 }
197 }
198}
199
200#[derive(Debug, Clone, ScryptoSbor)]
201pub struct FlashReceipt {
202 pub state_updates: StateUpdates,
203 pub state_update_summary: StateUpdateSummary,
204 pub substate_system_structures: SubstateSystemStructures,
205}
206
207impl From<FlashReceipt> for TransactionReceipt {
208 fn from(value: FlashReceipt) -> Self {
209 let mut commit_result =
212 CommitResult::empty_with_outcome(TransactionOutcome::Success(vec![]));
213 commit_result.state_updates = value.state_updates;
214 commit_result.state_update_summary = value.state_update_summary;
215 commit_result.system_structure.substate_system_structures =
216 value.substate_system_structures;
217 TransactionReceipt::empty_with_commit(commit_result)
218 }
219}
220
221impl FlashReceipt {
222 pub fn from_state_updates(
223 state_updates: StateUpdates,
224 before_store: &impl SubstateDatabase,
225 ) -> Self {
226 let state_updates = state_updates.rebuild_without_empty_entries();
227 let state_update_summary =
228 StateUpdateSummary::new_from_state_updates_on_db(before_store, &state_updates);
229 let substate_system_structures = {
230 let after_store = SystemDatabaseReader::new_with_overlay(before_store, &state_updates);
231 let mut substate_schema_mapper = SubstateSchemaMapper::new(after_store);
232 substate_schema_mapper.add_for_all_individually_updated(&state_updates);
233 substate_schema_mapper.done()
234 };
235 Self {
236 state_updates,
237 state_update_summary,
238 substate_system_structures,
239 }
240 }
241}
242
243pub fn create_system_bootstrap_flash_state_updates() -> StateUpdates {
244 let package_flashes = [
247 (
248 PACKAGE_PACKAGE,
249 PACKAGE_PACKAGE_DEFINITION.clone(),
250 NativeCodeId::PackageCode1 as u64,
251 metadata_init! {
252 "name" => "Package Package".to_owned(), locked;
253 "description" => "A native package that is called to create a new package on the network.".to_owned(), locked;
254 },
255 btreemap! {
257 PACKAGE_BLUEPRINT.to_string() => vec![SystemInstruction::MapCollectionToPhysicalPartition {
258 collection_index: PackageCollection::SchemaKeyValue.collection_index(),
259 partition_num: SCHEMAS_PARTITION,
260 }],
261 },
262 ),
263 (
264 ROYALTY_MODULE_PACKAGE,
265 ROYALTY_PACKAGE_DEFINITION.clone(),
266 NativeCodeId::RoyaltyCode1 as u64,
267 metadata_init! {
268 "name" => "Royalty Package".to_owned(), locked;
269 "description" => "A native package that defines the logic of the royalty module used by components.".to_owned(), locked;
270 },
271 btreemap!(),
272 ),
273 (
274 RESOURCE_PACKAGE,
275 RESOURCE_PACKAGE_DEFINITION.clone(),
276 NativeCodeId::ResourceCode1 as u64,
277 metadata_init! {
278 "name" => "Resource Package".to_owned(), locked;
279 "description" => "A native package that is called to create a new resource manager on the network.".to_owned(), locked;
280 },
281 btreemap!(),
282 ),
283 (
284 TRANSACTION_PROCESSOR_PACKAGE,
285 TRANSACTION_PROCESSOR_PACKAGE_DEFINITION.clone(),
286 NativeCodeId::TransactionProcessorCode1 as u64,
287 metadata_init! {
288 "name" => "Transaction Processor Package".to_owned(), locked;
289 "description" => "A native package that defines the logic of the processing of manifest instructions and transaction runtime.".to_owned(), locked;
290 },
291 btreemap!(),
292 ),
293 (
294 METADATA_MODULE_PACKAGE,
295 METADATA_PACKAGE_DEFINITION.clone(),
296 NativeCodeId::MetadataCode1 as u64,
297 metadata_init! {
298 "name" => "Metadata Package".to_owned(), locked;
299 "description" => "A native package that defines the logic of the metadata module that is used by resources, components, and packages.".to_owned(), locked;
300 },
301 btreemap!(),
302 ),
303 (
304 ROLE_ASSIGNMENT_MODULE_PACKAGE,
305 ROLE_ASSIGNMENT_PACKAGE_DEFINITION.clone(),
306 NativeCodeId::RoleAssignmentCode1 as u64,
307 metadata_init! {
308 "name" => "Access Rules Package".to_owned(), locked;
309 "description" => "A native package that defines the logic of the access rules module that is used by resources, components, and packages.".to_owned(), locked;
310 },
311 btreemap!(),
312 ),
313 (
314 TEST_UTILS_PACKAGE,
315 TEST_UTILS_PACKAGE_DEFINITION.clone(),
316 NativeCodeId::TestUtilsCode1 as u64,
317 metadata_init! {
318 "name" => "Test Utils Package".to_owned(), locked;
319 "description" => "A native package that contains a set of useful functions to use in testing.".to_owned(), locked;
320 },
321 btreemap!(),
322 ),
323 ];
324
325 let mut to_flash = StateUpdates::empty();
326
327 for (address, definition, native_code_id, metadata_init, system_instructions) in package_flashes
328 {
329 let partitions = {
330 let package_structure = PackageNativePackage::validate_and_build_package_structure(
331 definition,
332 VmType::Native,
333 native_code_id.to_be_bytes().to_vec(),
334 system_instructions,
335 false,
336 &VmBoot::babylon_genesis(),
337 )
338 .unwrap_or_else(|err| {
339 panic!(
340 "Invalid flashed Package definition with native_code_id {}: {:?}",
341 native_code_id, err
342 )
343 });
344
345 create_package_partition_substates(package_structure, metadata_init, None)
346 };
347
348 for (partition_num, partition_substates) in partitions {
349 let partition_updates: IndexMap<_, _> = partition_substates
350 .into_iter()
351 .map(|(key, value)| (key, DatabaseUpdate::Set(value.into())))
352 .collect();
353
354 if !partition_updates.is_empty() {
356 to_flash
357 .of_node(address)
358 .of_partition(partition_num)
359 .mut_update_substates(partition_updates);
360 }
361 }
362 }
363
364 to_flash
365}
366
367pub fn create_substate_flash_for_genesis() -> FlashReceipt {
368 let state_updates = create_system_bootstrap_flash_state_updates();
369 FlashReceipt::from_state_updates(state_updates, &EmptySubstateDatabase)
370}
371
372struct EmptySubstateDatabase;
373
374impl SubstateDatabase for EmptySubstateDatabase {
375 fn get_raw_substate_by_db_key(
376 &self,
377 _partition_key: &DbPartitionKey,
378 _sort_key: &DbSortKey,
379 ) -> Option<DbSubstateValue> {
380 None
381 }
382
383 fn list_raw_values_from_db_key(
384 &self,
385 _partition_key: &DbPartitionKey,
386 _from_sort_key: Option<&DbSortKey>,
387 ) -> Box<dyn Iterator<Item = PartitionEntry> + '_> {
388 Box::new(core::iter::empty())
389 }
390}
391
392pub fn create_system_bootstrap_transaction(
393 initial_epoch: Epoch,
394 initial_config: ConsensusManagerConfig,
395 initial_time_ms: i64,
396 initial_current_leader: Option<ValidatorIndex>,
397 faucet_supply: Decimal,
398) -> SystemTransactionV1 {
399 let mut manifest_builder = ManifestBuilder::new_system_v1();
400 let lookup = manifest_builder.name_lookup();
401
402 {
404 let xrd_reservation = manifest_builder.use_preallocated_address(
405 XRD,
406 RESOURCE_PACKAGE,
407 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
408 );
409 manifest_builder = manifest_builder.call_function(
410 RESOURCE_PACKAGE,
411 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
412 FUNGIBLE_RESOURCE_MANAGER_CREATE_WITH_INITIAL_SUPPLY_IDENT,
413 FungibleResourceManagerCreateWithInitialSupplyManifestInput {
414 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
415 track_total_supply: false,
416 divisibility: 18,
417 resource_roles: FungibleResourceRoles {
418 mint_roles: mint_roles! {
419 minter => rule!(require(global_caller(CONSENSUS_MANAGER)));
420 minter_updater => rule!(deny_all);
421 },
422 burn_roles: burn_roles! {
423 burner => rule!(require(global_caller(CONSENSUS_MANAGER)));
424 burner_updater => rule!(deny_all);
425 },
426 ..Default::default()
427 }.into(),
428 metadata: metadata! {
429 init {
430 "symbol" => "XRD".to_owned(), locked;
431 "name" => "Radix".to_owned(), locked;
432 "description" => "The Radix Public Network's native token, used to pay the network's required transaction fees and to secure the network through staking to its validator nodes.".to_owned(), locked;
433 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-xrd-32x32.png"), locked;
434 "info_url" => UncheckedUrl::of("https://tokens.radixdlt.com"), locked;
435 "tags" => Vec::<String>::new(), locked;
436 }
437 }.into(),
438 initial_supply: Decimal::zero(),
439 address_reservation: Some(xrd_reservation),
440 },
441 );
442 }
443
444 {
446 let reservation = manifest_builder.use_preallocated_address(
447 PACKAGE_OF_DIRECT_CALLER_RESOURCE,
448 RESOURCE_PACKAGE,
449 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
450 );
451 manifest_builder = manifest_builder.call_function(
452 RESOURCE_PACKAGE,
453 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
454 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
455 NonFungibleResourceManagerCreateManifestInput {
456 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
457 id_type: NonFungibleIdType::Bytes,
458 track_total_supply: false,
459 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<()>(),
460 resource_roles: NonFungibleResourceRoles {
461 withdraw_roles: withdraw_roles! {
462 withdrawer => rule!(deny_all);
463 withdrawer_updater => rule!(deny_all);
464 },
465 ..Default::default()
466 }.into(),
467 metadata: metadata! {
468 init {
469 "name" => "Package Virtual Badges".to_owned(), locked;
470 "description" => "Virtual badges generated automatically by the Radix system to represent the authority of the package for a direct caller. These badges cease to exist at the end of their transaction.".to_owned(), locked;
471 "tags" => vec!["badge".to_owned()], locked;
472 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-package_of_direct_caller_virtual_badge.png"), locked;
473 }
474 }
475 .into(),
476 address_reservation: Some(reservation),
477 },
478 );
479 }
480
481 {
483 let reservation = manifest_builder.use_preallocated_address(
484 GLOBAL_CALLER_RESOURCE,
485 RESOURCE_PACKAGE,
486 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
487 );
488 manifest_builder = manifest_builder.call_function(
489 RESOURCE_PACKAGE,
490 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
491 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
492 NonFungibleResourceManagerCreateManifestInput {
493 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
494 id_type: NonFungibleIdType::Bytes,
495 track_total_supply: false,
496 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<()>(),
497 resource_roles: NonFungibleResourceRoles {
498 withdraw_roles: withdraw_roles! {
499 withdrawer => rule!(deny_all);
500 withdrawer_updater => rule!(deny_all);
501 },
502 ..Default::default()
503 }.into(),
504 metadata: metadata! {
505 init {
506 "name" => "Global Caller Virtual Badges".to_owned(), locked;
507 "description" => "Virtual badges generated automatically by the Radix system to represent the authority of a global caller. These badges cease to exist at the end of their transaction.".to_owned(), locked;
508 "tags" => vec!["badge".to_owned()], locked;
509 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-global_caller_virtual_badge.png"), locked;
510 }
511 }.into(),
512 address_reservation: Some(reservation),
513 },
514 );
515 }
516
517 {
519 let reservation = manifest_builder.use_preallocated_address(
520 PACKAGE_OWNER_BADGE,
521 RESOURCE_PACKAGE,
522 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
523 );
524 manifest_builder = manifest_builder.call_function(
525 RESOURCE_PACKAGE,
526 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
527 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
528 NonFungibleResourceManagerCreateManifestInput {
529 owner_role: OwnerRole::Fixed(rule!(require(global_caller(PACKAGE_PACKAGE)))).into(),
530 id_type: NonFungibleIdType::Bytes,
531 track_total_supply: false,
532 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<PackageOwnerBadgeData>(),
533 resource_roles: NonFungibleResourceRoles {
534 mint_roles: mint_roles! {
535 minter => rule!(require(package_of_direct_caller(PACKAGE_PACKAGE)));
536 minter_updater => rule!(deny_all);
537 },
538 ..Default::default()
539 }.into(),
540 metadata: metadata! {
541 init {
542 "name" => "Package Owner Badges".to_owned(), locked;
543 "description" => "Badges created by the Radix system that provide individual control over blueprint packages deployed by developers.".to_owned(), locked;
544 "tags" => vec!["badge".to_owned(), "package".to_owned()], locked;
545 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-package_owner_badge.png"), locked;
546 }
547 }.into(),
548 address_reservation: Some(reservation),
549 },
550 );
551 }
552
553 {
555 let badge_reservation = manifest_builder.use_preallocated_address(
556 IDENTITY_OWNER_BADGE,
557 RESOURCE_PACKAGE,
558 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
559 );
560 manifest_builder = manifest_builder.call_function(
561 RESOURCE_PACKAGE,
562 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
563 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
564 NonFungibleResourceManagerCreateManifestInput {
565 owner_role: OwnerRole::Fixed(rule!(require(global_caller(IDENTITY_PACKAGE)))).into(),
566 id_type: NonFungibleIdType::Bytes,
567 track_total_supply: false,
568 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<IdentityOwnerBadgeData>(),
569 resource_roles: NonFungibleResourceRoles {
570 mint_roles: mint_roles! {
571 minter => rule!(require(package_of_direct_caller(IDENTITY_PACKAGE)));
572 minter_updater => rule!(deny_all);
573 },
574 ..Default::default()
575 }.into(),
576 metadata: metadata! {
577 init {
578 "name" => "Identity Owner Badges".to_owned(), locked;
579 "description" => "Badges created by the Radix system that provide individual control over identity components.".to_owned(), locked;
580 "tags" => vec!["badge".to_owned(), "identity".to_owned()], locked;
581 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-identity_owner_badge.png"), locked;
582 }
583 }.into(),
584 address_reservation: Some(badge_reservation),
585 },
586 );
587
588 let package_reservation = manifest_builder.use_preallocated_address(
589 IDENTITY_PACKAGE,
590 PACKAGE_PACKAGE,
591 PACKAGE_BLUEPRINT,
592 );
593 manifest_builder = manifest_builder.call_function(
594 PACKAGE_PACKAGE,
595 PACKAGE_BLUEPRINT,
596 PACKAGE_PUBLISH_NATIVE_IDENT,
597 PackagePublishNativeManifestInput {
598 package_address: Some(package_reservation),
599 definition: IDENTITY_PACKAGE_DEFINITION.clone().into(),
600 native_package_code_id: NativeCodeId::IdentityCode1 as u64,
601 metadata: metadata_init! {
602 "name" => "Identity Package".to_owned(), locked;
603 "description" => "A native package that defines the logic of identity components.".to_owned(), locked;
604 }.into(),
605 },
606 );
607 }
608
609 {
611 let reservation = manifest_builder.use_preallocated_address(
612 CONSENSUS_MANAGER_PACKAGE,
613 PACKAGE_PACKAGE,
614 PACKAGE_BLUEPRINT,
615 );
616 manifest_builder = manifest_builder.call_function(
617 PACKAGE_PACKAGE,
618 PACKAGE_BLUEPRINT,
619 PACKAGE_PUBLISH_NATIVE_IDENT,
620 PackagePublishNativeManifestInput {
621 package_address: Some(reservation),
622 definition: CONSENSUS_MANAGER_PACKAGE_DEFINITION.clone().into(),
623 native_package_code_id: NativeCodeId::ConsensusManagerCode1 as u64,
624 metadata: metadata_init! {
625 "name" => "Consensus Manager Package".to_owned(), locked;
626 "description" => "A native package that may be used to get network consensus information.".to_owned(), locked;
627 }.into(),
628 },
629 );
630 }
631
632 {
634 let badge_reservation = manifest_builder.use_preallocated_address(
635 ACCOUNT_OWNER_BADGE,
636 RESOURCE_PACKAGE,
637 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
638 );
639 manifest_builder = manifest_builder.call_function(
640 RESOURCE_PACKAGE,
641 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
642 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
643 NonFungibleResourceManagerCreateManifestInput {
644 owner_role: OwnerRole::Fixed(rule!(require(global_caller(ACCOUNT_PACKAGE)))).into(),
645 id_type: NonFungibleIdType::Bytes,
646 track_total_supply: false,
647 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<AccountOwnerBadgeData>(),
648 resource_roles: NonFungibleResourceRoles {
649 mint_roles: mint_roles! {
650 minter => rule!(require(package_of_direct_caller(ACCOUNT_PACKAGE)));
651 minter_updater => rule!(deny_all);
652 },
653 ..Default::default()
654 }.into(),
655 metadata: metadata! {
656 init {
657 "name" => "Account Owner Badges".to_owned(), locked;
658 "description" => "Badges created by the Radix system that provide individual control over account components.".to_owned(), locked;
659 "tags" => vec![
660 "badge".to_owned(),
661 "account".to_owned(),
662 ], locked;
663 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-account_owner_badge.png"), locked;
664 }
665 }.into(),
666 address_reservation: Some(badge_reservation),
667 },
668 );
669
670 let package_reservation = manifest_builder.use_preallocated_address(
671 ACCOUNT_PACKAGE,
672 PACKAGE_PACKAGE,
673 PACKAGE_BLUEPRINT,
674 );
675 manifest_builder = manifest_builder.call_function(
676 PACKAGE_PACKAGE,
677 PACKAGE_BLUEPRINT,
678 PACKAGE_PUBLISH_NATIVE_IDENT,
679 PackagePublishNativeManifestInput {
680 package_address: Some(package_reservation),
681 definition: ACCOUNT_PACKAGE_DEFINITION.clone().into(),
682 native_package_code_id: NativeCodeId::AccountCode1 as u64,
683 metadata: metadata_init! {
684 "name" => "Account Package".to_owned(), locked;
685 "description" => "A native package that defines the logic of account components.".to_owned(), locked;
686 }.into(),
687 },
688 );
689 }
690
691 {
693 let reservation = manifest_builder.use_preallocated_address(
694 ACCESS_CONTROLLER_PACKAGE,
695 PACKAGE_PACKAGE,
696 PACKAGE_BLUEPRINT,
697 );
698 manifest_builder = manifest_builder.call_function(
699 PACKAGE_PACKAGE,
700 PACKAGE_BLUEPRINT,
701 PACKAGE_PUBLISH_NATIVE_IDENT,
702 PackagePublishNativeManifestInput {
703 package_address: Some(reservation),
704 definition: ACCESS_CONTROLLER_PACKAGE_DEFINITION_V1_0.clone().into(),
705 metadata: metadata_init! {
706 "name" => "Access Controller Package".to_owned(), locked;
707 "description" => "A native package that defines the logic of access controller components.".to_owned(), locked;
708 }.into(),
709 native_package_code_id: NativeCodeId::AccessControllerCode1 as u64,
710 },
711 );
712 }
713
714 {
716 let reservation = manifest_builder.use_preallocated_address(
717 POOL_PACKAGE,
718 PACKAGE_PACKAGE,
719 PACKAGE_BLUEPRINT,
720 );
721 manifest_builder = manifest_builder.call_function(
722 PACKAGE_PACKAGE,
723 PACKAGE_BLUEPRINT,
724 PACKAGE_PUBLISH_NATIVE_IDENT,
725 PackagePublishNativeManifestInput {
726 package_address: Some(reservation),
727 definition: POOL_PACKAGE_DEFINITION_V1_0.clone().into(),
728 metadata: metadata_init! {
729 "name" => "Pool Package".to_owned(), locked;
730 "description" => "A native package that defines the logic for a selection of pool components.".to_owned(), locked;
731 }.into(),
732 native_package_code_id: NativeCodeId::PoolCode1 as u64,
733 },
734 );
735 }
736
737 {
739 let reservation = manifest_builder.use_preallocated_address(
740 SECP256K1_SIGNATURE_RESOURCE,
741 RESOURCE_PACKAGE,
742 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
743 );
744 manifest_builder = manifest_builder.call_function(
745 RESOURCE_PACKAGE,
746 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
747 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
748 NonFungibleResourceManagerCreateManifestInput {
749 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
750 id_type: NonFungibleIdType::Bytes,
751 track_total_supply: false,
752 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<()>(),
753 resource_roles: NonFungibleResourceRoles::default().into(),
754 metadata: metadata! {
755 init {
756 "name" => "ECDSA secp256k1 Virtual Badges".to_owned(), locked;
757 "description" => "Virtual badges generated automatically by the Radix system to represent ECDSA secp256k1 signatures applied to transactions. These badges cease to exist at the end of their transaction.".to_owned(), locked;
758 "tags" => vec!["badge".to_owned()], locked;
759 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-ecdsa_secp256k1_signature_virtual_badge.png"), locked;
760 }
761 }.into(),
762 address_reservation: Some(reservation),
763 }
764 );
765 }
766
767 {
769 let reservation = manifest_builder.use_preallocated_address(
770 ED25519_SIGNATURE_RESOURCE,
771 RESOURCE_PACKAGE,
772 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
773 );
774 manifest_builder = manifest_builder.call_function(
775 RESOURCE_PACKAGE,
776 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
777 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
778 NonFungibleResourceManagerCreateManifestInput {
779 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
780 id_type: NonFungibleIdType::Bytes,
781 track_total_supply: false,
782 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<()>(),
783 resource_roles: NonFungibleResourceRoles::default().into(),
784 metadata: metadata! {
785 init {
786 "name" => "EdDSA Ed25519 Virtual Badges".to_owned(), locked;
787 "description" => "Virtual badges generated automatically by the Radix system to represent EdDSA Ed25519 signatures applied to transactions. These badges cease to exist at the end of their transaction.".to_owned(), locked;
788 "tags" => vec!["badge".to_owned()], locked;
789 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-eddsa_ed25519_signature_virtual_badge.png"), locked;
790 }
791 }.into(),
792 address_reservation: Some(reservation),
793 },
794 );
795 }
796
797 {
799 let reservation = manifest_builder.use_preallocated_address(
800 SYSTEM_EXECUTION_RESOURCE,
801 RESOURCE_PACKAGE,
802 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
803 );
804 manifest_builder = manifest_builder.call_function(
805 RESOURCE_PACKAGE,
806 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
807 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
808 NonFungibleResourceManagerCreateManifestInput {
809 owner_role: OwnerRole::Fixed(rule!(require(system_execution(SystemExecution::Protocol)))).into(),
810 id_type: NonFungibleIdType::Integer,
811 track_total_supply: false,
812 non_fungible_schema: NonFungibleDataSchema::new_local_without_self_package_replacement::<()>(),
813 resource_roles: NonFungibleResourceRoles::default().into(),
814 metadata: metadata! {
815 init {
816 "name" => "System Transaction Badge".to_owned(), locked;
817 "description" => "Virtual badges are created under this resource to represent the Radix system's authority at genesis and to affect changes to system entities during protocol updates, or to represent the Radix system's authority in the regularly occurring system transactions including round and epoch changes.".to_owned(), locked;
818 "tags" => vec!["badge".to_owned(), "system badge".to_owned()], locked;
819 "icon_url" => UncheckedUrl::of("https://assets.radixdlt.com/icons/icon-system_transaction_badge.png"), locked;
820 }
821 }.into(),
822 address_reservation: Some(reservation),
823 },
824 );
825 }
826
827 {
829 let reservation: ManifestAddressReservation = manifest_builder.use_preallocated_address(
830 FAUCET_PACKAGE,
831 PACKAGE_PACKAGE,
832 PACKAGE_BLUEPRINT,
833 );
834 manifest_builder = manifest_builder.publish_package_advanced(
835 reservation,
836 include_bytes!("../../assets/faucet.wasm").to_vec(),
837 manifest_decode::<ManifestPackageDefinition>(include_bytes!("../../assets/faucet.rpd")).unwrap().try_into_typed().unwrap(),
838 metadata_init!{
839 "name" => "Faucet Package".to_owned(), locked;
840 "description" => "A package that defines the logic of a simple faucet component for testing purposes.".to_owned(), locked;
841 },
842 OwnerRole::None
843 );
844 }
845
846 {
848 let reservation = manifest_builder.use_preallocated_address(
849 GENESIS_HELPER_PACKAGE,
850 PACKAGE_PACKAGE,
851 PACKAGE_BLUEPRINT,
852 );
853 manifest_builder = manifest_builder.publish_package_advanced(
854 reservation,
855 include_bytes!("../../assets/genesis_helper.wasm").to_vec(),
856 manifest_decode::<ManifestPackageDefinition>(include_bytes!("../../assets/genesis_helper.rpd")).unwrap().try_into_typed().unwrap(),
857 metadata_init! {
858 "name" => "Genesis Helper Package".to_owned(), locked;
859 "description" => "A package that defines the logic of the genesis helper which includes various utility and helper functions used in the creation of the Babylon Genesis.".to_owned(), locked;
860 },
861 OwnerRole::None,
862 );
863 }
864
865 {
867 let badge_reservation = manifest_builder.use_preallocated_address(
868 VALIDATOR_OWNER_BADGE,
869 RESOURCE_PACKAGE,
870 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
871 );
872 let manager_reservation = manifest_builder.use_preallocated_address(
873 CONSENSUS_MANAGER,
874 CONSENSUS_MANAGER_PACKAGE,
875 CONSENSUS_MANAGER_BLUEPRINT,
876 );
877 manifest_builder = manifest_builder.call_function(
878 CONSENSUS_MANAGER_PACKAGE,
879 CONSENSUS_MANAGER_BLUEPRINT,
880 CONSENSUS_MANAGER_CREATE_IDENT,
881 ConsensusManagerCreateManifestInput {
882 validator_owner_token_address: badge_reservation,
883 component_address: manager_reservation,
884 initial_epoch,
885 initial_config,
886 initial_time_ms,
887 initial_current_leader,
888 },
889 );
890 }
891
892 {
894 let reservation = manifest_builder.use_preallocated_address(
895 GENESIS_HELPER,
896 GENESIS_HELPER_PACKAGE,
897 GENESIS_HELPER_BLUEPRINT,
898 );
899 manifest_builder = manifest_builder.call_function(
900 GENESIS_HELPER_PACKAGE,
901 GENESIS_HELPER_BLUEPRINT,
902 "new",
903 (
904 reservation,
905 CONSENSUS_MANAGER,
906 system_execution(SystemExecution::Protocol),
907 ),
908 );
909 }
910
911 {
913 let reservation = manifest_builder.use_preallocated_address(
914 TRANSACTION_TRACKER_PACKAGE,
915 PACKAGE_PACKAGE,
916 PACKAGE_BLUEPRINT,
917 );
918 manifest_builder = manifest_builder.call_function(
919 PACKAGE_PACKAGE,
920 PACKAGE_BLUEPRINT,
921 PACKAGE_PUBLISH_NATIVE_IDENT,
922 PackagePublishNativeManifestInput {
923 package_address: Some(reservation),
924 native_package_code_id: NativeCodeId::TransactionTrackerCode1 as u64,
925 definition: TRANSACTION_TRACKER_PACKAGE_DEFINITION.clone().into(),
926 metadata: metadata_init!().into(),
927 },
928 );
929 }
930
931 {
933 let reservation = manifest_builder.use_preallocated_address(
934 TRANSACTION_TRACKER,
935 TRANSACTION_TRACKER_PACKAGE,
936 TRANSACTION_TRACKER_BLUEPRINT,
937 );
938 manifest_builder = manifest_builder.call_function(
939 TRANSACTION_TRACKER_PACKAGE,
940 TRANSACTION_TRACKER_BLUEPRINT,
941 TRANSACTION_TRACKER_CREATE_IDENT,
942 (reservation,),
943 );
944 }
945
946 {
950 let reservation =
951 manifest_builder.use_preallocated_address(FAUCET, FAUCET_PACKAGE, FAUCET_BLUEPRINT);
952 manifest_builder = manifest_builder
955 .mint_fungible(XRD, faucet_supply)
956 .take_from_worktop(XRD, faucet_supply, "faucet_xrd")
957 .call_function(
958 FAUCET_PACKAGE,
959 FAUCET_BLUEPRINT,
960 "new",
961 (reservation, lookup.bucket("faucet_xrd")),
962 );
963 }
964
965 manifest_builder
966 .build()
967 .into_transaction(hash("Genesis Bootstrap"))
968}
969
970pub fn create_genesis_data_ingestion_transaction(
971 chunk: GenesisDataChunk,
972 chunk_index: usize,
973) -> SystemTransactionV1 {
974 map_address_allocations_for_manifest(chunk)
975 .into_transaction(hash(format!("Genesis Data Chunk: {}", chunk_index)))
976}
977
978fn map_address_allocations_for_manifest(
979 genesis_data_chunk: GenesisDataChunk,
980) -> SystemTransactionManifestV1 {
981 let mut manifest_builder = SystemManifestV1Builder::new_system_v1();
982 let data_chunk = match genesis_data_chunk {
983 GenesisDataChunk::Validators(content) => ManifestGenesisDataChunk::Validators(content),
984 GenesisDataChunk::Stakes {
985 accounts,
986 allocations,
987 } => ManifestGenesisDataChunk::Stakes {
988 accounts,
989 allocations,
990 },
991 GenesisDataChunk::Resources(genesis_resources) => {
992 let resources = genesis_resources
993 .into_iter()
994 .map(|genesis_resource| ManifestGenesisResource {
995 resource_address_reservation: manifest_builder.use_preallocated_address(
996 genesis_resource.reserved_resource_address,
997 RESOURCE_PACKAGE,
998 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
999 ),
1000 metadata: genesis_resource.metadata,
1001 owner: genesis_resource.owner,
1002 })
1003 .collect();
1004 ManifestGenesisDataChunk::Resources(resources)
1005 }
1006 GenesisDataChunk::ResourceBalances {
1007 accounts,
1008 allocations,
1009 } => ManifestGenesisDataChunk::ResourceBalances {
1010 accounts,
1011 allocations,
1012 },
1013 GenesisDataChunk::XrdBalances(content) => ManifestGenesisDataChunk::XrdBalances(content),
1014 };
1015 manifest_builder
1016 .call_method(GENESIS_HELPER, "ingest_data_chunk", (data_chunk,))
1017 .build()
1018}
1019
1020pub fn create_genesis_wrap_up_transaction() -> SystemTransactionV1 {
1021 let manifest = ManifestBuilder::new_system_v1()
1022 .call_method(GENESIS_HELPER, "wrap_up", ())
1023 .build();
1024
1025 manifest.into_transaction(hash("Genesis Wrap Up"))
1026}