sui_move_natives_latest/object_runtime/
fingerprint.rs1use move_binary_format::errors::{PartialVMError, PartialVMResult};
5use move_core_types::vm_status::StatusCode;
6use move_vm_types::values::Value;
7use sui_protocol_config::ProtocolConfig;
8use sui_types::base_types::{MoveObjectType, ObjectID};
9
10pub struct ObjectFingerprint(Option<ObjectFingerprint_>);
15
16enum ObjectFingerprint_ {
17 Empty,
19 Preexisting {
21 owner: ObjectID,
22 ty: MoveObjectType,
23 value: Value,
24 },
25}
26
27impl ObjectFingerprint {
28 #[cfg(debug_assertions)]
29 pub fn is_disabled(&self) -> bool {
30 self.0.is_none()
31 }
32
33 pub fn none(protocol_config: &ProtocolConfig) -> Self {
36 if !protocol_config.minimize_child_object_mutations() {
37 Self(None)
38 } else {
39 Self(Some(ObjectFingerprint_::Empty))
40 }
41 }
42
43 pub fn preexisting(
46 protocol_config: &ProtocolConfig,
47 preexisting_owner: &ObjectID,
48 preexisting_type: &MoveObjectType,
49 preexisting_value: &Value,
50 ) -> PartialVMResult<Self> {
51 Ok(if !protocol_config.minimize_child_object_mutations() {
52 Self(None)
53 } else {
54 Self(Some(ObjectFingerprint_::Preexisting {
55 owner: *preexisting_owner,
56 ty: preexisting_type.clone(),
57 value: preexisting_value.copy_value()?,
58 }))
59 })
60 }
61
62 pub fn object_has_changed(
67 &self,
68 final_owner: &ObjectID,
69 final_type: &MoveObjectType,
70 final_value: &Option<Value>,
71 ) -> PartialVMResult<bool> {
72 use ObjectFingerprint_ as F;
73 let Some(inner) = &self.0 else {
74 return Err(
75 PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message(
76 "Object fingerprint not enabled, yet we were asked for the changes".to_string(),
77 ),
78 );
79 };
80 Ok(match (inner, final_value) {
81 (F::Empty, None) => false,
82 (F::Empty, Some(_)) | (F::Preexisting { .. }, None) => true,
83 (
84 F::Preexisting {
85 owner: preexisting_owner,
86 ty: preexisting_type,
87 value: preexisting_value,
88 },
89 Some(final_value),
90 ) => {
91 !(preexisting_owner == final_owner
95 && preexisting_type == final_type
96 && preexisting_value.equals(final_value)?)
97 }
98 })
99 }
100}