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).to_be_bytes(),
527 ));
528 let (new_code_hash, (new_code_substate, new_vm_type_substate)) = {
529 let original_code = (NativeCodeId::AccessControllerCode2 as u64)
530 .to_be_bytes()
531 .to_vec();
532
533 let code_hash = CodeHash::from_hash(hash(&original_code));
534 let code_substate = PackageCodeOriginalCodeV1 {
535 code: original_code,
536 }
537 .into_versioned()
538 .into_locked_substate();
539 let vm_type_substate = PackageCodeVmTypeV1 {
540 vm_type: VmType::Native,
541 }
542 .into_locked_substate();
543
544 (code_hash, (code_substate, vm_type_substate))
545 };
546
547 let new_blueprint_auth_config = new_blueprint_definition.auth_config.into_locked_substate();
548
549 let blueprint_definition_substate = {
550 let mut blueprint_definition = reader
551 .read_object_collection_entry::<_, VersionedPackageBlueprintVersionDefinition>(
552 &node_id,
553 ObjectModuleId::Main,
554 ObjectCollectionKey::KeyValue(
555 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
556 &blueprint_version_key,
557 ),
558 )
559 .unwrap()
560 .unwrap()
561 .fully_update_and_into_latest_version();
562
563 blueprint_definition.interface.state = IndexedStateSchema::from_schema(
564 new_blueprint_definition
565 .schema
566 .schema
567 .generate_schema_hash(),
568 new_blueprint_definition.schema.state,
569 Default::default(),
570 );
571
572 blueprint_definition.interface.functions = new_blueprint_definition
573 .schema
574 .functions
575 .clone()
576 .functions
577 .into_iter()
578 .map(|(ident, func)| {
579 (
580 ident,
581 FunctionSchema {
582 receiver: func.receiver,
583 input: BlueprintPayloadDef::Static(ScopedTypeId(
584 new_schema_hash,
585 func.input.assert_static(),
586 )),
587 output: BlueprintPayloadDef::Static(ScopedTypeId(
588 new_schema_hash,
589 func.output.assert_static(),
590 )),
591 },
592 )
593 })
594 .collect();
595
596 blueprint_definition.function_exports = new_blueprint_definition
597 .schema
598 .functions
599 .clone()
600 .functions
601 .into_iter()
602 .map(|(ident, func)| {
603 (
604 ident,
605 PackageExport {
606 code_hash: new_code_hash,
607 export_name: func.export,
608 },
609 )
610 })
611 .collect();
612
613 blueprint_definition.interface.events = new_blueprint_definition
614 .schema
615 .events
616 .clone()
617 .event_schema
618 .into_iter()
619 .map(|(ident, type_ref)| {
620 (
621 ident,
622 BlueprintPayloadDef::Static(ScopedTypeId(
623 new_schema_hash,
624 type_ref.assert_static(),
625 )),
626 )
627 })
628 .collect();
629
630 blueprint_definition.into_locked_substate()
631 };
632
633 let original_code_partition_number = reader
634 .get_partition_of_collection(
635 &node_id,
636 ObjectModuleId::Main,
637 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
638 )
639 .unwrap();
640
641 let code_vm_type_partition_number = reader
642 .get_partition_of_collection(
643 &node_id,
644 ObjectModuleId::Main,
645 PackageCollection::CodeVmTypeKeyValue.collection_index(),
646 )
647 .unwrap();
648
649 let blueprint_definition_partition_number = reader
650 .get_partition_of_collection(
651 &node_id,
652 ObjectModuleId::Main,
653 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
654 )
655 .unwrap();
656
657 let blueprint_auth_configs = reader
658 .get_partition_of_collection(
659 &node_id,
660 ObjectModuleId::Main,
661 PackageCollection::BlueprintVersionAuthConfigKeyValue.collection_index(),
662 )
663 .unwrap();
664
665 let schema_partition_num = reader
666 .get_partition_of_collection(
667 &node_id,
668 ObjectModuleId::Main,
669 PackageCollection::SchemaKeyValue.collection_index(),
670 )
671 .unwrap();
672
673 StateUpdates {
674 by_node: indexmap! {
675 node_id => NodeStateUpdates::Delta {
676 by_partition: indexmap! {
677 blueprint_definition_partition_number => PartitionStateUpdates::Delta {
678 by_substate: indexmap! {
679 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
680 scrypto_encode!(&blueprint_definition_substate)
681 )
682 }
683 },
684 blueprint_auth_configs => PartitionStateUpdates::Delta {
685 by_substate: indexmap! {
686 SubstateKey::Map(scrypto_encode!(&blueprint_version_key)) => DatabaseUpdate::Set(
687 scrypto_encode!(&new_blueprint_auth_config)
688 )
689 }
690 },
691 original_code_partition_number => PartitionStateUpdates::Delta {
692 by_substate: indexmap! {
693 SubstateKey::Map(scrypto_encode!(&old_code_hash))
694 => DatabaseUpdate::Delete,
695 SubstateKey::Map(scrypto_encode!(&new_code_hash))
696 => DatabaseUpdate::Set(scrypto_encode!(&new_code_substate)),
697 }
698 },
699 code_vm_type_partition_number => PartitionStateUpdates::Delta {
700 by_substate: indexmap! {
701 SubstateKey::Map(scrypto_encode!(&old_code_hash))
702 => DatabaseUpdate::Delete,
703 SubstateKey::Map(scrypto_encode!(&new_code_hash))
704 => DatabaseUpdate::Set(scrypto_encode!(&new_vm_type_substate)),
705 }
706 },
707 schema_partition_num => PartitionStateUpdates::Delta {
708 by_substate: indexmap! {
709 SubstateKey::Map(scrypto_encode!(&old_schema_hash))
710 => DatabaseUpdate::Delete,
711 SubstateKey::Map(scrypto_encode!(&new_schema_hash))
712 => DatabaseUpdate::Set(scrypto_encode!(&new_schema_substate))
713 }
714 }
715 }
716 }
717 },
718 }
719}
720
721fn generate_restrict_reserved_role_key_state_updates<S: SubstateDatabase + ?Sized>(
723 db: &S,
724) -> StateUpdates {
725 let reader = SystemDatabaseReader::new(db);
726 let tx_processor_pkg_node_id = PACKAGE_PACKAGE.into_node_id();
727 let bp_version_key = BlueprintVersionKey {
728 blueprint: PACKAGE_BLUEPRINT.to_string(),
729 version: BlueprintVersion::default(),
730 };
731
732 let (new_code_substate, new_vm_type_substate, old_code_hash, new_code_hash) = {
734 let old_code = (NativeCodeId::PackageCode1 as u64).to_be_bytes().to_vec();
735 let old_code_hash = CodeHash::from_hash(hash(&old_code));
736
737 let new_code = (NativeCodeId::PackageCode2 as u64).to_be_bytes().to_vec();
738 let new_code_hash = CodeHash::from_hash(hash(&new_code));
739
740 let versioned_code = PackageCodeOriginalCodeV1 { code: new_code }.into_versioned();
741 let code_payload = versioned_code.into_payload();
742 let code_substate = code_payload.into_locked_substate();
743 let vm_type_substate = PackageCodeVmTypeV1 {
744 vm_type: VmType::Native,
745 }
746 .into_versioned()
747 .into_locked_substate();
748 (
749 scrypto_encode(&code_substate).unwrap(),
750 scrypto_encode(&vm_type_substate).unwrap(),
751 old_code_hash,
752 new_code_hash,
753 )
754 };
755
756 let updated_bp_definition_substate = {
758 let versioned_definition: VersionedPackageBlueprintVersionDefinition = reader
759 .read_object_collection_entry(
760 &tx_processor_pkg_node_id,
761 ObjectModuleId::Main,
762 ObjectCollectionKey::KeyValue(
763 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
764 &bp_version_key,
765 ),
766 )
767 .unwrap()
768 .unwrap();
769
770 let mut definition = versioned_definition.fully_update_and_into_latest_version();
771
772 for (_, export) in definition.function_exports.iter_mut() {
773 export.code_hash = new_code_hash
774 }
775
776 scrypto_encode(&definition.into_versioned().into_locked_substate()).unwrap()
777 };
778
779 let bp_definition_partition_num = reader
780 .get_partition_of_collection(
781 &tx_processor_pkg_node_id,
782 ObjectModuleId::Main,
783 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
784 )
785 .unwrap();
786
787 let vm_type_partition_num = reader
788 .get_partition_of_collection(
789 &tx_processor_pkg_node_id,
790 ObjectModuleId::Main,
791 PackageCollection::CodeVmTypeKeyValue.collection_index(),
792 )
793 .unwrap();
794
795 let original_code_partition_num = reader
796 .get_partition_of_collection(
797 &tx_processor_pkg_node_id,
798 ObjectModuleId::Main,
799 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
800 )
801 .unwrap();
802
803 StateUpdates {
804 by_node: indexmap!(
805 tx_processor_pkg_node_id => NodeStateUpdates::Delta {
806 by_partition: indexmap! {
807 bp_definition_partition_num => PartitionStateUpdates::Delta {
808 by_substate: indexmap! {
809 SubstateKey::Map(scrypto_encode(&bp_version_key).unwrap()) => DatabaseUpdate::Set(
810 updated_bp_definition_substate
811 )
812 }
813 },
814 vm_type_partition_num => PartitionStateUpdates::Delta {
815 by_substate: indexmap! {
816 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
817 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_vm_type_substate)
818 }
819 },
820 original_code_partition_num => PartitionStateUpdates::Delta {
821 by_substate: indexmap! {
822 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
823 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_code_substate)
824 }
825 },
826 }
827 }
828 ),
829 }
830}
831
832fn generate_transaction_processor_blob_limits_state_updates<S: SubstateDatabase + ?Sized>(
835 db: &S,
836) -> StateUpdates {
837 let reader = SystemDatabaseReader::new(db);
838 let tx_processor_pkg_node_id = TRANSACTION_PROCESSOR_PACKAGE.into_node_id();
839 let bp_version_key = BlueprintVersionKey {
840 blueprint: TRANSACTION_PROCESSOR_BLUEPRINT.to_string(),
841 version: BlueprintVersion::default(),
842 };
843
844 let (new_code_substate, new_vm_type_substate, old_code_hash, new_code_hash) = {
846 let old_code = (NativeCodeId::TransactionProcessorCode1 as u64)
847 .to_be_bytes()
848 .to_vec();
849 let old_code_hash = CodeHash::from_hash(hash(&old_code));
850
851 let new_code = (NativeCodeId::TransactionProcessorCode2 as u64)
852 .to_be_bytes()
853 .to_vec();
854 let new_code_hash = CodeHash::from_hash(hash(&new_code));
855
856 let versioned_code = PackageCodeOriginalCodeV1 { code: new_code }.into_versioned();
857 let code_payload = versioned_code.into_payload();
858 let code_substate = code_payload.into_locked_substate();
859 let vm_type_substate = PackageCodeVmTypeV1 {
860 vm_type: VmType::Native,
861 }
862 .into_versioned()
863 .into_locked_substate();
864 (
865 scrypto_encode(&code_substate).unwrap(),
866 scrypto_encode(&vm_type_substate).unwrap(),
867 old_code_hash,
868 new_code_hash,
869 )
870 };
871
872 let updated_bp_definition_substate = {
874 let versioned_definition: VersionedPackageBlueprintVersionDefinition = reader
875 .read_object_collection_entry(
876 &tx_processor_pkg_node_id,
877 ObjectModuleId::Main,
878 ObjectCollectionKey::KeyValue(
879 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
880 &bp_version_key,
881 ),
882 )
883 .unwrap()
884 .unwrap();
885
886 let mut definition = versioned_definition.fully_update_and_into_latest_version();
887
888 for (_, export) in definition.function_exports.iter_mut() {
889 export.code_hash = new_code_hash
890 }
891
892 scrypto_encode(&definition.into_versioned().into_locked_substate()).unwrap()
893 };
894
895 let bp_definition_partition_num = reader
896 .get_partition_of_collection(
897 &tx_processor_pkg_node_id,
898 ObjectModuleId::Main,
899 PackageCollection::BlueprintVersionDefinitionKeyValue.collection_index(),
900 )
901 .unwrap();
902
903 let vm_type_partition_num = reader
904 .get_partition_of_collection(
905 &tx_processor_pkg_node_id,
906 ObjectModuleId::Main,
907 PackageCollection::CodeVmTypeKeyValue.collection_index(),
908 )
909 .unwrap();
910
911 let original_code_partition_num = reader
912 .get_partition_of_collection(
913 &tx_processor_pkg_node_id,
914 ObjectModuleId::Main,
915 PackageCollection::CodeOriginalCodeKeyValue.collection_index(),
916 )
917 .unwrap();
918
919 StateUpdates {
920 by_node: indexmap!(
921 tx_processor_pkg_node_id => NodeStateUpdates::Delta {
922 by_partition: indexmap! {
923 bp_definition_partition_num => PartitionStateUpdates::Delta {
924 by_substate: indexmap! {
925 SubstateKey::Map(scrypto_encode(&bp_version_key).unwrap()) => DatabaseUpdate::Set(
926 updated_bp_definition_substate
927 )
928 }
929 },
930 vm_type_partition_num => PartitionStateUpdates::Delta {
931 by_substate: indexmap! {
932 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
933 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_vm_type_substate)
934 }
935 },
936 original_code_partition_num => PartitionStateUpdates::Delta {
937 by_substate: indexmap! {
938 SubstateKey::Map(scrypto_encode(&old_code_hash).unwrap()) => DatabaseUpdate::Delete,
939 SubstateKey::Map(scrypto_encode(&new_code_hash).unwrap()) => DatabaseUpdate::Set(new_code_substate)
940 }
941 },
942 }
943 }
944 ),
945 }
946}
947
948fn generate_ref_check_costs_state_updates() -> StateUpdates {
950 StateUpdates::empty().set_substate(
951 TRANSACTION_TRACKER,
952 BOOT_LOADER_PARTITION,
953 BootLoaderField::KernelBoot,
954 KernelBoot::V1,
955 )
956}