simulacrum/store/
mod.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;
6
7use iota_config::genesis;
8use iota_types::{
9    base_types::{IotaAddress, ObjectID, ObjectRef, SequenceNumber},
10    committee::{Committee, EpochId},
11    digests::{ObjectDigest, TransactionDigest, TransactionEventsDigest},
12    effects::{TransactionEffects, TransactionEffectsAPI, TransactionEvents},
13    error::{IotaResult, UserInputError},
14    messages_checkpoint::{
15        CheckpointContents, CheckpointContentsDigest, CheckpointDigest, CheckpointSequenceNumber,
16        VerifiedCheckpoint,
17    },
18    object::Object,
19    storage::{BackingStore, ChildObjectResolver},
20    transaction::{
21        InputObjectKind, InputObjects, ObjectReadResult, ReceivingObjectReadResult,
22        ReceivingObjects, VerifiedTransaction,
23    },
24};
25pub mod in_mem_store;
26
27pub trait SimulatorStore:
28    iota_types::storage::BackingPackageStore + iota_types::storage::ObjectStore + ChildObjectResolver
29{
30    fn init_with_genesis(&mut self, genesis: &genesis::Genesis) {
31        self.insert_checkpoint(genesis.checkpoint());
32        self.insert_checkpoint_contents(genesis.checkpoint_contents().clone());
33        self.insert_committee(genesis.committee().unwrap());
34        self.insert_transaction(VerifiedTransaction::new_unchecked(
35            genesis.transaction().clone(),
36        ));
37        self.insert_transaction_effects(genesis.effects().clone());
38        self.insert_events(
39            genesis.effects().transaction_digest(),
40            genesis.events().clone(),
41        );
42
43        self.update_objects(
44            genesis
45                .objects()
46                .iter()
47                .map(|o| (o.id(), o.clone()))
48                .collect(),
49            vec![],
50        );
51    }
52
53    fn get_checkpoint_by_sequence_number(
54        &self,
55        sequence_number: CheckpointSequenceNumber,
56    ) -> Option<VerifiedCheckpoint>;
57
58    fn get_checkpoint_by_digest(&self, digest: &CheckpointDigest) -> Option<VerifiedCheckpoint>;
59
60    fn get_highest_checkpoint(&self) -> Option<VerifiedCheckpoint>;
61
62    fn get_checkpoint_contents(
63        &self,
64        digest: &CheckpointContentsDigest,
65    ) -> Option<CheckpointContents>;
66
67    fn get_committee_by_epoch(&self, epoch: EpochId) -> Option<Committee>;
68
69    fn get_transaction(&self, digest: &TransactionDigest) -> Option<VerifiedTransaction>;
70
71    fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects>;
72
73    fn get_transaction_events(&self, digest: &TransactionEventsDigest)
74    -> Option<TransactionEvents>;
75
76    fn get_transaction_events_by_tx_digest(
77        &self,
78        tx_digest: &TransactionDigest,
79    ) -> Option<TransactionEvents>;
80
81    fn get_object(&self, id: &ObjectID) -> Option<Object>;
82
83    fn get_object_at_version(&self, id: &ObjectID, version: SequenceNumber) -> Option<Object>;
84
85    fn get_system_state(&self) -> iota_types::iota_system_state::IotaSystemState;
86
87    fn get_clock(&self) -> iota_types::clock::Clock;
88
89    fn owned_objects(&self, owner: IotaAddress) -> Box<dyn Iterator<Item = Object> + '_>;
90
91    fn insert_checkpoint(&mut self, checkpoint: VerifiedCheckpoint);
92
93    fn insert_checkpoint_contents(&mut self, contents: CheckpointContents);
94
95    fn insert_committee(&mut self, committee: Committee);
96
97    fn insert_executed_transaction(
98        &mut self,
99        transaction: VerifiedTransaction,
100        effects: TransactionEffects,
101        events: TransactionEvents,
102        written_objects: BTreeMap<ObjectID, Object>,
103    );
104
105    fn insert_transaction(&mut self, transaction: VerifiedTransaction);
106
107    fn insert_transaction_effects(&mut self, effects: TransactionEffects);
108
109    fn insert_events(&mut self, tx_digest: &TransactionDigest, events: TransactionEvents);
110
111    fn update_objects(
112        &mut self,
113        written_objects: BTreeMap<ObjectID, Object>,
114        deleted_objects: Vec<(ObjectID, SequenceNumber, ObjectDigest)>,
115    );
116
117    fn backing_store(&self) -> &dyn BackingStore;
118
119    // TODO: This function is now out-of-sync with read_objects_for_execution from
120    // transaction_input_loader.rs. For instance, it does not support the use of
121    // deleted shared objects. We will need to make SimulatorStore implement
122    // ExecutionCacheRead, and keep track of deleted shared objects in a marker
123    // table in order to merge this function.
124    fn read_objects_for_synchronous_execution(
125        &self,
126        _tx_digest: &TransactionDigest,
127        input_object_kinds: &[InputObjectKind],
128        receiving_object_refs: &[ObjectRef],
129    ) -> IotaResult<(InputObjects, ReceivingObjects)> {
130        let mut input_objects = Vec::new();
131        for kind in input_object_kinds {
132            let obj = match kind {
133                InputObjectKind::MovePackage(id) => {
134                    crate::store::SimulatorStore::get_object(self, id)
135                }
136                InputObjectKind::ImmOrOwnedMoveObject(objref) => {
137                    self.get_object_by_key(&objref.0, objref.1)?
138                }
139
140                InputObjectKind::SharedMoveObject { id, .. } => {
141                    crate::store::SimulatorStore::get_object(self, id)
142                }
143            };
144
145            input_objects.push(ObjectReadResult::new(
146                *kind,
147                obj.ok_or_else(|| kind.object_not_found_error())?.into(),
148            ));
149        }
150
151        let mut receiving_objects = Vec::new();
152        for objref in receiving_object_refs {
153            // no need for marker table check in simulacrum
154            let Some(obj) = crate::store::SimulatorStore::get_object(self, &objref.0) else {
155                return Err(UserInputError::ObjectNotFound {
156                    object_id: objref.0,
157                    version: Some(objref.1),
158                }
159                .into());
160            };
161            receiving_objects.push(ReceivingObjectReadResult::new(*objref, obj.into()));
162        }
163
164        Ok((input_objects.into(), receiving_objects.into()))
165    }
166}