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