simulacrum/store/
mod.rs

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