1pub use checked::*;
5
6#[sui_macros::with_checked_arithmetic]
7mod checked {
8
9 use crate::execution_mode::{self, ExecutionMode};
10 use crate::execution_value::SuiResolver;
11 use crate::gas_charger::PaymentMethod;
12 use move_binary_format::CompiledModule;
13 use move_trace_format::format::MoveTraceBuilder;
14 use move_vm_runtime::move_vm::MoveVM;
15 use std::collections::BTreeMap;
16 use std::{cell::RefCell, collections::HashSet, rc::Rc, sync::Arc};
17 use sui_types::accumulator_root::{ACCUMULATOR_ROOT_CREATE_FUNC, ACCUMULATOR_ROOT_MODULE};
18 use sui_types::balance::{
19 BALANCE_CREATE_REWARDS_FUNCTION_NAME, BALANCE_DESTROY_REBATES_FUNCTION_NAME,
20 BALANCE_MODULE_NAME,
21 };
22 use sui_types::execution_params::ExecutionOrEarlyError;
23 use sui_types::gas_coin::GAS;
24 use sui_types::messages_checkpoint::CheckpointTimestamp;
25 use sui_types::metrics::ExecutionMetrics;
26 use sui_types::object::OBJECT_START_VERSION;
27 use sui_types::programmable_transaction_builder::ProgrammableTransactionBuilder;
28 use sui_types::randomness_state::{
29 RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE_FUNCTION_NAME,
30 RANDOMNESS_STATE_UPDATE_FUNCTION_NAME,
31 };
32 use sui_types::{BRIDGE_ADDRESS, SUI_BRIDGE_OBJECT_ID, SUI_RANDOMNESS_STATE_OBJECT_ID};
33 use tracing::{info, instrument, trace, warn};
34
35 use crate::adapter::new_move_vm;
36 use crate::programmable_transactions;
37 use crate::sui_types::gas::SuiGasStatusAPI;
38 use crate::type_layout_resolver::TypeLayoutResolver;
39 use crate::{gas_charger::GasCharger, temporary_store::TemporaryStore};
40 use move_core_types::ident_str;
41 use sui_move_natives::all_natives;
42 use sui_protocol_config::{
43 LimitThresholdCrossed, PerObjectCongestionControlMode, ProtocolConfig, check_limit_by_meter,
44 };
45 use sui_types::authenticator_state::{
46 AUTHENTICATOR_STATE_CREATE_FUNCTION_NAME, AUTHENTICATOR_STATE_EXPIRE_JWKS_FUNCTION_NAME,
47 AUTHENTICATOR_STATE_MODULE_NAME, AUTHENTICATOR_STATE_UPDATE_FUNCTION_NAME,
48 };
49 use sui_types::base_types::SequenceNumber;
50 use sui_types::bridge::BRIDGE_COMMITTEE_MINIMAL_VOTING_POWER;
51 use sui_types::bridge::{
52 BRIDGE_CREATE_FUNCTION_NAME, BRIDGE_INIT_COMMITTEE_FUNCTION_NAME, BRIDGE_MODULE_NAME,
53 BridgeChainId,
54 };
55 use sui_types::clock::{CLOCK_MODULE_NAME, CONSENSUS_COMMIT_PROLOGUE_FUNCTION_NAME};
56 use sui_types::committee::EpochId;
57 use sui_types::deny_list_v1::{DENY_LIST_CREATE_FUNC, DENY_LIST_MODULE};
58 use sui_types::digests::{
59 ChainIdentifier, get_mainnet_chain_identifier, get_testnet_chain_identifier,
60 };
61 use sui_types::effects::TransactionEffects;
62 use sui_types::error::{ExecutionError, ExecutionErrorTrait};
63 use sui_types::execution::{ExecutionTiming, ResultWithTimings};
64 use sui_types::execution_status::{ExecutionErrorKind, ExecutionStatus};
65 use sui_types::gas::GasCostSummary;
66 use sui_types::gas::SuiGasStatus;
67 use sui_types::id::UID;
68 use sui_types::inner_temporary_store::InnerTemporaryStore;
69 use sui_types::storage::BackingStore;
70 #[cfg(msim)]
71 use sui_types::sui_system_state::advance_epoch_result_injection::maybe_modify_result;
72 use sui_types::sui_system_state::{ADVANCE_EPOCH_SAFE_MODE_FUNCTION_NAME, AdvanceEpochParams};
73 use sui_types::transaction::{
74 Argument, AuthenticatorStateExpire, AuthenticatorStateUpdate, CallArg, ChangeEpoch,
75 Command, EndOfEpochTransactionKind, GasData, GenesisTransaction, ObjectArg,
76 ProgrammableTransaction, StoredExecutionTimeObservations, TransactionKind,
77 WriteAccumulatorStorageCost, is_gas_paid_from_address_balance,
78 };
79 use sui_types::transaction::{CheckedInputObjects, RandomnessStateUpdate};
80 use sui_types::{
81 SUI_AUTHENTICATOR_STATE_OBJECT_ID, SUI_FRAMEWORK_ADDRESS, SUI_FRAMEWORK_PACKAGE_ID,
82 SUI_SYSTEM_PACKAGE_ID,
83 base_types::{SuiAddress, TransactionDigest, TxContext},
84 object::{Object, ObjectInner},
85 sui_system_state::{ADVANCE_EPOCH_FUNCTION_NAME, SUI_SYSTEM_MODULE_NAME},
86 };
87
88 #[instrument(name = "tx_execute_to_effects", level = "debug", skip_all)]
89 pub fn execute_transaction_to_effects<Mode: ExecutionMode>(
90 store: &dyn BackingStore,
91 input_objects: CheckedInputObjects,
92 gas_data: GasData,
93 gas_status: SuiGasStatus,
94 transaction_kind: TransactionKind,
95 transaction_signer: SuiAddress,
96 transaction_digest: TransactionDigest,
97 move_vm: &Arc<MoveVM>,
98 epoch_id: &EpochId,
99 epoch_timestamp_ms: u64,
100 protocol_config: &ProtocolConfig,
101 metrics: Arc<ExecutionMetrics>,
102 enable_expensive_checks: bool,
103 execution_params: ExecutionOrEarlyError,
104 trace_builder_opt: &mut Option<MoveTraceBuilder>,
105 ) -> (
106 InnerTemporaryStore,
107 SuiGasStatus,
108 TransactionEffects,
109 Vec<ExecutionTiming>,
110 Result<Mode::ExecutionResults, ExecutionError>,
111 ) {
112 let input_objects = input_objects.into_inner();
113 let mutable_inputs = if enable_expensive_checks {
114 input_objects.all_mutable_inputs().keys().copied().collect()
115 } else {
116 HashSet::new()
117 };
118 let shared_object_refs = input_objects.filter_shared_objects();
119 let receiving_objects = transaction_kind.receiving_objects();
120 let mut transaction_dependencies = input_objects.transaction_dependencies();
121
122 let mut temporary_store = TemporaryStore::new(
123 store,
124 input_objects,
125 receiving_objects,
126 transaction_digest,
127 protocol_config,
128 *epoch_id,
129 );
130
131 let sponsor = {
132 let gas_owner = gas_data.owner;
133 if gas_owner == transaction_signer {
134 None
135 } else {
136 Some(gas_owner)
137 }
138 };
139 let gas_price = gas_status.gas_price();
140 let rgp = gas_status.reference_gas_price();
141
142 let payment_method = if gas_data.is_unmetered() || transaction_kind.is_system_tx() {
143 PaymentMethod::Unmetered
144 } else if is_gas_paid_from_address_balance(&gas_data, &transaction_kind) {
145 PaymentMethod::AddressBalance(gas_data.owner)
146 } else {
147 PaymentMethod::Coins(gas_data.payment)
148 };
149
150 let mut gas_charger = GasCharger::new(
151 transaction_digest,
152 payment_method,
153 gas_status,
154 protocol_config,
155 );
156
157 let tx_ctx = TxContext::new_from_components(
158 &transaction_signer,
159 &transaction_digest,
160 epoch_id,
161 epoch_timestamp_ms,
162 rgp,
163 gas_price,
164 gas_data.budget,
165 sponsor,
166 protocol_config,
167 );
168 let tx_ctx = Rc::new(RefCell::new(tx_ctx));
169
170 let is_epoch_change = transaction_kind.is_end_of_epoch_tx();
171
172 let (gas_cost_summary, execution_result, timings) = execute_transaction::<Mode>(
173 store,
174 &mut temporary_store,
175 transaction_kind,
176 &mut gas_charger,
177 tx_ctx,
178 move_vm,
179 protocol_config,
180 metrics,
181 enable_expensive_checks,
182 execution_params,
183 trace_builder_opt,
184 );
185
186 let status = if let Err(error) = &execution_result {
187 ExecutionStatus::new_failure(error.to_execution_failure())
188 } else {
189 ExecutionStatus::Success
190 };
191
192 #[skip_checked_arithmetic]
193 trace!(
194 tx_digest = ?transaction_digest,
195 computation_gas_cost = gas_cost_summary.computation_cost,
196 storage_gas_cost = gas_cost_summary.storage_cost,
197 storage_gas_rebate = gas_cost_summary.storage_rebate,
198 "Finished execution of transaction with status {:?}",
199 status
200 );
201
202 transaction_dependencies.remove(&TransactionDigest::genesis_marker());
206
207 if enable_expensive_checks && !Mode::allow_arbitrary_function_calls() {
208 temporary_store
209 .check_ownership_invariants(
210 &transaction_signer,
211 &sponsor,
212 &mut gas_charger,
213 &mutable_inputs,
214 is_epoch_change,
215 )
216 .unwrap()
217 } let (inner, effects) = temporary_store.into_effects(
220 shared_object_refs,
221 &transaction_digest,
222 transaction_dependencies,
223 gas_cost_summary,
224 status,
225 &mut gas_charger,
226 *epoch_id,
227 );
228
229 (
230 inner,
231 gas_charger.into_gas_status(),
232 effects,
233 timings,
234 execution_result,
235 )
236 }
237
238 pub fn execute_genesis_state_update(
239 store: &dyn BackingStore,
240 protocol_config: &ProtocolConfig,
241 metrics: Arc<ExecutionMetrics>,
242 move_vm: &Arc<MoveVM>,
243 tx_context: Rc<RefCell<TxContext>>,
244 input_objects: CheckedInputObjects,
245 pt: ProgrammableTransaction,
246 ) -> Result<InnerTemporaryStore, ExecutionError> {
247 let input_objects = input_objects.into_inner();
248 let mut temporary_store = TemporaryStore::new(
249 store,
250 input_objects,
251 vec![],
252 tx_context.borrow().digest(),
253 protocol_config,
254 0,
255 );
256 let mut gas_charger = GasCharger::new_unmetered(tx_context.borrow().digest());
257 programmable_transactions::execution::execute::<execution_mode::Genesis>(
258 protocol_config,
259 metrics,
260 move_vm,
261 &mut temporary_store,
262 store.as_backing_package_store(),
263 tx_context,
264 &mut gas_charger,
265 None,
266 pt,
267 &mut None,
268 )
269 .map_err(|(e, _)| e)?;
270 temporary_store.update_object_version_and_prev_tx();
271 Ok(temporary_store.into_inner(BTreeMap::new()))
272 }
273
274 #[instrument(name = "tx_execute", level = "debug", skip_all)]
275 fn execute_transaction<Mode: ExecutionMode>(
276 store: &dyn BackingStore,
277 temporary_store: &mut TemporaryStore<'_>,
278 transaction_kind: TransactionKind,
279 gas_charger: &mut GasCharger,
280 tx_ctx: Rc<RefCell<TxContext>>,
281 move_vm: &Arc<MoveVM>,
282 protocol_config: &ProtocolConfig,
283 metrics: Arc<ExecutionMetrics>,
284 enable_expensive_checks: bool,
285 execution_params: ExecutionOrEarlyError,
286 trace_builder_opt: &mut Option<MoveTraceBuilder>,
287 ) -> (
288 GasCostSummary,
289 Result<Mode::ExecutionResults, ExecutionError>,
290 Vec<ExecutionTiming>,
291 ) {
292 gas_charger.smash_gas(temporary_store);
293
294 debug_assert!(
296 gas_charger.no_charges(),
297 "No gas charges must be applied yet"
298 );
299
300 let is_genesis_tx = matches!(transaction_kind, TransactionKind::Genesis(_));
301 let advance_epoch_gas_summary = transaction_kind.get_advance_epoch_tx_gas_summary();
302 let digest = tx_ctx.borrow().digest();
303
304 let result = gas_charger.charge_input_objects(temporary_store);
307
308 let result: ResultWithTimings<Mode::ExecutionResults, ExecutionError> =
309 result.map_err(|e| (e, vec![])).and_then(
310 |()| -> ResultWithTimings<Mode::ExecutionResults, ExecutionError> {
311 let mut execution_result: ResultWithTimings<
312 Mode::ExecutionResults,
313 ExecutionError,
314 > = match execution_params {
315 ExecutionOrEarlyError::Err(early_execution_error) => {
316 Err((ExecutionError::new(early_execution_error, None), vec![]))
317 }
318 ExecutionOrEarlyError::Ok(()) => execution_loop::<Mode>(
319 store,
320 temporary_store,
321 transaction_kind,
322 tx_ctx,
323 move_vm,
324 gas_charger,
325 protocol_config,
326 metrics.clone(),
327 trace_builder_opt,
328 ),
329 };
330
331 let meter_check = check_meter_limit(
332 temporary_store,
333 gas_charger,
334 protocol_config,
335 metrics.clone(),
336 );
337 if let Err(e) = meter_check {
338 execution_result = Err((e, vec![]));
339 }
340
341 if execution_result.is_ok() {
342 let gas_check = check_written_objects_limit(
343 temporary_store,
344 gas_charger,
345 protocol_config,
346 metrics,
347 );
348 if let Err(e) = gas_check {
349 execution_result = Err((e, vec![]));
350 }
351 }
352
353 execution_result
354 },
355 );
356
357 let (mut result, timings) = match result {
358 Ok((r, t)) => (Ok(r), t),
359 Err((e, t)) => (Err(e), t),
360 };
361
362 let cost_summary = gas_charger.charge_gas(temporary_store, &mut result);
363 temporary_store.conserve_unmetered_storage_rebate(gas_charger.unmetered_storage_rebate());
371
372 if let Err(e) = run_conservation_checks::<Mode>(
373 temporary_store,
374 gas_charger,
375 digest,
376 move_vm,
377 protocol_config.simple_conservation_checks(),
378 enable_expensive_checks,
379 &cost_summary,
380 is_genesis_tx,
381 advance_epoch_gas_summary,
382 ) {
383 result = Err(e);
385 }
386
387 (cost_summary, result, timings)
388 }
389
390 #[instrument(name = "run_conservation_checks", level = "debug", skip_all)]
391 fn run_conservation_checks<Mode: ExecutionMode>(
392 temporary_store: &mut TemporaryStore<'_>,
393 gas_charger: &mut GasCharger,
394 tx_digest: TransactionDigest,
395 move_vm: &Arc<MoveVM>,
396 simple_conservation_checks: bool,
397 enable_expensive_checks: bool,
398 cost_summary: &GasCostSummary,
399 is_genesis_tx: bool,
400 advance_epoch_gas_summary: Option<(u64, u64)>,
401 ) -> Result<(), ExecutionError> {
402 let mut result: std::result::Result<(), sui_types::error::ExecutionError> = Ok(());
403 if !is_genesis_tx && !Mode::skip_conservation_checks() {
404 let conservation_result = {
406 temporary_store
407 .check_sui_conserved(simple_conservation_checks, cost_summary)
408 .and_then(|()| {
409 if enable_expensive_checks {
410 let mut layout_resolver =
412 TypeLayoutResolver::new(move_vm, Box::new(&*temporary_store));
413 temporary_store.check_sui_conserved_expensive(
414 cost_summary,
415 advance_epoch_gas_summary,
416 &mut layout_resolver,
417 )
418 } else {
419 Ok(())
420 }
421 })
422 };
423 if let Err(conservation_err) = conservation_result {
424 result = Err(conservation_err);
427 gas_charger.reset(temporary_store);
428 gas_charger.charge_gas(temporary_store, &mut result);
429 if let Err(recovery_err) = {
431 temporary_store
432 .check_sui_conserved(simple_conservation_checks, cost_summary)
433 .and_then(|()| {
434 if enable_expensive_checks {
435 let mut layout_resolver =
437 TypeLayoutResolver::new(move_vm, Box::new(&*temporary_store));
438 temporary_store.check_sui_conserved_expensive(
439 cost_summary,
440 advance_epoch_gas_summary,
441 &mut layout_resolver,
442 )
443 } else {
444 Ok(())
445 }
446 })
447 } {
448 panic!(
452 "SUI conservation fail in tx block {}: {}\nGas status is {}\nTx was ",
453 tx_digest,
454 recovery_err,
455 gas_charger.summary()
456 )
457 }
458 }
459 } result
462 }
463
464 #[instrument(name = "check_meter_limit", level = "debug", skip_all)]
465 fn check_meter_limit(
466 temporary_store: &mut TemporaryStore<'_>,
467 gas_charger: &mut GasCharger,
468 protocol_config: &ProtocolConfig,
469 metrics: Arc<ExecutionMetrics>,
470 ) -> Result<(), ExecutionError> {
471 let effects_estimated_size = temporary_store.estimate_effects_size_upperbound();
472
473 match check_limit_by_meter!(
477 !gas_charger.is_unmetered(),
478 effects_estimated_size,
479 protocol_config.max_serialized_tx_effects_size_bytes(),
480 protocol_config.max_serialized_tx_effects_size_bytes_system_tx(),
481 metrics.limits_metrics.excessive_estimated_effects_size
482 ) {
483 LimitThresholdCrossed::None => Ok(()),
484 LimitThresholdCrossed::Soft(_, limit) => {
485 warn!(
486 effects_estimated_size = effects_estimated_size,
487 soft_limit = limit,
488 "Estimated transaction effects size crossed soft limit",
489 );
490 Ok(())
491 }
492 LimitThresholdCrossed::Hard(_, lim) => Err(ExecutionError::new_with_source(
493 ExecutionErrorKind::EffectsTooLarge {
494 current_size: effects_estimated_size as u64,
495 max_size: lim as u64,
496 },
497 "Transaction effects are too large",
498 )),
499 }
500 }
501
502 #[instrument(name = "check_written_objects_limit", level = "debug", skip_all)]
503 fn check_written_objects_limit(
504 temporary_store: &mut TemporaryStore<'_>,
505 gas_charger: &mut GasCharger,
506 protocol_config: &ProtocolConfig,
507 metrics: Arc<ExecutionMetrics>,
508 ) -> Result<(), ExecutionError> {
509 if let (Some(normal_lim), Some(system_lim)) = (
510 protocol_config.max_size_written_objects_as_option(),
511 protocol_config.max_size_written_objects_system_tx_as_option(),
512 ) {
513 let written_objects_size = temporary_store.written_objects_size();
514
515 match check_limit_by_meter!(
516 !gas_charger.is_unmetered(),
517 written_objects_size,
518 normal_lim,
519 system_lim,
520 metrics.limits_metrics.excessive_written_objects_size
521 ) {
522 LimitThresholdCrossed::None => (),
523 LimitThresholdCrossed::Soft(_, limit) => {
524 warn!(
525 written_objects_size = written_objects_size,
526 soft_limit = limit,
527 "Written objects size crossed soft limit",
528 )
529 }
530 LimitThresholdCrossed::Hard(_, lim) => {
531 return Err(ExecutionError::new_with_source(
532 ExecutionErrorKind::WrittenObjectsTooLarge {
533 current_size: written_objects_size as u64,
534 max_size: lim as u64,
535 },
536 "Written objects size crossed hard limit",
537 ));
538 }
539 };
540 }
541
542 Ok(())
543 }
544
545 #[instrument(level = "debug", skip_all)]
546 fn execution_loop<Mode: ExecutionMode>(
547 store: &dyn BackingStore,
548 temporary_store: &mut TemporaryStore<'_>,
549 transaction_kind: TransactionKind,
550 tx_ctx: Rc<RefCell<TxContext>>,
551 move_vm: &Arc<MoveVM>,
552 gas_charger: &mut GasCharger,
553 protocol_config: &ProtocolConfig,
554 metrics: Arc<ExecutionMetrics>,
555 trace_builder_opt: &mut Option<MoveTraceBuilder>,
556 ) -> ResultWithTimings<Mode::ExecutionResults, ExecutionError> {
557 let result = match transaction_kind {
558 TransactionKind::ChangeEpoch(change_epoch) => {
559 let builder = ProgrammableTransactionBuilder::new();
560 advance_epoch(
561 builder,
562 change_epoch,
563 temporary_store,
564 store,
565 tx_ctx,
566 move_vm,
567 gas_charger,
568 protocol_config,
569 metrics,
570 trace_builder_opt,
571 )
572 .map_err(|e| (e, vec![]))?;
573 Ok((Mode::empty_results(), vec![]))
574 }
575 TransactionKind::Genesis(GenesisTransaction { objects }) => {
576 if tx_ctx.borrow().epoch() != 0 {
577 panic!("BUG: Genesis Transactions can only be executed in epoch 0");
578 }
579
580 for genesis_object in objects {
581 match genesis_object {
582 sui_types::transaction::GenesisObject::RawObject { data, owner } => {
583 let object = ObjectInner {
584 data,
585 owner,
586 previous_transaction: tx_ctx.borrow().digest(),
587 storage_rebate: 0,
588 };
589 temporary_store.create_object(object.into());
590 }
591 }
592 }
593 Ok((Mode::empty_results(), vec![]))
594 }
595 TransactionKind::ConsensusCommitPrologue(prologue) => {
596 setup_consensus_commit(
597 prologue.commit_timestamp_ms,
598 temporary_store,
599 store,
600 tx_ctx,
601 move_vm,
602 gas_charger,
603 protocol_config,
604 metrics,
605 trace_builder_opt,
606 )
607 .expect("ConsensusCommitPrologue cannot fail");
608 Ok((Mode::empty_results(), vec![]))
609 }
610 TransactionKind::ConsensusCommitPrologueV2(prologue) => {
611 setup_consensus_commit(
612 prologue.commit_timestamp_ms,
613 temporary_store,
614 store,
615 tx_ctx,
616 move_vm,
617 gas_charger,
618 protocol_config,
619 metrics,
620 trace_builder_opt,
621 )
622 .expect("ConsensusCommitPrologueV2 cannot fail");
623 Ok((Mode::empty_results(), vec![]))
624 }
625 TransactionKind::ConsensusCommitPrologueV3(prologue) => {
626 setup_consensus_commit(
627 prologue.commit_timestamp_ms,
628 temporary_store,
629 store,
630 tx_ctx,
631 move_vm,
632 gas_charger,
633 protocol_config,
634 metrics,
635 trace_builder_opt,
636 )
637 .expect("ConsensusCommitPrologueV3 cannot fail");
638 Ok((Mode::empty_results(), vec![]))
639 }
640 TransactionKind::ConsensusCommitPrologueV4(prologue) => {
641 setup_consensus_commit(
642 prologue.commit_timestamp_ms,
643 temporary_store,
644 store,
645 tx_ctx,
646 move_vm,
647 gas_charger,
648 protocol_config,
649 metrics,
650 trace_builder_opt,
651 )
652 .expect("ConsensusCommitPrologue cannot fail");
653 Ok((Mode::empty_results(), vec![]))
654 }
655 TransactionKind::ProgrammableTransaction(pt) => {
656 programmable_transactions::execution::execute::<Mode>(
657 protocol_config,
658 metrics,
659 move_vm,
660 temporary_store,
661 store.as_backing_package_store(),
662 tx_ctx,
663 gas_charger,
664 None,
665 pt,
666 trace_builder_opt,
667 )
668 }
669 TransactionKind::ProgrammableSystemTransaction(pt) => {
670 programmable_transactions::execution::execute::<execution_mode::System>(
671 protocol_config,
672 metrics,
673 move_vm,
674 temporary_store,
675 store.as_backing_package_store(),
676 tx_ctx,
677 gas_charger,
678 None,
679 pt,
680 trace_builder_opt,
681 )?;
682 Ok((Mode::empty_results(), vec![]))
683 }
684 TransactionKind::EndOfEpochTransaction(txns) => {
685 let mut builder = ProgrammableTransactionBuilder::new();
686 let len = txns.len();
687 for (i, tx) in txns.into_iter().enumerate() {
688 match tx {
689 EndOfEpochTransactionKind::ChangeEpoch(change_epoch) => {
690 assert_eq!(i, len - 1);
691 advance_epoch(
692 builder,
693 change_epoch,
694 temporary_store,
695 store,
696 tx_ctx,
697 move_vm,
698 gas_charger,
699 protocol_config,
700 metrics,
701 trace_builder_opt,
702 )
703 .map_err(|e| (e, vec![]))?;
704 return Ok((Mode::empty_results(), vec![]));
705 }
706 EndOfEpochTransactionKind::AuthenticatorStateCreate => {
707 assert!(protocol_config.enable_jwk_consensus_updates());
708 builder = setup_authenticator_state_create(builder);
709 }
710 EndOfEpochTransactionKind::AuthenticatorStateExpire(expire) => {
711 assert!(protocol_config.enable_jwk_consensus_updates());
712
713 builder = setup_authenticator_state_expire(builder, expire);
716 }
717 EndOfEpochTransactionKind::RandomnessStateCreate => {
718 assert!(protocol_config.random_beacon());
719 builder = setup_randomness_state_create(builder);
720 }
721 EndOfEpochTransactionKind::DenyListStateCreate => {
722 assert!(protocol_config.enable_coin_deny_list_v1());
723 builder = setup_coin_deny_list_state_create(builder);
724 }
725 EndOfEpochTransactionKind::BridgeStateCreate(chain_id) => {
726 assert!(protocol_config.enable_bridge());
727 builder = setup_bridge_create(builder, chain_id)
728 }
729 EndOfEpochTransactionKind::BridgeCommitteeInit(bridge_shared_version) => {
730 assert!(protocol_config.enable_bridge());
731 assert!(protocol_config.should_try_to_finalize_bridge_committee());
732 builder = setup_bridge_committee_update(builder, bridge_shared_version)
733 }
734 EndOfEpochTransactionKind::StoreExecutionTimeObservations(estimates) => {
735 if let PerObjectCongestionControlMode::ExecutionTimeEstimate(params) =
736 protocol_config.per_object_congestion_control_mode()
737 {
738 if let Some(chunk_size) = params.observations_chunk_size {
739 builder = setup_store_execution_time_estimates_v2(
740 builder,
741 estimates,
742 chunk_size as usize,
743 );
744 } else {
745 builder =
746 setup_store_execution_time_estimates(builder, estimates);
747 }
748 }
749 }
750 EndOfEpochTransactionKind::AccumulatorRootCreate => {
751 assert!(protocol_config.create_root_accumulator_object());
752 builder = setup_accumulator_root_create(builder);
753 }
754 EndOfEpochTransactionKind::WriteAccumulatorStorageCost(
755 write_storage_cost,
756 ) => {
757 assert!(protocol_config.enable_accumulators());
758 builder =
759 setup_write_accumulator_storage_cost(builder, &write_storage_cost);
760 }
761 EndOfEpochTransactionKind::CoinRegistryCreate => {
762 assert!(protocol_config.enable_coin_registry());
763 builder = setup_coin_registry_create(builder);
764 }
765 EndOfEpochTransactionKind::DisplayRegistryCreate => {
766 assert!(protocol_config.enable_display_registry());
767 builder = setup_display_registry_create(builder);
768 }
769 EndOfEpochTransactionKind::AddressAliasStateCreate => {
770 assert!(protocol_config.address_aliases());
771 builder = setup_address_alias_state_create(builder);
772 }
773 }
774 }
775 unreachable!(
776 "EndOfEpochTransactionKind::ChangeEpoch should be the last transaction in the list"
777 )
778 }
779 TransactionKind::AuthenticatorStateUpdate(auth_state_update) => {
780 setup_authenticator_state_update(
781 auth_state_update,
782 temporary_store,
783 store,
784 tx_ctx,
785 move_vm,
786 gas_charger,
787 protocol_config,
788 metrics,
789 trace_builder_opt,
790 )
791 .map_err(|e| (e, vec![]))?;
792 Ok((Mode::empty_results(), vec![]))
793 }
794 TransactionKind::RandomnessStateUpdate(randomness_state_update) => {
795 setup_randomness_state_update(
796 randomness_state_update,
797 temporary_store,
798 store,
799 tx_ctx,
800 move_vm,
801 gas_charger,
802 protocol_config,
803 metrics,
804 trace_builder_opt,
805 )
806 .map_err(|e| (e, vec![]))?;
807 Ok((Mode::empty_results(), vec![]))
808 }
809 }?;
810 temporary_store
811 .check_execution_results_consistency()
812 .map_err(|e| (e, vec![]))?;
813 Ok(result)
814 }
815
816 fn mint_epoch_rewards_in_pt(
817 builder: &mut ProgrammableTransactionBuilder,
818 params: &AdvanceEpochParams,
819 ) -> (Argument, Argument) {
820 let storage_charge_arg = builder
822 .input(CallArg::Pure(
823 bcs::to_bytes(¶ms.storage_charge).unwrap(),
824 ))
825 .unwrap();
826 let storage_rewards = builder.programmable_move_call(
827 SUI_FRAMEWORK_PACKAGE_ID,
828 BALANCE_MODULE_NAME.to_owned(),
829 BALANCE_CREATE_REWARDS_FUNCTION_NAME.to_owned(),
830 vec![GAS::type_tag()],
831 vec![storage_charge_arg],
832 );
833
834 let computation_charge_arg = builder
836 .input(CallArg::Pure(
837 bcs::to_bytes(¶ms.computation_charge).unwrap(),
838 ))
839 .unwrap();
840 let computation_rewards = builder.programmable_move_call(
841 SUI_FRAMEWORK_PACKAGE_ID,
842 BALANCE_MODULE_NAME.to_owned(),
843 BALANCE_CREATE_REWARDS_FUNCTION_NAME.to_owned(),
844 vec![GAS::type_tag()],
845 vec![computation_charge_arg],
846 );
847 (storage_rewards, computation_rewards)
848 }
849
850 pub fn construct_advance_epoch_pt(
851 mut builder: ProgrammableTransactionBuilder,
852 params: &AdvanceEpochParams,
853 ) -> Result<ProgrammableTransaction, ExecutionError> {
854 let (storage_rewards, computation_rewards) = mint_epoch_rewards_in_pt(&mut builder, params);
856
857 let mut arguments = vec![storage_rewards, computation_rewards];
859 let call_arg_arguments = vec![
860 CallArg::SUI_SYSTEM_MUT,
861 CallArg::Pure(bcs::to_bytes(¶ms.epoch).unwrap()),
862 CallArg::Pure(bcs::to_bytes(¶ms.next_protocol_version.as_u64()).unwrap()),
863 CallArg::Pure(bcs::to_bytes(¶ms.storage_rebate).unwrap()),
864 CallArg::Pure(bcs::to_bytes(¶ms.non_refundable_storage_fee).unwrap()),
865 CallArg::Pure(bcs::to_bytes(¶ms.storage_fund_reinvest_rate).unwrap()),
866 CallArg::Pure(bcs::to_bytes(¶ms.reward_slashing_rate).unwrap()),
867 CallArg::Pure(bcs::to_bytes(¶ms.epoch_start_timestamp_ms).unwrap()),
868 ]
869 .into_iter()
870 .map(|a| builder.input(a))
871 .collect::<Result<_, _>>();
872
873 assert_invariant!(
874 call_arg_arguments.is_ok(),
875 "Unable to generate args for advance_epoch transaction!"
876 );
877
878 arguments.append(&mut call_arg_arguments.unwrap());
879
880 info!("Call arguments to advance_epoch transaction: {:?}", params);
881
882 let storage_rebates = builder.programmable_move_call(
883 SUI_SYSTEM_PACKAGE_ID,
884 SUI_SYSTEM_MODULE_NAME.to_owned(),
885 ADVANCE_EPOCH_FUNCTION_NAME.to_owned(),
886 vec![],
887 arguments,
888 );
889
890 builder.programmable_move_call(
892 SUI_FRAMEWORK_PACKAGE_ID,
893 BALANCE_MODULE_NAME.to_owned(),
894 BALANCE_DESTROY_REBATES_FUNCTION_NAME.to_owned(),
895 vec![GAS::type_tag()],
896 vec![storage_rebates],
897 );
898 Ok(builder.finish())
899 }
900
901 pub fn construct_advance_epoch_safe_mode_pt(
902 params: &AdvanceEpochParams,
903 protocol_config: &ProtocolConfig,
904 ) -> Result<ProgrammableTransaction, ExecutionError> {
905 let mut builder = ProgrammableTransactionBuilder::new();
906 let (storage_rewards, computation_rewards) = mint_epoch_rewards_in_pt(&mut builder, params);
908
909 let mut arguments = vec![storage_rewards, computation_rewards];
911
912 let mut args = vec![
913 CallArg::SUI_SYSTEM_MUT,
914 CallArg::Pure(bcs::to_bytes(¶ms.epoch).unwrap()),
915 CallArg::Pure(bcs::to_bytes(¶ms.next_protocol_version.as_u64()).unwrap()),
916 CallArg::Pure(bcs::to_bytes(¶ms.storage_rebate).unwrap()),
917 CallArg::Pure(bcs::to_bytes(¶ms.non_refundable_storage_fee).unwrap()),
918 ];
919
920 if protocol_config.get_advance_epoch_start_time_in_safe_mode() {
921 args.push(CallArg::Pure(
922 bcs::to_bytes(¶ms.epoch_start_timestamp_ms).unwrap(),
923 ));
924 }
925
926 let call_arg_arguments = args
927 .into_iter()
928 .map(|a| builder.input(a))
929 .collect::<Result<_, _>>();
930
931 assert_invariant!(
932 call_arg_arguments.is_ok(),
933 "Unable to generate args for advance_epoch transaction!"
934 );
935
936 arguments.append(&mut call_arg_arguments.unwrap());
937
938 info!("Call arguments to advance_epoch transaction: {:?}", params);
939
940 builder.programmable_move_call(
941 SUI_SYSTEM_PACKAGE_ID,
942 SUI_SYSTEM_MODULE_NAME.to_owned(),
943 ADVANCE_EPOCH_SAFE_MODE_FUNCTION_NAME.to_owned(),
944 vec![],
945 arguments,
946 );
947
948 Ok(builder.finish())
949 }
950
951 fn advance_epoch(
952 builder: ProgrammableTransactionBuilder,
953 change_epoch: ChangeEpoch,
954 temporary_store: &mut TemporaryStore<'_>,
955 store: &dyn BackingStore,
956 tx_ctx: Rc<RefCell<TxContext>>,
957 move_vm: &Arc<MoveVM>,
958 gas_charger: &mut GasCharger,
959 protocol_config: &ProtocolConfig,
960 metrics: Arc<ExecutionMetrics>,
961 trace_builder_opt: &mut Option<MoveTraceBuilder>,
962 ) -> Result<(), ExecutionError> {
963 let params = AdvanceEpochParams {
964 epoch: change_epoch.epoch,
965 next_protocol_version: change_epoch.protocol_version,
966 storage_charge: change_epoch.storage_charge,
967 computation_charge: change_epoch.computation_charge,
968 storage_rebate: change_epoch.storage_rebate,
969 non_refundable_storage_fee: change_epoch.non_refundable_storage_fee,
970 storage_fund_reinvest_rate: protocol_config.storage_fund_reinvest_rate(),
971 reward_slashing_rate: protocol_config.reward_slashing_rate(),
972 epoch_start_timestamp_ms: change_epoch.epoch_start_timestamp_ms,
973 };
974 let advance_epoch_pt = construct_advance_epoch_pt(builder, ¶ms)?;
975 let result = programmable_transactions::execution::execute::<execution_mode::System>(
976 protocol_config,
977 metrics.clone(),
978 move_vm,
979 temporary_store,
980 store.as_backing_package_store(),
981 tx_ctx.clone(),
982 gas_charger,
983 None,
984 advance_epoch_pt,
985 trace_builder_opt,
986 );
987
988 #[cfg(msim)]
989 let result = maybe_modify_result(result, change_epoch.epoch);
990
991 if let Err(err) = &result {
992 tracing::error!(
993 "Failed to execute advance epoch transaction. Switching to safe mode. Error: {:?}. Input objects: {:?}. Tx data: {:?}",
994 err.0,
995 temporary_store.objects(),
996 change_epoch,
997 );
998 temporary_store.drop_writes();
999 gas_charger.reset_storage_cost_and_rebate();
1001
1002 if protocol_config.get_advance_epoch_start_time_in_safe_mode() {
1003 temporary_store.advance_epoch_safe_mode(¶ms, protocol_config);
1004 } else {
1005 let advance_epoch_safe_mode_pt =
1006 construct_advance_epoch_safe_mode_pt(¶ms, protocol_config)?;
1007 programmable_transactions::execution::execute::<execution_mode::System>(
1008 protocol_config,
1009 metrics.clone(),
1010 move_vm,
1011 temporary_store,
1012 store.as_backing_package_store(),
1013 tx_ctx.clone(),
1014 gas_charger,
1015 None,
1016 advance_epoch_safe_mode_pt,
1017 trace_builder_opt,
1018 )
1019 .map_err(|(e, _)| e)
1020 .expect("Advance epoch with safe mode must succeed");
1021 }
1022 }
1023
1024 if protocol_config.fresh_vm_on_framework_upgrade() {
1025 let new_vm = new_move_vm(
1026 all_natives(true, protocol_config),
1027 protocol_config,
1028 )
1029 .expect("Failed to create new MoveVM");
1030 process_system_packages(
1031 change_epoch,
1032 temporary_store,
1033 store,
1034 tx_ctx,
1035 &new_vm,
1036 gas_charger,
1037 protocol_config,
1038 metrics,
1039 trace_builder_opt,
1040 );
1041 } else {
1042 process_system_packages(
1043 change_epoch,
1044 temporary_store,
1045 store,
1046 tx_ctx,
1047 move_vm,
1048 gas_charger,
1049 protocol_config,
1050 metrics,
1051 trace_builder_opt,
1052 );
1053 }
1054 Ok(())
1055 }
1056
1057 fn process_system_packages(
1058 change_epoch: ChangeEpoch,
1059 temporary_store: &mut TemporaryStore<'_>,
1060 store: &dyn BackingStore,
1061 tx_ctx: Rc<RefCell<TxContext>>,
1062 move_vm: &MoveVM,
1063 gas_charger: &mut GasCharger,
1064 protocol_config: &ProtocolConfig,
1065 metrics: Arc<ExecutionMetrics>,
1066 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1067 ) {
1068 let digest = tx_ctx.borrow().digest();
1069 let binary_config = protocol_config.binary_config(None);
1070 for (version, modules, dependencies) in change_epoch.system_packages.into_iter() {
1071 let deserialized_modules: Vec<_> = modules
1072 .iter()
1073 .map(|m| CompiledModule::deserialize_with_config(m, &binary_config).unwrap())
1074 .collect();
1075
1076 if version == OBJECT_START_VERSION {
1077 let package_id = deserialized_modules.first().unwrap().address();
1078 info!("adding new system package {package_id}");
1079
1080 let publish_pt = {
1081 let mut b = ProgrammableTransactionBuilder::new();
1082 b.command(Command::Publish(modules, dependencies));
1083 b.finish()
1084 };
1085
1086 programmable_transactions::execution::execute::<execution_mode::System>(
1087 protocol_config,
1088 metrics.clone(),
1089 move_vm,
1090 temporary_store,
1091 store.as_backing_package_store(),
1092 tx_ctx.clone(),
1093 gas_charger,
1094 None,
1095 publish_pt,
1096 trace_builder_opt,
1097 )
1098 .map_err(|(e, _)| e)
1099 .expect("System Package Publish must succeed");
1100 } else {
1101 let mut new_package = Object::new_system_package(
1102 &deserialized_modules,
1103 version,
1104 dependencies,
1105 digest,
1106 );
1107
1108 info!(
1109 "upgraded system package {:?}",
1110 new_package.compute_object_reference()
1111 );
1112
1113 new_package
1116 .data
1117 .try_as_package_mut()
1118 .unwrap()
1119 .decrement_version();
1120
1121 temporary_store.upgrade_system_package(new_package);
1123 }
1124 }
1125 }
1126
1127 fn setup_consensus_commit(
1132 consensus_commit_timestamp_ms: CheckpointTimestamp,
1133 temporary_store: &mut TemporaryStore<'_>,
1134 store: &dyn BackingStore,
1135 tx_ctx: Rc<RefCell<TxContext>>,
1136 move_vm: &Arc<MoveVM>,
1137 gas_charger: &mut GasCharger,
1138 protocol_config: &ProtocolConfig,
1139 metrics: Arc<ExecutionMetrics>,
1140 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1141 ) -> Result<(), ExecutionError> {
1142 let pt = {
1143 let mut builder = ProgrammableTransactionBuilder::new();
1144 let res = builder.move_call(
1145 SUI_FRAMEWORK_ADDRESS.into(),
1146 CLOCK_MODULE_NAME.to_owned(),
1147 CONSENSUS_COMMIT_PROLOGUE_FUNCTION_NAME.to_owned(),
1148 vec![],
1149 vec![
1150 CallArg::CLOCK_MUT,
1151 CallArg::Pure(bcs::to_bytes(&consensus_commit_timestamp_ms).unwrap()),
1152 ],
1153 );
1154 assert_invariant!(
1155 res.is_ok(),
1156 "Unable to generate consensus_commit_prologue transaction!"
1157 );
1158 builder.finish()
1159 };
1160 programmable_transactions::execution::execute::<execution_mode::System>(
1161 protocol_config,
1162 metrics,
1163 move_vm,
1164 temporary_store,
1165 store.as_backing_package_store(),
1166 tx_ctx,
1167 gas_charger,
1168 None,
1169 pt,
1170 trace_builder_opt,
1171 )
1172 .map_err(|(e, _)| e)?;
1173 Ok(())
1174 }
1175
1176 fn setup_authenticator_state_create(
1177 mut builder: ProgrammableTransactionBuilder,
1178 ) -> ProgrammableTransactionBuilder {
1179 builder
1180 .move_call(
1181 SUI_FRAMEWORK_ADDRESS.into(),
1182 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1183 AUTHENTICATOR_STATE_CREATE_FUNCTION_NAME.to_owned(),
1184 vec![],
1185 vec![],
1186 )
1187 .expect("Unable to generate authenticator_state_create transaction!");
1188 builder
1189 }
1190
1191 fn setup_randomness_state_create(
1192 mut builder: ProgrammableTransactionBuilder,
1193 ) -> ProgrammableTransactionBuilder {
1194 builder
1195 .move_call(
1196 SUI_FRAMEWORK_ADDRESS.into(),
1197 RANDOMNESS_MODULE_NAME.to_owned(),
1198 RANDOMNESS_STATE_CREATE_FUNCTION_NAME.to_owned(),
1199 vec![],
1200 vec![],
1201 )
1202 .expect("Unable to generate randomness_state_create transaction!");
1203 builder
1204 }
1205
1206 fn setup_bridge_create(
1207 mut builder: ProgrammableTransactionBuilder,
1208 chain_id: ChainIdentifier,
1209 ) -> ProgrammableTransactionBuilder {
1210 let bridge_uid = builder
1211 .input(CallArg::Pure(UID::new(SUI_BRIDGE_OBJECT_ID).to_bcs_bytes()))
1212 .expect("Unable to create Bridge object UID!");
1213
1214 let bridge_chain_id = if chain_id == get_mainnet_chain_identifier() {
1215 BridgeChainId::SuiMainnet as u8
1216 } else if chain_id == get_testnet_chain_identifier() {
1217 BridgeChainId::SuiTestnet as u8
1218 } else {
1219 BridgeChainId::SuiCustom as u8
1221 };
1222
1223 let bridge_chain_id = builder.pure(bridge_chain_id).unwrap();
1224 builder.programmable_move_call(
1225 BRIDGE_ADDRESS.into(),
1226 BRIDGE_MODULE_NAME.to_owned(),
1227 BRIDGE_CREATE_FUNCTION_NAME.to_owned(),
1228 vec![],
1229 vec![bridge_uid, bridge_chain_id],
1230 );
1231 builder
1232 }
1233
1234 fn setup_bridge_committee_update(
1235 mut builder: ProgrammableTransactionBuilder,
1236 bridge_shared_version: SequenceNumber,
1237 ) -> ProgrammableTransactionBuilder {
1238 let bridge = builder
1239 .obj(ObjectArg::SharedObject {
1240 id: SUI_BRIDGE_OBJECT_ID,
1241 initial_shared_version: bridge_shared_version,
1242 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1243 })
1244 .expect("Unable to create Bridge object arg!");
1245 let system_state = builder
1246 .obj(ObjectArg::SUI_SYSTEM_MUT)
1247 .expect("Unable to create System State object arg!");
1248
1249 let voting_power = builder.programmable_move_call(
1250 SUI_SYSTEM_PACKAGE_ID,
1251 SUI_SYSTEM_MODULE_NAME.to_owned(),
1252 ident_str!("validator_voting_powers").to_owned(),
1253 vec![],
1254 vec![system_state],
1255 );
1256
1257 let min_stake_participation_percentage = builder
1260 .input(CallArg::Pure(
1261 bcs::to_bytes(&BRIDGE_COMMITTEE_MINIMAL_VOTING_POWER).unwrap(),
1262 ))
1263 .unwrap();
1264
1265 builder.programmable_move_call(
1266 BRIDGE_ADDRESS.into(),
1267 BRIDGE_MODULE_NAME.to_owned(),
1268 BRIDGE_INIT_COMMITTEE_FUNCTION_NAME.to_owned(),
1269 vec![],
1270 vec![bridge, voting_power, min_stake_participation_percentage],
1271 );
1272 builder
1273 }
1274
1275 fn setup_authenticator_state_update(
1276 update: AuthenticatorStateUpdate,
1277 temporary_store: &mut TemporaryStore<'_>,
1278 store: &dyn BackingStore,
1279 tx_ctx: Rc<RefCell<TxContext>>,
1280 move_vm: &Arc<MoveVM>,
1281 gas_charger: &mut GasCharger,
1282 protocol_config: &ProtocolConfig,
1283 metrics: Arc<ExecutionMetrics>,
1284 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1285 ) -> Result<(), ExecutionError> {
1286 let pt = {
1287 let mut builder = ProgrammableTransactionBuilder::new();
1288 let res = builder.move_call(
1289 SUI_FRAMEWORK_ADDRESS.into(),
1290 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1291 AUTHENTICATOR_STATE_UPDATE_FUNCTION_NAME.to_owned(),
1292 vec![],
1293 vec![
1294 CallArg::Object(ObjectArg::SharedObject {
1295 id: SUI_AUTHENTICATOR_STATE_OBJECT_ID,
1296 initial_shared_version: update.authenticator_obj_initial_shared_version,
1297 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1298 }),
1299 CallArg::Pure(bcs::to_bytes(&update.new_active_jwks).unwrap()),
1300 ],
1301 );
1302 assert_invariant!(
1303 res.is_ok(),
1304 "Unable to generate authenticator_state_update transaction!"
1305 );
1306 builder.finish()
1307 };
1308 programmable_transactions::execution::execute::<execution_mode::System>(
1309 protocol_config,
1310 metrics,
1311 move_vm,
1312 temporary_store,
1313 store.as_backing_package_store(),
1314 tx_ctx,
1315 gas_charger,
1316 None,
1317 pt,
1318 trace_builder_opt,
1319 )
1320 .map_err(|(e, _)| e)?;
1321 Ok(())
1322 }
1323
1324 fn setup_authenticator_state_expire(
1325 mut builder: ProgrammableTransactionBuilder,
1326 expire: AuthenticatorStateExpire,
1327 ) -> ProgrammableTransactionBuilder {
1328 builder
1329 .move_call(
1330 SUI_FRAMEWORK_ADDRESS.into(),
1331 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1332 AUTHENTICATOR_STATE_EXPIRE_JWKS_FUNCTION_NAME.to_owned(),
1333 vec![],
1334 vec![
1335 CallArg::Object(ObjectArg::SharedObject {
1336 id: SUI_AUTHENTICATOR_STATE_OBJECT_ID,
1337 initial_shared_version: expire.authenticator_obj_initial_shared_version,
1338 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1339 }),
1340 CallArg::Pure(bcs::to_bytes(&expire.min_epoch).unwrap()),
1341 ],
1342 )
1343 .expect("Unable to generate authenticator_state_expire transaction!");
1344 builder
1345 }
1346
1347 fn setup_randomness_state_update(
1348 update: RandomnessStateUpdate,
1349 temporary_store: &mut TemporaryStore<'_>,
1350 store: &dyn BackingStore,
1351 tx_ctx: Rc<RefCell<TxContext>>,
1352 move_vm: &Arc<MoveVM>,
1353 gas_charger: &mut GasCharger,
1354 protocol_config: &ProtocolConfig,
1355 metrics: Arc<ExecutionMetrics>,
1356 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1357 ) -> Result<(), ExecutionError> {
1358 let pt = {
1359 let mut builder = ProgrammableTransactionBuilder::new();
1360 let res = builder.move_call(
1361 SUI_FRAMEWORK_ADDRESS.into(),
1362 RANDOMNESS_MODULE_NAME.to_owned(),
1363 RANDOMNESS_STATE_UPDATE_FUNCTION_NAME.to_owned(),
1364 vec![],
1365 vec![
1366 CallArg::Object(ObjectArg::SharedObject {
1367 id: SUI_RANDOMNESS_STATE_OBJECT_ID,
1368 initial_shared_version: update.randomness_obj_initial_shared_version,
1369 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1370 }),
1371 CallArg::Pure(bcs::to_bytes(&update.randomness_round).unwrap()),
1372 CallArg::Pure(bcs::to_bytes(&update.random_bytes).unwrap()),
1373 ],
1374 );
1375 assert_invariant!(
1376 res.is_ok(),
1377 "Unable to generate randomness_state_update transaction!"
1378 );
1379 builder.finish()
1380 };
1381 programmable_transactions::execution::execute::<execution_mode::System>(
1382 protocol_config,
1383 metrics,
1384 move_vm,
1385 temporary_store,
1386 store.as_backing_package_store(),
1387 tx_ctx,
1388 gas_charger,
1389 None,
1390 pt,
1391 trace_builder_opt,
1392 )
1393 .map_err(|(e, _)| e)?;
1394 Ok(())
1395 }
1396
1397 fn setup_coin_deny_list_state_create(
1398 mut builder: ProgrammableTransactionBuilder,
1399 ) -> ProgrammableTransactionBuilder {
1400 builder
1401 .move_call(
1402 SUI_FRAMEWORK_ADDRESS.into(),
1403 DENY_LIST_MODULE.to_owned(),
1404 DENY_LIST_CREATE_FUNC.to_owned(),
1405 vec![],
1406 vec![],
1407 )
1408 .expect("Unable to generate coin_deny_list_create transaction!");
1409 builder
1410 }
1411
1412 fn setup_store_execution_time_estimates(
1413 mut builder: ProgrammableTransactionBuilder,
1414 estimates: StoredExecutionTimeObservations,
1415 ) -> ProgrammableTransactionBuilder {
1416 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1417 let estimates_bytes = bcs::to_bytes(&estimates).unwrap();
1420 let estimates_arg = builder.pure(estimates_bytes).unwrap();
1421 builder.programmable_move_call(
1422 SUI_SYSTEM_PACKAGE_ID,
1423 SUI_SYSTEM_MODULE_NAME.to_owned(),
1424 ident_str!("store_execution_time_estimates").to_owned(),
1425 vec![],
1426 vec![system_state, estimates_arg],
1427 );
1428 builder
1429 }
1430
1431 fn setup_store_execution_time_estimates_v2(
1432 mut builder: ProgrammableTransactionBuilder,
1433 estimates: StoredExecutionTimeObservations,
1434 chunk_size: usize,
1435 ) -> ProgrammableTransactionBuilder {
1436 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1437
1438 let estimate_chunks = estimates.chunk_observations(chunk_size);
1439
1440 let chunk_bytes: Vec<Vec<u8>> = estimate_chunks
1441 .into_iter()
1442 .map(|chunk| bcs::to_bytes(&chunk).unwrap())
1443 .collect();
1444
1445 let chunks_arg = builder.pure(chunk_bytes).unwrap();
1446
1447 builder.programmable_move_call(
1448 SUI_SYSTEM_PACKAGE_ID,
1449 SUI_SYSTEM_MODULE_NAME.to_owned(),
1450 ident_str!("store_execution_time_estimates_v2").to_owned(),
1451 vec![],
1452 vec![system_state, chunks_arg],
1453 );
1454 builder
1455 }
1456
1457 fn setup_accumulator_root_create(
1458 mut builder: ProgrammableTransactionBuilder,
1459 ) -> ProgrammableTransactionBuilder {
1460 builder
1461 .move_call(
1462 SUI_FRAMEWORK_ADDRESS.into(),
1463 ACCUMULATOR_ROOT_MODULE.to_owned(),
1464 ACCUMULATOR_ROOT_CREATE_FUNC.to_owned(),
1465 vec![],
1466 vec![],
1467 )
1468 .expect("Unable to generate accumulator_root_create transaction!");
1469 builder
1470 }
1471
1472 fn setup_write_accumulator_storage_cost(
1473 mut builder: ProgrammableTransactionBuilder,
1474 write_storage_cost: &WriteAccumulatorStorageCost,
1475 ) -> ProgrammableTransactionBuilder {
1476 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1477 let storage_cost_arg = builder.pure(write_storage_cost.storage_cost).unwrap();
1478 builder.programmable_move_call(
1479 SUI_SYSTEM_PACKAGE_ID,
1480 SUI_SYSTEM_MODULE_NAME.to_owned(),
1481 ident_str!("write_accumulator_storage_cost").to_owned(),
1482 vec![],
1483 vec![system_state, storage_cost_arg],
1484 );
1485 builder
1486 }
1487
1488 fn setup_coin_registry_create(
1489 mut builder: ProgrammableTransactionBuilder,
1490 ) -> ProgrammableTransactionBuilder {
1491 builder
1492 .move_call(
1493 SUI_FRAMEWORK_ADDRESS.into(),
1494 ident_str!("coin_registry").to_owned(),
1495 ident_str!("create").to_owned(),
1496 vec![],
1497 vec![],
1498 )
1499 .expect("Unable to generate coin_registry_create transaction!");
1500 builder
1501 }
1502
1503 fn setup_display_registry_create(
1504 mut builder: ProgrammableTransactionBuilder,
1505 ) -> ProgrammableTransactionBuilder {
1506 builder
1507 .move_call(
1508 SUI_FRAMEWORK_ADDRESS.into(),
1509 ident_str!("display_registry").to_owned(),
1510 ident_str!("create").to_owned(),
1511 vec![],
1512 vec![],
1513 )
1514 .expect("Unable to generate display_registry_create transaction!");
1515 builder
1516 }
1517
1518 fn setup_address_alias_state_create(
1519 mut builder: ProgrammableTransactionBuilder,
1520 ) -> ProgrammableTransactionBuilder {
1521 builder
1522 .move_call(
1523 SUI_FRAMEWORK_ADDRESS.into(),
1524 ident_str!("address_alias").to_owned(),
1525 ident_str!("create").to_owned(),
1526 vec![],
1527 vec![],
1528 )
1529 .expect("Unable to generate address_alias_state_create transaction!");
1530 builder
1531 }
1532}