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.into_early_errors() {
315 Some(early_execution_errors) => Err((
316 ExecutionError::new(early_execution_errors.head, None),
317 vec![],
318 )),
319 None => execution_loop::<Mode>(
320 store,
321 temporary_store,
322 transaction_kind,
323 tx_ctx,
324 move_vm,
325 gas_charger,
326 protocol_config,
327 metrics.clone(),
328 trace_builder_opt,
329 ),
330 };
331
332 let meter_check = check_meter_limit(
333 temporary_store,
334 gas_charger,
335 protocol_config,
336 metrics.clone(),
337 );
338 if let Err(e) = meter_check {
339 execution_result = Err((e, vec![]));
340 }
341
342 if execution_result.is_ok() {
343 let gas_check = check_written_objects_limit(
344 temporary_store,
345 gas_charger,
346 protocol_config,
347 metrics,
348 );
349 if let Err(e) = gas_check {
350 execution_result = Err((e, vec![]));
351 }
352 }
353
354 execution_result
355 },
356 );
357
358 let (mut result, timings) = match result {
359 Ok((r, t)) => (Ok(r), t),
360 Err((e, t)) => (Err(e), t),
361 };
362
363 let cost_summary = gas_charger.charge_gas(temporary_store, &mut result);
364 temporary_store.conserve_unmetered_storage_rebate(gas_charger.unmetered_storage_rebate());
372
373 if let Err(e) = run_conservation_checks::<Mode>(
374 temporary_store,
375 gas_charger,
376 digest,
377 move_vm,
378 protocol_config.simple_conservation_checks(),
379 enable_expensive_checks,
380 &cost_summary,
381 is_genesis_tx,
382 advance_epoch_gas_summary,
383 ) {
384 result = Err(e);
386 }
387
388 (cost_summary, result, timings)
389 }
390
391 #[instrument(name = "run_conservation_checks", level = "debug", skip_all)]
392 fn run_conservation_checks<Mode: ExecutionMode>(
393 temporary_store: &mut TemporaryStore<'_>,
394 gas_charger: &mut GasCharger,
395 tx_digest: TransactionDigest,
396 move_vm: &Arc<MoveVM>,
397 simple_conservation_checks: bool,
398 enable_expensive_checks: bool,
399 cost_summary: &GasCostSummary,
400 is_genesis_tx: bool,
401 advance_epoch_gas_summary: Option<(u64, u64)>,
402 ) -> Result<(), ExecutionError> {
403 let mut result: std::result::Result<(), sui_types::error::ExecutionError> = Ok(());
404 if !is_genesis_tx && !Mode::skip_conservation_checks() {
405 let conservation_result = {
407 temporary_store
408 .check_sui_conserved(simple_conservation_checks, cost_summary)
409 .and_then(|()| {
410 if enable_expensive_checks {
411 let mut layout_resolver =
413 TypeLayoutResolver::new(move_vm, Box::new(&*temporary_store));
414 temporary_store.check_sui_conserved_expensive(
415 cost_summary,
416 advance_epoch_gas_summary,
417 &mut layout_resolver,
418 )
419 } else {
420 Ok(())
421 }
422 })
423 };
424 if let Err(conservation_err) = conservation_result {
425 result = Err(conservation_err);
428 gas_charger.reset(temporary_store);
429 gas_charger.charge_gas(temporary_store, &mut result);
430 if let Err(recovery_err) = {
432 temporary_store
433 .check_sui_conserved(simple_conservation_checks, cost_summary)
434 .and_then(|()| {
435 if enable_expensive_checks {
436 let mut layout_resolver =
438 TypeLayoutResolver::new(move_vm, Box::new(&*temporary_store));
439 temporary_store.check_sui_conserved_expensive(
440 cost_summary,
441 advance_epoch_gas_summary,
442 &mut layout_resolver,
443 )
444 } else {
445 Ok(())
446 }
447 })
448 } {
449 panic!(
453 "SUI conservation fail in tx block {}: {}\nGas status is {}\nTx was ",
454 tx_digest,
455 recovery_err,
456 gas_charger.summary()
457 )
458 }
459 }
460 } result
463 }
464
465 #[instrument(name = "check_meter_limit", level = "debug", skip_all)]
466 fn check_meter_limit(
467 temporary_store: &mut TemporaryStore<'_>,
468 gas_charger: &mut GasCharger,
469 protocol_config: &ProtocolConfig,
470 metrics: Arc<ExecutionMetrics>,
471 ) -> Result<(), ExecutionError> {
472 let effects_estimated_size = temporary_store.estimate_effects_size_upperbound();
473
474 match check_limit_by_meter!(
478 !gas_charger.is_unmetered(),
479 effects_estimated_size,
480 protocol_config.max_serialized_tx_effects_size_bytes(),
481 protocol_config.max_serialized_tx_effects_size_bytes_system_tx(),
482 metrics.limits_metrics.excessive_estimated_effects_size
483 ) {
484 LimitThresholdCrossed::None => Ok(()),
485 LimitThresholdCrossed::Soft(_, limit) => {
486 warn!(
487 effects_estimated_size = effects_estimated_size,
488 soft_limit = limit,
489 "Estimated transaction effects size crossed soft limit",
490 );
491 Ok(())
492 }
493 LimitThresholdCrossed::Hard(_, lim) => Err(ExecutionError::new_with_source(
494 ExecutionErrorKind::EffectsTooLarge {
495 current_size: effects_estimated_size as u64,
496 max_size: lim as u64,
497 },
498 "Transaction effects are too large",
499 )),
500 }
501 }
502
503 #[instrument(name = "check_written_objects_limit", level = "debug", skip_all)]
504 fn check_written_objects_limit(
505 temporary_store: &mut TemporaryStore<'_>,
506 gas_charger: &mut GasCharger,
507 protocol_config: &ProtocolConfig,
508 metrics: Arc<ExecutionMetrics>,
509 ) -> Result<(), ExecutionError> {
510 if let (Some(normal_lim), Some(system_lim)) = (
511 protocol_config.max_size_written_objects_as_option(),
512 protocol_config.max_size_written_objects_system_tx_as_option(),
513 ) {
514 let written_objects_size = temporary_store.written_objects_size();
515
516 match check_limit_by_meter!(
517 !gas_charger.is_unmetered(),
518 written_objects_size,
519 normal_lim,
520 system_lim,
521 metrics.limits_metrics.excessive_written_objects_size
522 ) {
523 LimitThresholdCrossed::None => (),
524 LimitThresholdCrossed::Soft(_, limit) => {
525 warn!(
526 written_objects_size = written_objects_size,
527 soft_limit = limit,
528 "Written objects size crossed soft limit",
529 )
530 }
531 LimitThresholdCrossed::Hard(_, lim) => {
532 return Err(ExecutionError::new_with_source(
533 ExecutionErrorKind::WrittenObjectsTooLarge {
534 current_size: written_objects_size as u64,
535 max_size: lim as u64,
536 },
537 "Written objects size crossed hard limit",
538 ));
539 }
540 };
541 }
542
543 Ok(())
544 }
545
546 #[instrument(level = "debug", skip_all)]
547 fn execution_loop<Mode: ExecutionMode>(
548 store: &dyn BackingStore,
549 temporary_store: &mut TemporaryStore<'_>,
550 transaction_kind: TransactionKind,
551 tx_ctx: Rc<RefCell<TxContext>>,
552 move_vm: &Arc<MoveVM>,
553 gas_charger: &mut GasCharger,
554 protocol_config: &ProtocolConfig,
555 metrics: Arc<ExecutionMetrics>,
556 trace_builder_opt: &mut Option<MoveTraceBuilder>,
557 ) -> ResultWithTimings<Mode::ExecutionResults, ExecutionError> {
558 let result = match transaction_kind {
559 TransactionKind::ChangeEpoch(change_epoch) => {
560 let builder = ProgrammableTransactionBuilder::new();
561 advance_epoch(
562 builder,
563 change_epoch,
564 temporary_store,
565 store,
566 tx_ctx,
567 move_vm,
568 gas_charger,
569 protocol_config,
570 metrics,
571 trace_builder_opt,
572 )
573 .map_err(|e| (e, vec![]))?;
574 Ok((Mode::empty_results(), vec![]))
575 }
576 TransactionKind::Genesis(GenesisTransaction { objects }) => {
577 if tx_ctx.borrow().epoch() != 0 {
578 panic!("BUG: Genesis Transactions can only be executed in epoch 0");
579 }
580
581 for genesis_object in objects {
582 match genesis_object {
583 sui_types::transaction::GenesisObject::RawObject { data, owner } => {
584 let object = ObjectInner {
585 data,
586 owner,
587 previous_transaction: tx_ctx.borrow().digest(),
588 storage_rebate: 0,
589 };
590 temporary_store.create_object(object.into());
591 }
592 }
593 }
594 Ok((Mode::empty_results(), vec![]))
595 }
596 TransactionKind::ConsensusCommitPrologue(prologue) => {
597 setup_consensus_commit(
598 prologue.commit_timestamp_ms,
599 temporary_store,
600 store,
601 tx_ctx,
602 move_vm,
603 gas_charger,
604 protocol_config,
605 metrics,
606 trace_builder_opt,
607 )
608 .expect("ConsensusCommitPrologue cannot fail");
609 Ok((Mode::empty_results(), vec![]))
610 }
611 TransactionKind::ConsensusCommitPrologueV2(prologue) => {
612 setup_consensus_commit(
613 prologue.commit_timestamp_ms,
614 temporary_store,
615 store,
616 tx_ctx,
617 move_vm,
618 gas_charger,
619 protocol_config,
620 metrics,
621 trace_builder_opt,
622 )
623 .expect("ConsensusCommitPrologueV2 cannot fail");
624 Ok((Mode::empty_results(), vec![]))
625 }
626 TransactionKind::ConsensusCommitPrologueV3(prologue) => {
627 setup_consensus_commit(
628 prologue.commit_timestamp_ms,
629 temporary_store,
630 store,
631 tx_ctx,
632 move_vm,
633 gas_charger,
634 protocol_config,
635 metrics,
636 trace_builder_opt,
637 )
638 .expect("ConsensusCommitPrologueV3 cannot fail");
639 Ok((Mode::empty_results(), vec![]))
640 }
641 TransactionKind::ConsensusCommitPrologueV4(prologue) => {
642 setup_consensus_commit(
643 prologue.commit_timestamp_ms,
644 temporary_store,
645 store,
646 tx_ctx,
647 move_vm,
648 gas_charger,
649 protocol_config,
650 metrics,
651 trace_builder_opt,
652 )
653 .expect("ConsensusCommitPrologue cannot fail");
654 Ok((Mode::empty_results(), vec![]))
655 }
656 TransactionKind::ProgrammableTransaction(pt) => {
657 programmable_transactions::execution::execute::<Mode>(
658 protocol_config,
659 metrics,
660 move_vm,
661 temporary_store,
662 store.as_backing_package_store(),
663 tx_ctx,
664 gas_charger,
665 None,
666 pt,
667 trace_builder_opt,
668 )
669 }
670 TransactionKind::ProgrammableSystemTransaction(pt) => {
671 programmable_transactions::execution::execute::<execution_mode::System>(
672 protocol_config,
673 metrics,
674 move_vm,
675 temporary_store,
676 store.as_backing_package_store(),
677 tx_ctx,
678 gas_charger,
679 None,
680 pt,
681 trace_builder_opt,
682 )?;
683 Ok((Mode::empty_results(), vec![]))
684 }
685 TransactionKind::EndOfEpochTransaction(txns) => {
686 let mut builder = ProgrammableTransactionBuilder::new();
687 let len = txns.len();
688 for (i, tx) in txns.into_iter().enumerate() {
689 match tx {
690 EndOfEpochTransactionKind::ChangeEpoch(change_epoch) => {
691 assert_eq!(i, len - 1);
692 advance_epoch(
693 builder,
694 change_epoch,
695 temporary_store,
696 store,
697 tx_ctx,
698 move_vm,
699 gas_charger,
700 protocol_config,
701 metrics,
702 trace_builder_opt,
703 )
704 .map_err(|e| (e, vec![]))?;
705 return Ok((Mode::empty_results(), vec![]));
706 }
707 EndOfEpochTransactionKind::AuthenticatorStateCreate => {
708 assert!(protocol_config.enable_jwk_consensus_updates());
709 builder = setup_authenticator_state_create(builder);
710 }
711 EndOfEpochTransactionKind::AuthenticatorStateExpire(expire) => {
712 assert!(protocol_config.enable_jwk_consensus_updates());
713
714 builder = setup_authenticator_state_expire(builder, expire);
717 }
718 EndOfEpochTransactionKind::RandomnessStateCreate => {
719 assert!(protocol_config.random_beacon());
720 builder = setup_randomness_state_create(builder);
721 }
722 EndOfEpochTransactionKind::DenyListStateCreate => {
723 assert!(protocol_config.enable_coin_deny_list_v1());
724 builder = setup_coin_deny_list_state_create(builder);
725 }
726 EndOfEpochTransactionKind::BridgeStateCreate(chain_id) => {
727 assert!(protocol_config.enable_bridge());
728 builder = setup_bridge_create(builder, chain_id)
729 }
730 EndOfEpochTransactionKind::BridgeCommitteeInit(bridge_shared_version) => {
731 assert!(protocol_config.enable_bridge());
732 assert!(protocol_config.should_try_to_finalize_bridge_committee());
733 builder = setup_bridge_committee_update(builder, bridge_shared_version)
734 }
735 EndOfEpochTransactionKind::StoreExecutionTimeObservations(estimates) => {
736 if let PerObjectCongestionControlMode::ExecutionTimeEstimate(params) =
737 protocol_config.per_object_congestion_control_mode()
738 {
739 if let Some(chunk_size) = params.observations_chunk_size {
740 builder = setup_store_execution_time_estimates_v2(
741 builder,
742 estimates,
743 chunk_size as usize,
744 );
745 } else {
746 builder =
747 setup_store_execution_time_estimates(builder, estimates);
748 }
749 }
750 }
751 EndOfEpochTransactionKind::AccumulatorRootCreate => {
752 assert!(protocol_config.create_root_accumulator_object());
753 builder = setup_accumulator_root_create(builder);
754 }
755 EndOfEpochTransactionKind::WriteAccumulatorStorageCost(
756 write_storage_cost,
757 ) => {
758 assert!(protocol_config.enable_accumulators());
759 builder =
760 setup_write_accumulator_storage_cost(builder, &write_storage_cost);
761 }
762 EndOfEpochTransactionKind::CoinRegistryCreate => {
763 assert!(protocol_config.enable_coin_registry());
764 builder = setup_coin_registry_create(builder);
765 }
766 EndOfEpochTransactionKind::DisplayRegistryCreate => {
767 assert!(protocol_config.enable_display_registry());
768 builder = setup_display_registry_create(builder);
769 }
770 EndOfEpochTransactionKind::AddressAliasStateCreate => {
771 assert!(protocol_config.address_aliases());
772 builder = setup_address_alias_state_create(builder);
773 }
774 }
775 }
776 unreachable!(
777 "EndOfEpochTransactionKind::ChangeEpoch should be the last transaction in the list"
778 )
779 }
780 TransactionKind::AuthenticatorStateUpdate(auth_state_update) => {
781 setup_authenticator_state_update(
782 auth_state_update,
783 temporary_store,
784 store,
785 tx_ctx,
786 move_vm,
787 gas_charger,
788 protocol_config,
789 metrics,
790 trace_builder_opt,
791 )
792 .map_err(|e| (e, vec![]))?;
793 Ok((Mode::empty_results(), vec![]))
794 }
795 TransactionKind::RandomnessStateUpdate(randomness_state_update) => {
796 setup_randomness_state_update(
797 randomness_state_update,
798 temporary_store,
799 store,
800 tx_ctx,
801 move_vm,
802 gas_charger,
803 protocol_config,
804 metrics,
805 trace_builder_opt,
806 )
807 .map_err(|e| (e, vec![]))?;
808 Ok((Mode::empty_results(), vec![]))
809 }
810 }?;
811 temporary_store
812 .check_execution_results_consistency()
813 .map_err(|e| (e, vec![]))?;
814 Ok(result)
815 }
816
817 fn mint_epoch_rewards_in_pt(
818 builder: &mut ProgrammableTransactionBuilder,
819 params: &AdvanceEpochParams,
820 ) -> (Argument, Argument) {
821 let storage_charge_arg = builder
823 .input(CallArg::Pure(
824 bcs::to_bytes(¶ms.storage_charge).unwrap(),
825 ))
826 .unwrap();
827 let storage_rewards = builder.programmable_move_call(
828 SUI_FRAMEWORK_PACKAGE_ID,
829 BALANCE_MODULE_NAME.to_owned(),
830 BALANCE_CREATE_REWARDS_FUNCTION_NAME.to_owned(),
831 vec![GAS::type_tag()],
832 vec![storage_charge_arg],
833 );
834
835 let computation_charge_arg = builder
837 .input(CallArg::Pure(
838 bcs::to_bytes(¶ms.computation_charge).unwrap(),
839 ))
840 .unwrap();
841 let computation_rewards = builder.programmable_move_call(
842 SUI_FRAMEWORK_PACKAGE_ID,
843 BALANCE_MODULE_NAME.to_owned(),
844 BALANCE_CREATE_REWARDS_FUNCTION_NAME.to_owned(),
845 vec![GAS::type_tag()],
846 vec![computation_charge_arg],
847 );
848 (storage_rewards, computation_rewards)
849 }
850
851 pub fn construct_advance_epoch_pt(
852 mut builder: ProgrammableTransactionBuilder,
853 params: &AdvanceEpochParams,
854 ) -> Result<ProgrammableTransaction, ExecutionError> {
855 let (storage_rewards, computation_rewards) = mint_epoch_rewards_in_pt(&mut builder, params);
857
858 let mut arguments = vec![storage_rewards, computation_rewards];
860 let call_arg_arguments = vec![
861 CallArg::SUI_SYSTEM_MUT,
862 CallArg::Pure(bcs::to_bytes(¶ms.epoch).unwrap()),
863 CallArg::Pure(bcs::to_bytes(¶ms.next_protocol_version.as_u64()).unwrap()),
864 CallArg::Pure(bcs::to_bytes(¶ms.storage_rebate).unwrap()),
865 CallArg::Pure(bcs::to_bytes(¶ms.non_refundable_storage_fee).unwrap()),
866 CallArg::Pure(bcs::to_bytes(¶ms.storage_fund_reinvest_rate).unwrap()),
867 CallArg::Pure(bcs::to_bytes(¶ms.reward_slashing_rate).unwrap()),
868 CallArg::Pure(bcs::to_bytes(¶ms.epoch_start_timestamp_ms).unwrap()),
869 ]
870 .into_iter()
871 .map(|a| builder.input(a))
872 .collect::<Result<_, _>>();
873
874 assert_invariant!(
875 call_arg_arguments.is_ok(),
876 "Unable to generate args for advance_epoch transaction!"
877 );
878
879 arguments.append(&mut call_arg_arguments.unwrap());
880
881 info!("Call arguments to advance_epoch transaction: {:?}", params);
882
883 let storage_rebates = builder.programmable_move_call(
884 SUI_SYSTEM_PACKAGE_ID,
885 SUI_SYSTEM_MODULE_NAME.to_owned(),
886 ADVANCE_EPOCH_FUNCTION_NAME.to_owned(),
887 vec![],
888 arguments,
889 );
890
891 builder.programmable_move_call(
893 SUI_FRAMEWORK_PACKAGE_ID,
894 BALANCE_MODULE_NAME.to_owned(),
895 BALANCE_DESTROY_REBATES_FUNCTION_NAME.to_owned(),
896 vec![GAS::type_tag()],
897 vec![storage_rebates],
898 );
899 Ok(builder.finish())
900 }
901
902 pub fn construct_advance_epoch_safe_mode_pt(
903 params: &AdvanceEpochParams,
904 protocol_config: &ProtocolConfig,
905 ) -> Result<ProgrammableTransaction, ExecutionError> {
906 let mut builder = ProgrammableTransactionBuilder::new();
907 let (storage_rewards, computation_rewards) = mint_epoch_rewards_in_pt(&mut builder, params);
909
910 let mut arguments = vec![storage_rewards, computation_rewards];
912
913 let mut args = vec![
914 CallArg::SUI_SYSTEM_MUT,
915 CallArg::Pure(bcs::to_bytes(¶ms.epoch).unwrap()),
916 CallArg::Pure(bcs::to_bytes(¶ms.next_protocol_version.as_u64()).unwrap()),
917 CallArg::Pure(bcs::to_bytes(¶ms.storage_rebate).unwrap()),
918 CallArg::Pure(bcs::to_bytes(¶ms.non_refundable_storage_fee).unwrap()),
919 ];
920
921 if protocol_config.get_advance_epoch_start_time_in_safe_mode() {
922 args.push(CallArg::Pure(
923 bcs::to_bytes(¶ms.epoch_start_timestamp_ms).unwrap(),
924 ));
925 }
926
927 let call_arg_arguments = args
928 .into_iter()
929 .map(|a| builder.input(a))
930 .collect::<Result<_, _>>();
931
932 assert_invariant!(
933 call_arg_arguments.is_ok(),
934 "Unable to generate args for advance_epoch transaction!"
935 );
936
937 arguments.append(&mut call_arg_arguments.unwrap());
938
939 info!("Call arguments to advance_epoch transaction: {:?}", params);
940
941 builder.programmable_move_call(
942 SUI_SYSTEM_PACKAGE_ID,
943 SUI_SYSTEM_MODULE_NAME.to_owned(),
944 ADVANCE_EPOCH_SAFE_MODE_FUNCTION_NAME.to_owned(),
945 vec![],
946 arguments,
947 );
948
949 Ok(builder.finish())
950 }
951
952 fn advance_epoch(
953 builder: ProgrammableTransactionBuilder,
954 change_epoch: ChangeEpoch,
955 temporary_store: &mut TemporaryStore<'_>,
956 store: &dyn BackingStore,
957 tx_ctx: Rc<RefCell<TxContext>>,
958 move_vm: &Arc<MoveVM>,
959 gas_charger: &mut GasCharger,
960 protocol_config: &ProtocolConfig,
961 metrics: Arc<ExecutionMetrics>,
962 trace_builder_opt: &mut Option<MoveTraceBuilder>,
963 ) -> Result<(), ExecutionError> {
964 let params = AdvanceEpochParams {
965 epoch: change_epoch.epoch,
966 next_protocol_version: change_epoch.protocol_version,
967 storage_charge: change_epoch.storage_charge,
968 computation_charge: change_epoch.computation_charge,
969 storage_rebate: change_epoch.storage_rebate,
970 non_refundable_storage_fee: change_epoch.non_refundable_storage_fee,
971 storage_fund_reinvest_rate: protocol_config.storage_fund_reinvest_rate(),
972 reward_slashing_rate: protocol_config.reward_slashing_rate(),
973 epoch_start_timestamp_ms: change_epoch.epoch_start_timestamp_ms,
974 };
975 let advance_epoch_pt = construct_advance_epoch_pt(builder, ¶ms)?;
976 let result = programmable_transactions::execution::execute::<execution_mode::System>(
977 protocol_config,
978 metrics.clone(),
979 move_vm,
980 temporary_store,
981 store.as_backing_package_store(),
982 tx_ctx.clone(),
983 gas_charger,
984 None,
985 advance_epoch_pt,
986 trace_builder_opt,
987 );
988
989 #[cfg(msim)]
990 let result = maybe_modify_result(result, change_epoch.epoch);
991
992 if let Err(err) = &result {
993 tracing::error!(
994 "Failed to execute advance epoch transaction. Switching to safe mode. Error: {:?}. Input objects: {:?}. Tx data: {:?}",
995 err.0,
996 temporary_store.objects(),
997 change_epoch,
998 );
999 temporary_store.drop_writes();
1000 gas_charger.reset_storage_cost_and_rebate();
1002
1003 if protocol_config.get_advance_epoch_start_time_in_safe_mode() {
1004 temporary_store.advance_epoch_safe_mode(¶ms, protocol_config);
1005 } else {
1006 let advance_epoch_safe_mode_pt =
1007 construct_advance_epoch_safe_mode_pt(¶ms, protocol_config)?;
1008 programmable_transactions::execution::execute::<execution_mode::System>(
1009 protocol_config,
1010 metrics.clone(),
1011 move_vm,
1012 temporary_store,
1013 store.as_backing_package_store(),
1014 tx_ctx.clone(),
1015 gas_charger,
1016 None,
1017 advance_epoch_safe_mode_pt,
1018 trace_builder_opt,
1019 )
1020 .map_err(|(e, _)| e)
1021 .expect("Advance epoch with safe mode must succeed");
1022 }
1023 }
1024
1025 if protocol_config.fresh_vm_on_framework_upgrade() {
1026 let new_vm = new_move_vm(
1027 all_natives(true, protocol_config),
1028 protocol_config,
1029 )
1030 .expect("Failed to create new MoveVM");
1031 process_system_packages(
1032 change_epoch,
1033 temporary_store,
1034 store,
1035 tx_ctx,
1036 &new_vm,
1037 gas_charger,
1038 protocol_config,
1039 metrics,
1040 trace_builder_opt,
1041 );
1042 } else {
1043 process_system_packages(
1044 change_epoch,
1045 temporary_store,
1046 store,
1047 tx_ctx,
1048 move_vm,
1049 gas_charger,
1050 protocol_config,
1051 metrics,
1052 trace_builder_opt,
1053 );
1054 }
1055 Ok(())
1056 }
1057
1058 fn process_system_packages(
1059 change_epoch: ChangeEpoch,
1060 temporary_store: &mut TemporaryStore<'_>,
1061 store: &dyn BackingStore,
1062 tx_ctx: Rc<RefCell<TxContext>>,
1063 move_vm: &MoveVM,
1064 gas_charger: &mut GasCharger,
1065 protocol_config: &ProtocolConfig,
1066 metrics: Arc<ExecutionMetrics>,
1067 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1068 ) {
1069 let digest = tx_ctx.borrow().digest();
1070 let binary_config = protocol_config.binary_config(None);
1071 for (version, modules, dependencies) in change_epoch.system_packages.into_iter() {
1072 let deserialized_modules: Vec<_> = modules
1073 .iter()
1074 .map(|m| CompiledModule::deserialize_with_config(m, &binary_config).unwrap())
1075 .collect();
1076
1077 if version == OBJECT_START_VERSION {
1078 let package_id = deserialized_modules.first().unwrap().address();
1079 info!("adding new system package {package_id}");
1080
1081 let publish_pt = {
1082 let mut b = ProgrammableTransactionBuilder::new();
1083 b.command(Command::Publish(modules, dependencies));
1084 b.finish()
1085 };
1086
1087 programmable_transactions::execution::execute::<execution_mode::System>(
1088 protocol_config,
1089 metrics.clone(),
1090 move_vm,
1091 temporary_store,
1092 store.as_backing_package_store(),
1093 tx_ctx.clone(),
1094 gas_charger,
1095 None,
1096 publish_pt,
1097 trace_builder_opt,
1098 )
1099 .map_err(|(e, _)| e)
1100 .expect("System Package Publish must succeed");
1101 } else {
1102 let mut new_package = Object::new_system_package(
1103 &deserialized_modules,
1104 version,
1105 dependencies,
1106 digest,
1107 );
1108
1109 info!(
1110 "upgraded system package {:?}",
1111 new_package.compute_object_reference()
1112 );
1113
1114 new_package
1117 .data
1118 .try_as_package_mut()
1119 .unwrap()
1120 .decrement_version();
1121
1122 temporary_store.upgrade_system_package(new_package);
1124 }
1125 }
1126 }
1127
1128 fn setup_consensus_commit(
1133 consensus_commit_timestamp_ms: CheckpointTimestamp,
1134 temporary_store: &mut TemporaryStore<'_>,
1135 store: &dyn BackingStore,
1136 tx_ctx: Rc<RefCell<TxContext>>,
1137 move_vm: &Arc<MoveVM>,
1138 gas_charger: &mut GasCharger,
1139 protocol_config: &ProtocolConfig,
1140 metrics: Arc<ExecutionMetrics>,
1141 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1142 ) -> Result<(), ExecutionError> {
1143 let pt = {
1144 let mut builder = ProgrammableTransactionBuilder::new();
1145 let res = builder.move_call(
1146 SUI_FRAMEWORK_ADDRESS.into(),
1147 CLOCK_MODULE_NAME.to_owned(),
1148 CONSENSUS_COMMIT_PROLOGUE_FUNCTION_NAME.to_owned(),
1149 vec![],
1150 vec![
1151 CallArg::CLOCK_MUT,
1152 CallArg::Pure(bcs::to_bytes(&consensus_commit_timestamp_ms).unwrap()),
1153 ],
1154 );
1155 assert_invariant!(
1156 res.is_ok(),
1157 "Unable to generate consensus_commit_prologue transaction!"
1158 );
1159 builder.finish()
1160 };
1161 programmable_transactions::execution::execute::<execution_mode::System>(
1162 protocol_config,
1163 metrics,
1164 move_vm,
1165 temporary_store,
1166 store.as_backing_package_store(),
1167 tx_ctx,
1168 gas_charger,
1169 None,
1170 pt,
1171 trace_builder_opt,
1172 )
1173 .map_err(|(e, _)| e)?;
1174 Ok(())
1175 }
1176
1177 fn setup_authenticator_state_create(
1178 mut builder: ProgrammableTransactionBuilder,
1179 ) -> ProgrammableTransactionBuilder {
1180 builder
1181 .move_call(
1182 SUI_FRAMEWORK_ADDRESS.into(),
1183 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1184 AUTHENTICATOR_STATE_CREATE_FUNCTION_NAME.to_owned(),
1185 vec![],
1186 vec![],
1187 )
1188 .expect("Unable to generate authenticator_state_create transaction!");
1189 builder
1190 }
1191
1192 fn setup_randomness_state_create(
1193 mut builder: ProgrammableTransactionBuilder,
1194 ) -> ProgrammableTransactionBuilder {
1195 builder
1196 .move_call(
1197 SUI_FRAMEWORK_ADDRESS.into(),
1198 RANDOMNESS_MODULE_NAME.to_owned(),
1199 RANDOMNESS_STATE_CREATE_FUNCTION_NAME.to_owned(),
1200 vec![],
1201 vec![],
1202 )
1203 .expect("Unable to generate randomness_state_create transaction!");
1204 builder
1205 }
1206
1207 fn setup_bridge_create(
1208 mut builder: ProgrammableTransactionBuilder,
1209 chain_id: ChainIdentifier,
1210 ) -> ProgrammableTransactionBuilder {
1211 let bridge_uid = builder
1212 .input(CallArg::Pure(UID::new(SUI_BRIDGE_OBJECT_ID).to_bcs_bytes()))
1213 .expect("Unable to create Bridge object UID!");
1214
1215 let bridge_chain_id = if chain_id == get_mainnet_chain_identifier() {
1216 BridgeChainId::SuiMainnet as u8
1217 } else if chain_id == get_testnet_chain_identifier() {
1218 BridgeChainId::SuiTestnet as u8
1219 } else {
1220 BridgeChainId::SuiCustom as u8
1222 };
1223
1224 let bridge_chain_id = builder.pure(bridge_chain_id).unwrap();
1225 builder.programmable_move_call(
1226 BRIDGE_ADDRESS.into(),
1227 BRIDGE_MODULE_NAME.to_owned(),
1228 BRIDGE_CREATE_FUNCTION_NAME.to_owned(),
1229 vec![],
1230 vec![bridge_uid, bridge_chain_id],
1231 );
1232 builder
1233 }
1234
1235 fn setup_bridge_committee_update(
1236 mut builder: ProgrammableTransactionBuilder,
1237 bridge_shared_version: SequenceNumber,
1238 ) -> ProgrammableTransactionBuilder {
1239 let bridge = builder
1240 .obj(ObjectArg::SharedObject {
1241 id: SUI_BRIDGE_OBJECT_ID,
1242 initial_shared_version: bridge_shared_version,
1243 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1244 })
1245 .expect("Unable to create Bridge object arg!");
1246 let system_state = builder
1247 .obj(ObjectArg::SUI_SYSTEM_MUT)
1248 .expect("Unable to create System State object arg!");
1249
1250 let voting_power = builder.programmable_move_call(
1251 SUI_SYSTEM_PACKAGE_ID,
1252 SUI_SYSTEM_MODULE_NAME.to_owned(),
1253 ident_str!("validator_voting_powers").to_owned(),
1254 vec![],
1255 vec![system_state],
1256 );
1257
1258 let min_stake_participation_percentage = builder
1261 .input(CallArg::Pure(
1262 bcs::to_bytes(&BRIDGE_COMMITTEE_MINIMAL_VOTING_POWER).unwrap(),
1263 ))
1264 .unwrap();
1265
1266 builder.programmable_move_call(
1267 BRIDGE_ADDRESS.into(),
1268 BRIDGE_MODULE_NAME.to_owned(),
1269 BRIDGE_INIT_COMMITTEE_FUNCTION_NAME.to_owned(),
1270 vec![],
1271 vec![bridge, voting_power, min_stake_participation_percentage],
1272 );
1273 builder
1274 }
1275
1276 fn setup_authenticator_state_update(
1277 update: AuthenticatorStateUpdate,
1278 temporary_store: &mut TemporaryStore<'_>,
1279 store: &dyn BackingStore,
1280 tx_ctx: Rc<RefCell<TxContext>>,
1281 move_vm: &Arc<MoveVM>,
1282 gas_charger: &mut GasCharger,
1283 protocol_config: &ProtocolConfig,
1284 metrics: Arc<ExecutionMetrics>,
1285 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1286 ) -> Result<(), ExecutionError> {
1287 let pt = {
1288 let mut builder = ProgrammableTransactionBuilder::new();
1289 let res = builder.move_call(
1290 SUI_FRAMEWORK_ADDRESS.into(),
1291 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1292 AUTHENTICATOR_STATE_UPDATE_FUNCTION_NAME.to_owned(),
1293 vec![],
1294 vec![
1295 CallArg::Object(ObjectArg::SharedObject {
1296 id: SUI_AUTHENTICATOR_STATE_OBJECT_ID,
1297 initial_shared_version: update.authenticator_obj_initial_shared_version,
1298 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1299 }),
1300 CallArg::Pure(bcs::to_bytes(&update.new_active_jwks).unwrap()),
1301 ],
1302 );
1303 assert_invariant!(
1304 res.is_ok(),
1305 "Unable to generate authenticator_state_update transaction!"
1306 );
1307 builder.finish()
1308 };
1309 programmable_transactions::execution::execute::<execution_mode::System>(
1310 protocol_config,
1311 metrics,
1312 move_vm,
1313 temporary_store,
1314 store.as_backing_package_store(),
1315 tx_ctx,
1316 gas_charger,
1317 None,
1318 pt,
1319 trace_builder_opt,
1320 )
1321 .map_err(|(e, _)| e)?;
1322 Ok(())
1323 }
1324
1325 fn setup_authenticator_state_expire(
1326 mut builder: ProgrammableTransactionBuilder,
1327 expire: AuthenticatorStateExpire,
1328 ) -> ProgrammableTransactionBuilder {
1329 builder
1330 .move_call(
1331 SUI_FRAMEWORK_ADDRESS.into(),
1332 AUTHENTICATOR_STATE_MODULE_NAME.to_owned(),
1333 AUTHENTICATOR_STATE_EXPIRE_JWKS_FUNCTION_NAME.to_owned(),
1334 vec![],
1335 vec![
1336 CallArg::Object(ObjectArg::SharedObject {
1337 id: SUI_AUTHENTICATOR_STATE_OBJECT_ID,
1338 initial_shared_version: expire.authenticator_obj_initial_shared_version,
1339 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1340 }),
1341 CallArg::Pure(bcs::to_bytes(&expire.min_epoch).unwrap()),
1342 ],
1343 )
1344 .expect("Unable to generate authenticator_state_expire transaction!");
1345 builder
1346 }
1347
1348 fn setup_randomness_state_update(
1349 update: RandomnessStateUpdate,
1350 temporary_store: &mut TemporaryStore<'_>,
1351 store: &dyn BackingStore,
1352 tx_ctx: Rc<RefCell<TxContext>>,
1353 move_vm: &Arc<MoveVM>,
1354 gas_charger: &mut GasCharger,
1355 protocol_config: &ProtocolConfig,
1356 metrics: Arc<ExecutionMetrics>,
1357 trace_builder_opt: &mut Option<MoveTraceBuilder>,
1358 ) -> Result<(), ExecutionError> {
1359 let pt = {
1360 let mut builder = ProgrammableTransactionBuilder::new();
1361 let res = builder.move_call(
1362 SUI_FRAMEWORK_ADDRESS.into(),
1363 RANDOMNESS_MODULE_NAME.to_owned(),
1364 RANDOMNESS_STATE_UPDATE_FUNCTION_NAME.to_owned(),
1365 vec![],
1366 vec![
1367 CallArg::Object(ObjectArg::SharedObject {
1368 id: SUI_RANDOMNESS_STATE_OBJECT_ID,
1369 initial_shared_version: update.randomness_obj_initial_shared_version,
1370 mutability: sui_types::transaction::SharedObjectMutability::Mutable,
1371 }),
1372 CallArg::Pure(bcs::to_bytes(&update.randomness_round).unwrap()),
1373 CallArg::Pure(bcs::to_bytes(&update.random_bytes).unwrap()),
1374 ],
1375 );
1376 assert_invariant!(
1377 res.is_ok(),
1378 "Unable to generate randomness_state_update transaction!"
1379 );
1380 builder.finish()
1381 };
1382 programmable_transactions::execution::execute::<execution_mode::System>(
1383 protocol_config,
1384 metrics,
1385 move_vm,
1386 temporary_store,
1387 store.as_backing_package_store(),
1388 tx_ctx,
1389 gas_charger,
1390 None,
1391 pt,
1392 trace_builder_opt,
1393 )
1394 .map_err(|(e, _)| e)?;
1395 Ok(())
1396 }
1397
1398 fn setup_coin_deny_list_state_create(
1399 mut builder: ProgrammableTransactionBuilder,
1400 ) -> ProgrammableTransactionBuilder {
1401 builder
1402 .move_call(
1403 SUI_FRAMEWORK_ADDRESS.into(),
1404 DENY_LIST_MODULE.to_owned(),
1405 DENY_LIST_CREATE_FUNC.to_owned(),
1406 vec![],
1407 vec![],
1408 )
1409 .expect("Unable to generate coin_deny_list_create transaction!");
1410 builder
1411 }
1412
1413 fn setup_store_execution_time_estimates(
1414 mut builder: ProgrammableTransactionBuilder,
1415 estimates: StoredExecutionTimeObservations,
1416 ) -> ProgrammableTransactionBuilder {
1417 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1418 let estimates_bytes = bcs::to_bytes(&estimates).unwrap();
1421 let estimates_arg = builder.pure(estimates_bytes).unwrap();
1422 builder.programmable_move_call(
1423 SUI_SYSTEM_PACKAGE_ID,
1424 SUI_SYSTEM_MODULE_NAME.to_owned(),
1425 ident_str!("store_execution_time_estimates").to_owned(),
1426 vec![],
1427 vec![system_state, estimates_arg],
1428 );
1429 builder
1430 }
1431
1432 fn setup_store_execution_time_estimates_v2(
1433 mut builder: ProgrammableTransactionBuilder,
1434 estimates: StoredExecutionTimeObservations,
1435 chunk_size: usize,
1436 ) -> ProgrammableTransactionBuilder {
1437 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1438
1439 let estimate_chunks = estimates.chunk_observations(chunk_size);
1440
1441 let chunk_bytes: Vec<Vec<u8>> = estimate_chunks
1442 .into_iter()
1443 .map(|chunk| bcs::to_bytes(&chunk).unwrap())
1444 .collect();
1445
1446 let chunks_arg = builder.pure(chunk_bytes).unwrap();
1447
1448 builder.programmable_move_call(
1449 SUI_SYSTEM_PACKAGE_ID,
1450 SUI_SYSTEM_MODULE_NAME.to_owned(),
1451 ident_str!("store_execution_time_estimates_v2").to_owned(),
1452 vec![],
1453 vec![system_state, chunks_arg],
1454 );
1455 builder
1456 }
1457
1458 fn setup_accumulator_root_create(
1459 mut builder: ProgrammableTransactionBuilder,
1460 ) -> ProgrammableTransactionBuilder {
1461 builder
1462 .move_call(
1463 SUI_FRAMEWORK_ADDRESS.into(),
1464 ACCUMULATOR_ROOT_MODULE.to_owned(),
1465 ACCUMULATOR_ROOT_CREATE_FUNC.to_owned(),
1466 vec![],
1467 vec![],
1468 )
1469 .expect("Unable to generate accumulator_root_create transaction!");
1470 builder
1471 }
1472
1473 fn setup_write_accumulator_storage_cost(
1474 mut builder: ProgrammableTransactionBuilder,
1475 write_storage_cost: &WriteAccumulatorStorageCost,
1476 ) -> ProgrammableTransactionBuilder {
1477 let system_state = builder.obj(ObjectArg::SUI_SYSTEM_MUT).unwrap();
1478 let storage_cost_arg = builder.pure(write_storage_cost.storage_cost).unwrap();
1479 builder.programmable_move_call(
1480 SUI_SYSTEM_PACKAGE_ID,
1481 SUI_SYSTEM_MODULE_NAME.to_owned(),
1482 ident_str!("write_accumulator_storage_cost").to_owned(),
1483 vec![],
1484 vec![system_state, storage_cost_arg],
1485 );
1486 builder
1487 }
1488
1489 fn setup_coin_registry_create(
1490 mut builder: ProgrammableTransactionBuilder,
1491 ) -> ProgrammableTransactionBuilder {
1492 builder
1493 .move_call(
1494 SUI_FRAMEWORK_ADDRESS.into(),
1495 ident_str!("coin_registry").to_owned(),
1496 ident_str!("create").to_owned(),
1497 vec![],
1498 vec![],
1499 )
1500 .expect("Unable to generate coin_registry_create transaction!");
1501 builder
1502 }
1503
1504 fn setup_display_registry_create(
1505 mut builder: ProgrammableTransactionBuilder,
1506 ) -> ProgrammableTransactionBuilder {
1507 builder
1508 .move_call(
1509 SUI_FRAMEWORK_ADDRESS.into(),
1510 ident_str!("display_registry").to_owned(),
1511 ident_str!("create").to_owned(),
1512 vec![],
1513 vec![],
1514 )
1515 .expect("Unable to generate display_registry_create transaction!");
1516 builder
1517 }
1518
1519 fn setup_address_alias_state_create(
1520 mut builder: ProgrammableTransactionBuilder,
1521 ) -> ProgrammableTransactionBuilder {
1522 builder
1523 .move_call(
1524 SUI_FRAMEWORK_ADDRESS.into(),
1525 ident_str!("address_alias").to_owned(),
1526 ident_str!("create").to_owned(),
1527 vec![],
1528 vec![],
1529 )
1530 .expect("Unable to generate address_alias_state_create transaction!");
1531 builder
1532 }
1533}