Skip to main content

iota_types/
transaction_executor.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::BTreeMap, time::Duration};
6
7use iota_sdk_types::ObjectId;
8
9use crate::{
10    digests::TransactionDigest,
11    effects::{TransactionEffects, TransactionEvents},
12    error::{ExecutionError, IotaError},
13    execution::ExecutionResult,
14    messages_checkpoint::CheckpointSequenceNumber,
15    object::Object,
16    quorum_driver_types::{
17        ExecuteTransactionRequestV1, ExecuteTransactionResponseV1, QuorumDriverError,
18    },
19    transaction::TransactionData,
20};
21
22/// Trait to define the interface for how the REST service interacts with a
23/// QuorumDriver or a simulated transaction executor.
24#[async_trait::async_trait]
25pub trait TransactionExecutor: Send + Sync {
26    async fn execute_transaction(
27        &self,
28        request: ExecuteTransactionRequestV1,
29        skip_certification: bool,
30        client_addr: Option<std::net::SocketAddr>,
31    ) -> Result<ExecuteTransactionResponseV1, QuorumDriverError>;
32
33    fn simulate_transaction(
34        &self,
35        transaction: TransactionData,
36        checks: VmChecks,
37    ) -> Result<SimulateTransactionResult, IotaError>;
38
39    /// Wait for the given transactions to be included in a checkpoint.
40    ///
41    /// Returns a mapping from transaction digest to
42    /// `(checkpoint_sequence_number, checkpoint_timestamp_ms)`.
43    /// On timeout, returns partial results for any transactions that were
44    /// already checkpointed.
45    async fn wait_for_checkpoint_inclusion(
46        &self,
47        digests: &[TransactionDigest],
48        timeout: Duration,
49    ) -> Result<BTreeMap<TransactionDigest, (CheckpointSequenceNumber, u64)>, IotaError>;
50
51    /// Read authoritative effects, events, and input/output objects for a
52    /// locally-executed transaction from the cache. Used by callers that
53    /// have already waited for checkpoint inclusion and want to discard any
54    /// uncertified single-validator copies.
55    ///
56    /// Returns `Ok(None)` if the tx is not in the cache, or if the executor
57    /// does not maintain a local cache (e.g. simulacrum).
58    fn read_transaction_from_cache(
59        &self,
60        digest: &TransactionDigest,
61        include_events: bool,
62        include_input_objects: bool,
63        include_output_objects: bool,
64    ) -> Result<Option<CachedTransactionData>, IotaError> {
65        // Default: no cache — safe fallback for executors like simulacrum.
66        let _ = (
67            digest,
68            include_events,
69            include_input_objects,
70            include_output_objects,
71        );
72        Ok(None)
73    }
74}
75
76/// Authoritative per-transaction data read from a local cache.
77pub struct CachedTransactionData {
78    pub effects: TransactionEffects,
79    pub events: Option<TransactionEvents>,
80    pub input_objects: Option<Vec<Object>>,
81    pub output_objects: Option<Vec<Object>>,
82}
83
84pub struct SimulateTransactionResult {
85    pub effects: TransactionEffects,
86    pub events: Option<TransactionEvents>,
87    pub input_objects: BTreeMap<ObjectId, Object>,
88    pub output_objects: BTreeMap<ObjectId, Object>,
89    pub execution_result: Result<Vec<ExecutionResult>, ExecutionError>,
90    pub mock_gas_id: Option<ObjectId>,
91    pub suggested_gas_price: Option<u64>,
92}
93
94#[derive(Default, Debug, Copy, Clone)]
95pub enum VmChecks {
96    #[default]
97    Enabled,
98    Disabled,
99}
100
101impl VmChecks {
102    pub fn disabled(self) -> bool {
103        matches!(self, Self::Disabled)
104    }
105
106    pub fn enabled(self) -> bool {
107        matches!(self, Self::Enabled)
108    }
109}