sui_core/execution_cache/
object_locks.rs1use mysten_common::ZipDebugEqIteratorExt;
5
6#[cfg(test)]
7use crate::authority::authority_per_epoch_store::AuthorityPerEpochStore;
8use sui_types::base_types::{ObjectID, ObjectRef};
9#[cfg(test)]
10use sui_types::digests::TransactionDigest;
11use sui_types::error::{SuiErrorKind, SuiResult, UserInputError};
12use sui_types::object::Object;
13use sui_types::storage::ObjectStore;
14use tracing::{debug, instrument};
15
16use super::writeback_cache::WritebackCache;
17
18pub(super) struct ObjectLocks {}
19
20impl ObjectLocks {
21 pub fn new() -> Self {
22 Self {}
23 }
24
25 #[cfg(test)]
26 pub(crate) fn get_transaction_lock(
27 &self,
28 obj_ref: &ObjectRef,
29 epoch_store: &AuthorityPerEpochStore,
30 ) -> SuiResult<Option<TransactionDigest>> {
31 epoch_store.tables()?.get_locked_transaction(obj_ref)
32 }
33
34 pub(crate) fn clear(&self) {
35 }
38
39 fn verify_live_object(obj_ref: &ObjectRef, live_object: &Object) -> SuiResult {
40 debug_assert_eq!(obj_ref.0, live_object.id());
41 if obj_ref.1 != live_object.version() {
42 debug!(
43 "object version unavailable for consumption: {:?} (current: {})",
44 obj_ref,
45 live_object.version()
46 );
47 return Err(SuiErrorKind::UserInputError {
48 error: UserInputError::ObjectVersionUnavailableForConsumption {
49 provided_obj_ref: *obj_ref,
50 current_version: live_object.version(),
51 },
52 }
53 .into());
54 }
55
56 let live_digest = live_object.digest();
57 if obj_ref.2 != live_digest {
58 return Err(SuiErrorKind::UserInputError {
59 error: UserInputError::InvalidObjectDigest {
60 object_id: obj_ref.0,
61 expected_digest: live_digest,
62 },
63 }
64 .into());
65 }
66
67 Ok(())
68 }
69
70 fn multi_get_objects_must_exist(
71 cache: &WritebackCache,
72 object_ids: &[ObjectID],
73 ) -> SuiResult<Vec<Object>> {
74 let objects = cache.multi_get_objects(object_ids);
75 let mut result = Vec::with_capacity(objects.len());
76 for (i, object) in objects.into_iter().enumerate() {
77 if let Some(object) = object {
78 result.push(object);
79 } else {
80 return Err(SuiErrorKind::UserInputError {
81 error: UserInputError::ObjectNotFound {
82 object_id: object_ids[i],
83 version: None,
84 },
85 }
86 .into());
87 }
88 }
89 Ok(result)
90 }
91
92 #[instrument(level = "debug", skip_all)]
95 pub(crate) fn validate_owned_object_versions(
96 cache: &WritebackCache,
97 owned_input_objects: &[ObjectRef],
98 ) -> SuiResult {
99 let object_ids = owned_input_objects.iter().map(|o| o.0).collect::<Vec<_>>();
100 let live_objects = Self::multi_get_objects_must_exist(cache, &object_ids)?;
101
102 for (obj_ref, live_object) in owned_input_objects.iter().zip_debug_eq(live_objects.iter()) {
104 Self::verify_live_object(obj_ref, live_object)?;
105 }
106
107 Ok(())
108 }
109}