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