1use 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}