iota_execution/
latest.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::{collections::HashSet, path::PathBuf, sync::Arc};
6
7use iota_adapter_latest::{
8    adapter::{new_move_vm, run_metered_move_bytecode_verifier},
9    execution_engine::{execute_genesis_state_update, execute_transaction_to_effects},
10    execution_mode,
11    type_layout_resolver::TypeLayoutResolver,
12};
13use iota_move_natives_latest::all_natives;
14use iota_protocol_config::ProtocolConfig;
15use iota_types::{
16    base_types::{IotaAddress, ObjectRef, TxContext},
17    committee::EpochId,
18    digests::TransactionDigest,
19    effects::TransactionEffects,
20    error::{ExecutionError, IotaError, IotaResult},
21    execution::{ExecutionResult, TypeLayoutStore},
22    gas::IotaGasStatus,
23    inner_temporary_store::InnerTemporaryStore,
24    layout_resolver::LayoutResolver,
25    metrics::{BytecodeVerifierMetrics, LimitsMetrics},
26    storage::BackingStore,
27    transaction::{CheckedInputObjects, ProgrammableTransaction, TransactionKind},
28};
29use iota_verifier_latest::meter::IotaVerifierMeter;
30use move_binary_format::CompiledModule;
31use move_bytecode_verifier_meter::Meter;
32use move_trace_format::format::MoveTraceBuilder;
33use move_vm_config::verifier::{MeterConfig, VerifierConfig};
34use move_vm_runtime_latest::move_vm::MoveVM;
35
36use crate::{executor, verifier};
37
38pub(crate) struct Executor(Arc<MoveVM>);
39
40pub(crate) struct Verifier<'m> {
41    config: VerifierConfig,
42    metrics: &'m Arc<BytecodeVerifierMetrics>,
43}
44
45impl Executor {
46    pub(crate) fn new(
47        protocol_config: &ProtocolConfig,
48        silent: bool,
49        enable_profiler: Option<PathBuf>,
50    ) -> Result<Self, IotaError> {
51        Ok(Executor(Arc::new(new_move_vm(
52            all_natives(silent, protocol_config),
53            protocol_config,
54            enable_profiler,
55        )?)))
56    }
57}
58
59impl<'m> Verifier<'m> {
60    pub(crate) fn new(config: VerifierConfig, metrics: &'m Arc<BytecodeVerifierMetrics>) -> Self {
61        Verifier { config, metrics }
62    }
63}
64
65impl executor::Executor for Executor {
66    fn execute_transaction_to_effects(
67        &self,
68        store: &dyn BackingStore,
69        protocol_config: &ProtocolConfig,
70        metrics: Arc<LimitsMetrics>,
71        enable_expensive_checks: bool,
72        certificate_deny_set: &HashSet<TransactionDigest>,
73        epoch_id: &EpochId,
74        epoch_timestamp_ms: u64,
75        input_objects: CheckedInputObjects,
76        gas_coins: Vec<ObjectRef>,
77        gas_status: IotaGasStatus,
78        transaction_kind: TransactionKind,
79        transaction_signer: IotaAddress,
80        transaction_digest: TransactionDigest,
81        trace_builder_opt: &mut Option<MoveTraceBuilder>,
82    ) -> (
83        InnerTemporaryStore,
84        IotaGasStatus,
85        TransactionEffects,
86        Result<(), ExecutionError>,
87    ) {
88        execute_transaction_to_effects::<execution_mode::Normal>(
89            store,
90            input_objects,
91            gas_coins,
92            gas_status,
93            transaction_kind,
94            transaction_signer,
95            transaction_digest,
96            &self.0,
97            epoch_id,
98            epoch_timestamp_ms,
99            protocol_config,
100            metrics,
101            enable_expensive_checks,
102            certificate_deny_set,
103            trace_builder_opt,
104        )
105    }
106
107    fn dev_inspect_transaction(
108        &self,
109        store: &dyn BackingStore,
110        protocol_config: &ProtocolConfig,
111        metrics: Arc<LimitsMetrics>,
112        enable_expensive_checks: bool,
113        certificate_deny_set: &HashSet<TransactionDigest>,
114        epoch_id: &EpochId,
115        epoch_timestamp_ms: u64,
116        input_objects: CheckedInputObjects,
117        gas_coins: Vec<ObjectRef>,
118        gas_status: IotaGasStatus,
119        transaction_kind: TransactionKind,
120        transaction_signer: IotaAddress,
121        transaction_digest: TransactionDigest,
122        skip_all_checks: bool,
123    ) -> (
124        InnerTemporaryStore,
125        IotaGasStatus,
126        TransactionEffects,
127        Result<Vec<ExecutionResult>, ExecutionError>,
128    ) {
129        if skip_all_checks {
130            execute_transaction_to_effects::<execution_mode::DevInspect<true>>(
131                store,
132                input_objects,
133                gas_coins,
134                gas_status,
135                transaction_kind,
136                transaction_signer,
137                transaction_digest,
138                &self.0,
139                epoch_id,
140                epoch_timestamp_ms,
141                protocol_config,
142                metrics,
143                enable_expensive_checks,
144                certificate_deny_set,
145                &mut None,
146            )
147        } else {
148            execute_transaction_to_effects::<execution_mode::DevInspect<false>>(
149                store,
150                input_objects,
151                gas_coins,
152                gas_status,
153                transaction_kind,
154                transaction_signer,
155                transaction_digest,
156                &self.0,
157                epoch_id,
158                epoch_timestamp_ms,
159                protocol_config,
160                metrics,
161                enable_expensive_checks,
162                certificate_deny_set,
163                &mut None,
164            )
165        }
166    }
167
168    fn update_genesis_state(
169        &self,
170        store: &dyn BackingStore,
171        protocol_config: &ProtocolConfig,
172        metrics: Arc<LimitsMetrics>,
173        tx_context: &mut TxContext,
174        input_objects: CheckedInputObjects,
175        pt: ProgrammableTransaction,
176    ) -> Result<InnerTemporaryStore, ExecutionError> {
177        execute_genesis_state_update(
178            store,
179            protocol_config,
180            metrics,
181            &self.0,
182            tx_context,
183            input_objects,
184            pt,
185        )
186    }
187
188    fn type_layout_resolver<'r, 'vm: 'r, 'store: 'r>(
189        &'vm self,
190        store: Box<dyn TypeLayoutStore + 'store>,
191    ) -> Box<dyn LayoutResolver + 'r> {
192        Box::new(TypeLayoutResolver::new(&self.0, store))
193    }
194}
195
196impl verifier::Verifier for Verifier<'_> {
197    fn meter(&self, config: MeterConfig) -> Box<dyn Meter> {
198        Box::new(IotaVerifierMeter::new(config))
199    }
200
201    fn meter_compiled_modules(
202        &mut self,
203        _protocol_config: &ProtocolConfig,
204        modules: &[CompiledModule],
205        meter: &mut dyn Meter,
206    ) -> IotaResult<()> {
207        run_metered_move_bytecode_verifier(modules, &self.config, meter, self.metrics)
208    }
209}