1use super::*;
2use crate::blueprints::access_controller::v1::AccessControllerV1NativePackage;
3use crate::blueprints::access_controller::v2::AccessControllerV2NativePackage;
4use crate::blueprints::locker::LockerNativePackage;
5use crate::blueprints::models::KeyValueEntryContentSource;
6use crate::blueprints::package::*;
7use crate::internal_prelude::*;
8use crate::kernel::kernel::*;
9use crate::object_modules::role_assignment::*;
10use crate::system::system_callback::*;
11use crate::system::system_db_reader::*;
12use crate::vm::*;
13use radix_engine_interface::blueprints::access_controller::*;
14use radix_engine_interface::blueprints::account::*;
15use radix_engine_interface::blueprints::transaction_processor::*;
16
17#[derive(Clone, ScryptoSbor)]
18pub struct BottlenoseSettings {
19 pub add_owner_role_getter: UpdateSetting<NoSettings>,
21
22 pub add_locker_package: UpdateSetting<NoSettings>,
24
25 pub fix_account_try_deposit_or_refund_behaviour: UpdateSetting<NoSettings>,
28
29 pub move_protocol_params_to_state: UpdateSetting<ProtocolParamsSettings>,
31
32 pub update_access_controller_to_add_xrd_fee_vault: UpdateSetting<NoSettings>,
34
35 pub impose_a_limit_on_transaction_processor_blobs: UpdateSetting<NoSettings>,
37
38 pub apply_costing_for_ref_checks: UpdateSetting<NoSettings>,
40
41 pub restrict_reserved_role_key: UpdateSetting<NoSettings>,
43}
44
45#[derive(Clone, Sbor)]
46pub struct ProtocolParamsSettings {
47 pub network_definition: NetworkDefinition,
48}
49
50impl UpdateSettingContent for ProtocolParamsSettings {
51 fn default_setting(network_definition: &NetworkDefinition) -> Self {
52 Self {
53 network_definition: network_definition.clone(),
54 }
55 }
56}
57
58impl UpdateSettings for BottlenoseSettings {
59 type UpdateGenerator = BottlenoseGenerator;
60
61 fn protocol_version() -> ProtocolVersion {
62 ProtocolVersion::Bottlenose
63 }
64
65 fn all_enabled_as_default_for_network(network: &NetworkDefinition) -> Self {
66 Self {
67 add_owner_role_getter: UpdateSetting::enabled_as_default_for_network(network),
68 add_locker_package: UpdateSetting::enabled_as_default_for_network(network),
69 move_protocol_params_to_state: UpdateSetting::enabled_as_default_for_network(network),
70 fix_account_try_deposit_or_refund_behaviour:
71 UpdateSetting::enabled_as_default_for_network(network),
72 update_access_controller_to_add_xrd_fee_vault:
73 UpdateSetting::enabled_as_default_for_network(network),
74 impose_a_limit_on_transaction_processor_blobs:
75 UpdateSetting::enabled_as_default_for_network(network),
76 apply_costing_for_ref_checks: UpdateSetting::enabled_as_default_for_network(network),
77 restrict_reserved_role_key: UpdateSetting::enabled_as_default_for_network(network),
78 }
79 }
80
81 fn all_disabled() -> Self {
82 Self {
83 add_owner_role_getter: UpdateSetting::Disabled,
84 add_locker_package: UpdateSetting::Disabled,
85 move_protocol_params_to_state: UpdateSetting::Disabled,
86 fix_account_try_deposit_or_refund_behaviour: UpdateSetting::Disabled,
87 update_access_controller_to_add_xrd_fee_vault: UpdateSetting::Disabled,
88 impose_a_limit_on_transaction_processor_blobs: UpdateSetting::Disabled,
89 apply_costing_for_ref_checks: UpdateSetting::Disabled,
90 restrict_reserved_role_key: UpdateSetting::Disabled,
91 }
92 }
93
94 fn create_generator(&self) -> Self::UpdateGenerator {
95 BottlenoseGenerator {
96 settings: self.clone(),
97 }
98 }
99}
100
101pub struct BottlenoseGenerator {
102 settings: BottlenoseSettings,
103}
104
105impl ProtocolUpdateGenerator for BottlenoseGenerator {
106 fn insert_status_tracking_flash_transactions(&self) -> bool {
107 false
109 }
110
111 fn batch_groups(&self) -> Vec<Box<dyn ProtocolUpdateBatchGroupGenerator + '_>> {
112 vec![FixedBatchGroupGenerator::named("principal")
113 .add_batch("primary", |store| generate_batch(store, &self.settings))
114 .build()]
115 }
116}
117
118#[deny(unused_variables)]
119fn generate_batch(
120 store: &dyn SubstateDatabase,
121 BottlenoseSettings {
122 add_owner_role_getter,
123 add_locker_package,
124 fix_account_try_deposit_or_refund_behaviour,
125 move_protocol_params_to_state,
126 update_access_controller_to_add_xrd_fee_vault,
127 impose_a_limit_on_transaction_processor_blobs,
128 apply_costing_for_ref_checks: ref_cost_checks,
129 restrict_reserved_role_key,
130 }: &BottlenoseSettings,
131) -> ProtocolUpdateBatch {
132 let mut transactions = vec![];
133 if let UpdateSetting::Enabled(NoSettings) = &add_owner_role_getter {
134 transactions.push(ProtocolUpdateTransaction::flash(
135 "bottlenose-owner-role-getter",
136 generate_owner_role_getter_state_updates(store),
137 ));
138 }
139 if let UpdateSetting::Enabled(NoSettings) = &add_locker_package {
140 transactions.push(ProtocolUpdateTransaction::flash(
141 "bottlenose-locker-package",
142 generate_locker_package_state_updates(),
143 ));
144 }
145 if let UpdateSetting::Enabled(NoSettings) = &fix_account_try_deposit_or_refund_behaviour {
146 transactions.push(ProtocolUpdateTransaction::flash(
147 "bottlenose-account-try-deposit-or-refund",
148 generate_account_bottlenose_extension_state_updates(store),
149 ));
150 }
151 if let UpdateSetting::Enabled(settings) = &move_protocol_params_to_state {
152 transactions.push(ProtocolUpdateTransaction::flash(
153 "bottlenose-protocol-params-to-state",
154 generate_protocol_params_to_state_updates(settings.network_definition.clone()),
155 ));
156 }
157 if let UpdateSetting::Enabled(NoSettings) = &update_access_controller_to_add_xrd_fee_vault {
158 transactions.push(ProtocolUpdateTransaction::flash(
159 "bottlenose-access-controller-xrd-fee-vault",
160 generate_access_controller_state_updates(store),
161 ));
162 }
163 if let UpdateSetting::Enabled(NoSettings) = &impose_a_limit_on_transaction_processor_blobs {
164 transactions.push(ProtocolUpdateTransaction::flash(
165 "bottlenose-transaction-processor-blob-limits",
166 generate_transaction_processor_blob_limits_state_updates(store),
167 ));
168 }
169 if let UpdateSetting::Enabled(NoSettings) = &ref_cost_checks {
170 transactions.push(ProtocolUpdateTransaction::flash(
171 "bottlenose-add-deferred-reference-check-cost",
172 generate_ref_check_costs_state_updates(),
173 ));
174 }
175 if let UpdateSetting::Enabled(NoSettings) = &restrict_reserved_role_key {
176 transactions.push(ProtocolUpdateTransaction::flash(
177 "bottlenose-restrict-role-assignment-reserved-role-key",
178 generate_restrict_reserved_role_key_state_updates(store),
179 ));
180 }
181 ProtocolUpdateBatch { transactions }
182}
183
184macro_rules! scrypto_encode {
186 (
187 $expr: expr
188 ) => {
189 ::radix_common::prelude::scrypto_encode($expr).unwrap()
190 };
191}
192
193fn generate_owner_role_getter_state_updates<S: SubstateDatabase + ?Sized>(db: &S) -> StateUpdates {
194 let reader = SystemDatabaseReader::new(db);
195 let node_id = ROLE_ASSIGNMENT_MODULE_PACKAGE.into_node_id();
196 let blueprint_version_key = BlueprintVersionKey {
197 blueprint: ROLE_ASSIGNMENT_BLUEPRINT.to_string(),
198 version: Default::default(),
199 };
200
201 let (code_hash, (code_substate, vm_type_substate)) = {
203 let original_code = (NativeCodeId::RoleAssignmentCode2 as u64)
204 .to_be_bytes()
205 .to_vec();
206
207 let code_hash = CodeHash::from_hash(hash(&original_code));
208 let code_substate = PackageCodeOriginalCodeV1 {
209 code: original_code,
210 }
211 .into_versioned()
212 .into_locked_substate();
213 let vm_type_substate = PackageCodeVmTypeV1 {
214 vm_type: VmType::Native,
215 }
216 .into_locked_substate();
217
218 (code_hash, (code_substate, vm_type_substate))
219 };
220
221 let (added_functions, schema) = RoleAssignmentBottlenoseExtension::added_functions_schema();
223 let (schema_hash, schema_substate) =
224 (schema.generate_schema_hash(), schema.into_locked_substate());
225
226 let blueprint_definition_substate = {
228 let mut blueprint_definition = reader
229 .read_object_collection_entry::<_, VersionedPackageBlueprintVersionDefinition>(
230 &node_id,
231 ObjectModuleId::Main,
232 ObjectCollectionKey::KeyValue(
233 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
234 &blueprint_version_key,
235 ),
236 )
237 .unwrap()
238 .unwrap()
239 .fully_update_and_into_latest_version();
240
241 for (function_name, added_function) in added_functions.into_iter() {
242 let TypeRef::Static(input_local_id) = added_function.input else {
243 unreachable!()
244 };
245 let TypeRef::Static(output_local_id) = added_function.output else {
246 unreachable!()
247 };
248
249 blueprint_definition.function_exports.insert(
250 function_name.clone(),
251 PackageExport {
252 code_hash,
253 export_name: function_name.clone(),
254 },
255 );
256 blueprint_definition.interface.functions.insert(
257 function_name,
258 FunctionSchema {
259 receiver: added_function.receiver,
260 input: BlueprintPayloadDef::Static(ScopedTypeId(schema_hash, input_local_id)),
261 output: BlueprintPayloadDef::Static(ScopedTypeId(schema_hash, output_local_id)),
262 },
263 );
264 }
265
266 blueprint_definition.into_locked_substate()
267 };
268
269 let [blueprint_version_definition_partition_number, code_vm_type_partition_number, code_original_code_partition_number, schema_partition_number] =
271 [
272 PackageCollection::BlueprintVersionDefinitionKeyValue,
273 PackageCollection::CodeVmTypeKeyValue,
274 PackageCollection::CodeOriginalCodeKeyValue,
275 PackageCollection::SchemaKeyValue,
276 ]
277 .map(|package_collection| {
278 reader
279 .get_partition_of_collection(
280 &node_id,
281 ObjectModuleId::Main,
282 package_collection.collection_index(),
283 )
284 .unwrap()
285 });
286
287 StateUpdates {
289 by_node: indexmap!(
290 node_id => NodeStateUpdates::Delta {
291 by_partition: indexmap! {
292 blueprint_version_definition_partition_number => PartitionStateUpdates::Delta {
293 by_substate: indexmap! {
294 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
295 scrypto_encode!(&blueprint_definition_substate)
296 )
297 }
298 },
299 code_vm_type_partition_number => PartitionStateUpdates::Delta {
300 by_substate: indexmap! {
301 SubstateKey::Map(scrypto_encode!(&code_hash)) => DatabaseUpdate::Set(
302 scrypto_encode!(&vm_type_substate)
303 )
304 }
305 },
306 code_original_code_partition_number => PartitionStateUpdates::Delta {
307 by_substate: indexmap! {
308 SubstateKey::Map(scrypto_encode!(&code_hash)) => DatabaseUpdate::Set(
309 scrypto_encode!(&code_substate)
310 )
311 }
312 },
313 schema_partition_number => PartitionStateUpdates::Delta {
314 by_substate: indexmap! {
315 SubstateKey::Map(scrypto_encode!(&schema_hash)) => DatabaseUpdate::Set(
316 scrypto_encode!(&schema_substate)
317 )
318 }
319 }
320 }
321 }
322 ),
323 }
324}
325
326fn generate_locker_package_state_updates() -> StateUpdates {
327 let package_definition = LockerNativePackage::definition();
328 let package_structure = PackageNativePackage::validate_and_build_package_structure(
329 package_definition,
330 VmType::Native,
331 (NativeCodeId::LockerCode1 as u64).to_be_bytes().to_vec(),
332 Default::default(),
333 false,
334 &VmBoot::latest(),
335 )
336 .unwrap_or_else(|err| {
337 panic!(
338 "Invalid flashed Package definition with native_code_id {}: {:?}",
339 NativeCodeId::LockerCode1 as u64,
340 err
341 )
342 });
343
344 let partitions = create_package_partition_substates(
345 package_structure,
346 metadata_init! {
347 "name" => "Locker Package", locked;
348 "description" => "A native package that defines the logic for dApp-owned lockers to send resources to specified account addresses.", locked;
349 },
350 None,
351 );
352
353 StateUpdates {
354 by_node: indexmap! {
355 LOCKER_PACKAGE.into_node_id() => NodeStateUpdates::Delta {
356 by_partition: partitions
357 .into_iter()
358 .map(|(partition_num, substates)| {
359 (
360 partition_num,
361 PartitionStateUpdates::Delta {
362 by_substate: substates
363 .into_iter()
364 .map(|(key, value)| {
365 (key, DatabaseUpdate::Set(value.as_vec_ref().clone()))
366 })
367 .collect(),
368 },
369 )
370 })
371 .collect(),
372 }
373 },
374 }
375}
376
377fn generate_account_bottlenose_extension_state_updates<S: SubstateDatabase + ?Sized>(
378 db: &S,
379) -> StateUpdates {
380 let reader = SystemDatabaseReader::new(db);
381 let node_id = ACCOUNT_PACKAGE.into_node_id();
382 let blueprint_version_key = BlueprintVersionKey {
383 blueprint: ACCOUNT_BLUEPRINT.to_string(),
384 version: Default::default(),
385 };
386
387 let (code_hash, (code_substate, vm_type_substate)) = {
389 let original_code = (NativeCodeId::AccountCode2 as u64).to_be_bytes().to_vec();
390
391 let code_hash = CodeHash::from_hash(hash(&original_code));
392 let code_substate = PackageCodeOriginalCodeV1 {
393 code: original_code,
394 }
395 .into_locked_substate();
396 let vm_type_substate = PackageCodeVmTypeV1 {
397 vm_type: VmType::Native,
398 }
399 .into_locked_substate();
400
401 (code_hash, (code_substate, vm_type_substate))
402 };
403
404 let blueprint_definition_substate = {
407 let mut blueprint_definition = reader
408 .read_object_collection_entry::<_, VersionedPackageBlueprintVersionDefinition>(
409 &node_id,
410 ObjectModuleId::Main,
411 ObjectCollectionKey::KeyValue(
412 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
413 &blueprint_version_key,
414 ),
415 )
416 .unwrap()
417 .unwrap()
418 .fully_update_and_into_latest_version();
419
420 for function_name in [
421 ACCOUNT_TRY_DEPOSIT_OR_REFUND_IDENT,
422 ACCOUNT_TRY_DEPOSIT_BATCH_OR_REFUND_IDENT,
423 ] {
424 blueprint_definition
425 .function_exports
426 .get_mut(function_name)
427 .expect("This function must exist")
428 .code_hash = code_hash;
429 }
430
431 blueprint_definition.into_locked_substate()
432 };
433
434 let [blueprint_version_definition_partition_number, code_vm_type_partition_number, code_original_code_partition_number] =
436 [
437 PackageCollection::BlueprintVersionDefinitionKeyValue,
438 PackageCollection::CodeVmTypeKeyValue,
439 PackageCollection::CodeOriginalCodeKeyValue,
440 ]
441 .map(|package_collection| {
442 reader
443 .get_partition_of_collection(
444 &node_id,
445 ObjectModuleId::Main,
446 package_collection.collection_index(),
447 )
448 .unwrap()
449 });
450
451 StateUpdates {
453 by_node: indexmap!(
454 node_id => NodeStateUpdates::Delta {
455 by_partition: indexmap! {
456 blueprint_version_definition_partition_number => PartitionStateUpdates::Delta {
457 by_substate: indexmap! {
458 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
459 scrypto_encode!(&blueprint_definition_substate)
460 )
461 }
462 },
463 code_vm_type_partition_number => PartitionStateUpdates::Delta {
464 by_substate: indexmap! {
465 SubstateKey::Map(scrypto_encode!(&code_hash)) => DatabaseUpdate::Set(
466 scrypto_encode!(&vm_type_substate)
467 )
468 }
469 },
470 code_original_code_partition_number => PartitionStateUpdates::Delta {
471 by_substate: indexmap! {
472 SubstateKey::Map(scrypto_encode!(&code_hash)) => DatabaseUpdate::Set(
473 scrypto_encode!(&code_substate)
474 )
475 }
476 },
477 }
478 }
479 ),
480 }
481}
482
483fn generate_protocol_params_to_state_updates(
484 network_definition: NetworkDefinition,
485) -> StateUpdates {
486 StateUpdates::empty().set_substate(
487 TRANSACTION_TRACKER,
488 BOOT_LOADER_PARTITION,
489 BootLoaderField::SystemBoot,
490 SystemBoot::bottlenose(network_definition),
491 )
492}
493
494fn generate_access_controller_state_updates<S: SubstateDatabase + ?Sized>(db: &S) -> StateUpdates {
495 let reader = SystemDatabaseReader::new(db);
496 let node_id = ACCESS_CONTROLLER_PACKAGE.into_node_id();
497 let blueprint_version_key = BlueprintVersionKey {
498 blueprint: ACCESS_CONTROLLER_BLUEPRINT.to_string(),
499 version: Default::default(),
500 };
501 let old_blueprint_definition = AccessControllerV1NativePackage::definition()
502 .blueprints
503 .swap_remove(ACCESS_CONTROLLER_BLUEPRINT)
504 .unwrap();
505 let new_blueprint_definition = AccessControllerV2NativePackage::definition()
506 .blueprints
507 .swap_remove(ACCESS_CONTROLLER_BLUEPRINT)
508 .unwrap();
509
510 let old_schema_hash = old_blueprint_definition
511 .schema
512 .schema
513 .generate_schema_hash();
514 let new_schema_hash = new_blueprint_definition
515 .schema
516 .schema
517 .generate_schema_hash();
518 let new_schema_substate = new_blueprint_definition
519 .schema
520 .schema
521 .clone()
522 .into_locked_substate();
523
524 let old_code_hash = CodeHash::from_hash(hash(
526 (NativeCodeId::AccessControllerCode1 as u64)
527 .to_be_bytes()
528 .to_vec(),
529 ));
530 let (new_code_hash, (new_code_substate, new_vm_type_substate)) = {
531 let original_code = (NativeCodeId::AccessControllerCode2 as u64)
532 .to_be_bytes()
533 .to_vec();
534
535 let code_hash = CodeHash::from_hash(hash(&original_code));
536 let code_substate = PackageCodeOriginalCodeV1 {
537 code: original_code,
538 }
539 .into_versioned()
540 .into_locked_substate();
541 let vm_type_substate = PackageCodeVmTypeV1 {
542 vm_type: VmType::Native,
543 }
544 .into_locked_substate();
545
546 (code_hash, (code_substate, vm_type_substate))
547 };
548
549 let new_blueprint_auth_config = new_blueprint_definition.auth_config.into_locked_substate();
550
551 let blueprint_definition_substate = {
552 let mut blueprint_definition = reader
553 .read_object_collection_entry::<_, VersionedPackageBlueprintVersionDefinition>(
554 &node_id,
555 ObjectModuleId::Main,
556 ObjectCollectionKey::KeyValue(
557 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
558 &blueprint_version_key,
559 ),
560 )
561 .unwrap()
562 .unwrap()
563 .fully_update_and_into_latest_version();
564
565 blueprint_definition.interface.state = IndexedStateSchema::from_schema(
566 new_blueprint_definition
567 .schema
568 .schema
569 .generate_schema_hash(),
570 new_blueprint_definition.schema.state,
571 Default::default(),
572 );
573
574 blueprint_definition.interface.functions = new_blueprint_definition
575 .schema
576 .functions
577 .clone()
578 .functions
579 .into_iter()
580 .map(|(ident, func)| {
581 (
582 ident,
583 FunctionSchema {
584 receiver: func.receiver,
585 input: BlueprintPayloadDef::Static(ScopedTypeId(
586 new_schema_hash,
587 func.input.assert_static(),
588 )),
589 output: BlueprintPayloadDef::Static(ScopedTypeId(
590 new_schema_hash,
591 func.output.assert_static(),
592 )),
593 },
594 )
595 })
596 .collect();
597
598 blueprint_definition.function_exports = new_blueprint_definition
599 .schema
600 .functions
601 .clone()
602 .functions
603 .into_iter()
604 .map(|(ident, func)| {
605 (
606 ident,
607 PackageExport {
608 code_hash: new_code_hash,
609 export_name: func.export,
610 },
611 )
612 })
613 .collect();
614
615 blueprint_definition.interface.events = new_blueprint_definition
616 .schema
617 .events
618 .clone()
619 .event_schema
620 .into_iter()
621 .map(|(ident, type_ref)| {
622 (
623 ident,
624 BlueprintPayloadDef::Static(ScopedTypeId(
625 new_schema_hash,
626 type_ref.assert_static(),
627 )),
628 )
629 })
630 .collect();
631
632 blueprint_definition.into_locked_substate()
633 };
634
635 let original_code_partition_number = reader
636 .get_partition_of_collection(
637 &node_id,
638 ObjectModuleId::Main,
639 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
640 )
641 .unwrap();
642
643 let code_vm_type_partition_number = reader
644 .get_partition_of_collection(
645 &node_id,
646 ObjectModuleId::Main,
647 PackageCollection::CodeVmTypeKeyValue.collection_index(),
648 )
649 .unwrap();
650
651 let blueprint_definition_partition_number = reader
652 .get_partition_of_collection(
653 &node_id,
654 ObjectModuleId::Main,
655 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
656 )
657 .unwrap();
658
659 let blueprint_auth_configs = reader
660 .get_partition_of_collection(
661 &node_id,
662 ObjectModuleId::Main,
663 PackageCollection::BlueprintVersionAuthConfigKeyValue.collection_index(),
664 )
665 .unwrap();
666
667 let schema_partition_num = reader
668 .get_partition_of_collection(
669 &node_id,
670 ObjectModuleId::Main,
671 PackageCollection::SchemaKeyValue.collection_index(),
672 )
673 .unwrap();
674
675 StateUpdates {
676 by_node: indexmap! {
677 node_id => NodeStateUpdates::Delta {
678 by_partition: indexmap! {
679 blueprint_definition_partition_number => PartitionStateUpdates::Delta {
680 by_substate: indexmap! {
681 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
682 scrypto_encode!(&blueprint_definition_substate)
683 )
684 }
685 },
686 blueprint_auth_configs => PartitionStateUpdates::Delta {
687 by_substate: indexmap! {
688 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
689 scrypto_encode!(&new_blueprint_auth_config)
690 )
691 }
692 },
693 original_code_partition_number => PartitionStateUpdates::Delta {
694 by_substate: indexmap! {
695 SubstateKey::Map(scrypto_encode!(&old_code_hash))
696 => DatabaseUpdate::Delete,
697 SubstateKey::Map(scrypto_encode!(&new_code_hash))
698 => DatabaseUpdate::Set(scrypto_encode!(&new_code_substate)),
699 }
700 },
701 code_vm_type_partition_number => PartitionStateUpdates::Delta {
702 by_substate: indexmap! {
703 SubstateKey::Map(scrypto_encode!(&old_code_hash))
704 => DatabaseUpdate::Delete,
705 SubstateKey::Map(scrypto_encode!(&new_code_hash))
706 => DatabaseUpdate::Set(scrypto_encode!(&new_vm_type_substate)),
707 }
708 },
709 schema_partition_num => PartitionStateUpdates::Delta {
710 by_substate: indexmap! {
711 SubstateKey::Map(scrypto_encode!(&old_schema_hash))
712 => DatabaseUpdate::Delete,
713 SubstateKey::Map(scrypto_encode!(&new_schema_hash))
714 => DatabaseUpdate::Set(scrypto_encode!(&new_schema_substate))
715 }
716 }
717 }
718 }
719 },
720 }
721}
722
723fn generate_restrict_reserved_role_key_state_updates<S: SubstateDatabase + ?Sized>(
725 db: &S,
726) -> StateUpdates {
727 let reader = SystemDatabaseReader::new(db);
728 let tx_processor_pkg_node_id = PACKAGE_PACKAGE.into_node_id();
729 let bp_version_key = BlueprintVersionKey {
730 blueprint: PACKAGE_BLUEPRINT.to_string(),
731 version: BlueprintVersion::default(),
732 };
733
734 let (new_code_substate, new_vm_type_substate, old_code_hash, new_code_hash) = {
736 let old_code = (NativeCodeId::PackageCode1 as u64).to_be_bytes().to_vec();
737 let old_code_hash = CodeHash::from_hash(hash(&old_code));
738
739 let new_code = (NativeCodeId::PackageCode2 as u64).to_be_bytes().to_vec();
740 let new_code_hash = CodeHash::from_hash(hash(&new_code));
741
742 let versioned_code = PackageCodeOriginalCodeV1 { code: new_code }.into_versioned();
743 let code_payload = versioned_code.into_payload();
744 let code_substate = code_payload.into_locked_substate();
745 let vm_type_substate = PackageCodeVmTypeV1 {
746 vm_type: VmType::Native,
747 }
748 .into_versioned()
749 .into_locked_substate();
750 (
751 scrypto_encode(&code_substate).unwrap(),
752 scrypto_encode(&vm_type_substate).unwrap(),
753 old_code_hash,
754 new_code_hash,
755 )
756 };
757
758 let updated_bp_definition_substate = {
760 let versioned_definition: VersionedPackageBlueprintVersionDefinition = reader
761 .read_object_collection_entry(
762 &tx_processor_pkg_node_id,
763 ObjectModuleId::Main,
764 ObjectCollectionKey::KeyValue(
765 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
766 &bp_version_key,
767 ),
768 )
769 .unwrap()
770 .unwrap();
771
772 let mut definition = versioned_definition.fully_update_and_into_latest_version();
773
774 for (_, export) in definition.function_exports.iter_mut() {
775 export.code_hash = new_code_hash
776 }
777
778 scrypto_encode(&definition.into_versioned().into_locked_substate()).unwrap()
779 };
780
781 let bp_definition_partition_num = reader
782 .get_partition_of_collection(
783 &tx_processor_pkg_node_id,
784 ObjectModuleId::Main,
785 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
786 )
787 .unwrap();
788
789 let vm_type_partition_num = reader
790 .get_partition_of_collection(
791 &tx_processor_pkg_node_id,
792 ObjectModuleId::Main,
793 PackageCollection::CodeVmTypeKeyValue.collection_index(),
794 )
795 .unwrap();
796
797 let original_code_partition_num = reader
798 .get_partition_of_collection(
799 &tx_processor_pkg_node_id,
800 ObjectModuleId::Main,
801 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
802 )
803 .unwrap();
804
805 StateUpdates {
806 by_node: indexmap!(
807 tx_processor_pkg_node_id => NodeStateUpdates::Delta {
808 by_partition: indexmap! {
809 bp_definition_partition_num => PartitionStateUpdates::Delta {
810 by_substate: indexmap! {
811 SubstateKey::Map(scrypto_encode(&bp_version_key).unwrap()) => DatabaseUpdate::Set(
812 updated_bp_definition_substate
813 )
814 }
815 },
816 vm_type_partition_num => PartitionStateUpdates::Delta {
817 by_substate: indexmap! {
818 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
819 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_vm_type_substate)
820 }
821 },
822 original_code_partition_num => PartitionStateUpdates::Delta {
823 by_substate: indexmap! {
824 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
825 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_code_substate)
826 }
827 },
828 }
829 }
830 ),
831 }
832}
833
834fn generate_transaction_processor_blob_limits_state_updates<S: SubstateDatabase + ?Sized>(
837 db: &S,
838) -> StateUpdates {
839 let reader = SystemDatabaseReader::new(db);
840 let tx_processor_pkg_node_id = TRANSACTION_PROCESSOR_PACKAGE.into_node_id();
841 let bp_version_key = BlueprintVersionKey {
842 blueprint: TRANSACTION_PROCESSOR_BLUEPRINT.to_string(),
843 version: BlueprintVersion::default(),
844 };
845
846 let (new_code_substate, new_vm_type_substate, old_code_hash, new_code_hash) = {
848 let old_code = (NativeCodeId::TransactionProcessorCode1 as u64)
849 .to_be_bytes()
850 .to_vec();
851 let old_code_hash = CodeHash::from_hash(hash(&old_code));
852
853 let new_code = (NativeCodeId::TransactionProcessorCode2 as u64)
854 .to_be_bytes()
855 .to_vec();
856 let new_code_hash = CodeHash::from_hash(hash(&new_code));
857
858 let versioned_code = PackageCodeOriginalCodeV1 { code: new_code }.into_versioned();
859 let code_payload = versioned_code.into_payload();
860 let code_substate = code_payload.into_locked_substate();
861 let vm_type_substate = PackageCodeVmTypeV1 {
862 vm_type: VmType::Native,
863 }
864 .into_versioned()
865 .into_locked_substate();
866 (
867 scrypto_encode(&code_substate).unwrap(),
868 scrypto_encode(&vm_type_substate).unwrap(),
869 old_code_hash,
870 new_code_hash,
871 )
872 };
873
874 let updated_bp_definition_substate = {
876 let versioned_definition: VersionedPackageBlueprintVersionDefinition = reader
877 .read_object_collection_entry(
878 &tx_processor_pkg_node_id,
879 ObjectModuleId::Main,
880 ObjectCollectionKey::KeyValue(
881 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
882 &bp_version_key,
883 ),
884 )
885 .unwrap()
886 .unwrap();
887
888 let mut definition = versioned_definition.fully_update_and_into_latest_version();
889
890 for (_, export) in definition.function_exports.iter_mut() {
891 export.code_hash = new_code_hash
892 }
893
894 scrypto_encode(&definition.into_versioned().into_locked_substate()).unwrap()
895 };
896
897 let bp_definition_partition_num = reader
898 .get_partition_of_collection(
899 &tx_processor_pkg_node_id,
900 ObjectModuleId::Main,
901 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
902 )
903 .unwrap();
904
905 let vm_type_partition_num = reader
906 .get_partition_of_collection(
907 &tx_processor_pkg_node_id,
908 ObjectModuleId::Main,
909 PackageCollection::CodeVmTypeKeyValue.collection_index(),
910 )
911 .unwrap();
912
913 let original_code_partition_num = reader
914 .get_partition_of_collection(
915 &tx_processor_pkg_node_id,
916 ObjectModuleId::Main,
917 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
918 )
919 .unwrap();
920
921 StateUpdates {
922 by_node: indexmap!(
923 tx_processor_pkg_node_id => NodeStateUpdates::Delta {
924 by_partition: indexmap! {
925 bp_definition_partition_num => PartitionStateUpdates::Delta {
926 by_substate: indexmap! {
927 SubstateKey::Map(scrypto_encode(&bp_version_key).unwrap()) => DatabaseUpdate::Set(
928 updated_bp_definition_substate
929 )
930 }
931 },
932 vm_type_partition_num => PartitionStateUpdates::Delta {
933 by_substate: indexmap! {
934 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
935 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_vm_type_substate)
936 }
937 },
938 original_code_partition_num => PartitionStateUpdates::Delta {
939 by_substate: indexmap! {
940 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
941 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_code_substate)
942 }
943 },
944 }
945 }
946 ),
947 }
948}
949
950fn generate_ref_check_costs_state_updates() -> StateUpdates {
952 StateUpdates::empty().set_substate(
953 TRANSACTION_TRACKER,
954 BOOT_LOADER_PARTITION,
955 BootLoaderField::KernelBoot,
956 KernelBoot::V1,
957 )
958}