sui_rpc_store/reader/
object_store.rs1use sui_consistent_store::reader::Reader;
16use sui_types::base_types::ObjectID;
17use sui_types::base_types::VersionNumber;
18use sui_types::object::Object;
19use sui_types::storage::ObjectStore;
20use tracing::error;
21
22use crate::reader::RpcStoreReader;
23
24impl<R: Reader + Send + Sync> ObjectStore for RpcStoreReader<R> {
25 fn get_object(&self, object_id: &ObjectID) -> Option<Object> {
26 match self.schema().get_object(*object_id) {
27 Ok(object) => object,
28 Err(e) => {
29 error!(?object_id, "get_object: {e:#}");
30 None
31 }
32 }
33 }
34
35 fn get_object_by_key(&self, object_id: &ObjectID, version: VersionNumber) -> Option<Object> {
36 match self.schema().get_object_by_key(*object_id, version) {
37 Ok(object) => object,
38 Err(e) => {
39 error!(?object_id, ?version, "get_object_by_key: {e:#}");
40 None
41 }
42 }
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use std::sync::Arc;
49
50 use sui_consistent_store::Db;
51 use sui_consistent_store::DbOptions;
52 use sui_types::base_types::ObjectID;
53 use sui_types::base_types::SuiAddress;
54 use sui_types::object::Object;
55 use sui_types::storage::ObjectKey;
56 use sui_types::storage::ObjectStore;
57
58 use crate::RpcStoreSchema;
59 use crate::reader::RpcStoreReader;
60 use crate::schema::objects;
61
62 fn open() -> (tempfile::TempDir, Db, RpcStoreSchema) {
63 let dir = tempfile::tempdir().unwrap();
64 let (db, schema) = Db::open::<RpcStoreSchema>(dir.path(), DbOptions::default()).unwrap();
65 (dir, db, schema)
66 }
67
68 fn dummy(id: ObjectID) -> Object {
69 Object::with_id_owner_for_testing(id, SuiAddress::ZERO)
70 }
71
72 fn seed(db: &Db, schema: &RpcStoreSchema, object: &Object) {
73 let mut batch = db.batch();
76 batch
77 .put(
78 &schema.objects,
79 &objects::Key {
80 id: object.id(),
81 version: object.version(),
82 },
83 &objects::store(object),
84 )
85 .unwrap();
86 batch.commit().unwrap();
87 }
88
89 #[test]
90 fn get_object_returns_latest_via_checkpoint_index() {
91 let (_dir, db, schema) = open();
92 let object = dummy(ObjectID::from_single_byte(1));
93 seed(&db, &schema, &object);
94
95 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
96 let read = reader
97 .get_object(&object.id())
98 .expect("object present via checkpoint index");
99 assert_eq!(read, object);
100 }
101
102 #[test]
103 fn get_object_returns_none_for_missing_id() {
104 let (_dir, db, schema) = open();
105 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
106 assert!(reader.get_object(&ObjectID::from_single_byte(7)).is_none());
107 }
108
109 #[test]
110 fn get_object_by_key_returns_exact_version() {
111 let (_dir, db, schema) = open();
112 let object = dummy(ObjectID::from_single_byte(2));
113 seed(&db, &schema, &object);
114
115 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
116 let read = reader
117 .get_object_by_key(&object.id(), object.version())
118 .expect("object present at exact version");
119 assert_eq!(read, object);
120 }
121
122 #[test]
123 fn get_object_by_key_returns_none_for_unknown_version() {
124 let (_dir, db, schema) = open();
125 let object = dummy(ObjectID::from_single_byte(3));
126 seed(&db, &schema, &object);
127
128 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
129 let missing_version = sui_types::base_types::SequenceNumber::from_u64(99);
130 assert!(
131 reader
132 .get_object_by_key(&object.id(), missing_version)
133 .is_none()
134 );
135 }
136
137 #[test]
138 fn multi_get_objects_uses_default_delegate() {
139 let (_dir, db, schema) = open();
140 let o1 = dummy(ObjectID::from_single_byte(4));
141 let o2 = dummy(ObjectID::from_single_byte(5));
142 seed(&db, &schema, &o1);
143 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
146 let results = reader.multi_get_objects(&[o1.id(), o2.id()]);
147 assert_eq!(results.len(), 2);
148 assert_eq!(results[0].as_ref(), Some(&o1));
149 assert!(results[1].is_none());
150 }
151
152 #[test]
153 fn multi_get_objects_by_key_uses_default_delegate() {
154 let (_dir, db, schema) = open();
155 let o1 = dummy(ObjectID::from_single_byte(6));
156 let o2 = dummy(ObjectID::from_single_byte(7));
157 seed(&db, &schema, &o1);
158 seed(&db, &schema, &o2);
159
160 let reader = RpcStoreReader::new(db.clone(), Arc::new(schema));
161 let keys = vec![
162 ObjectKey(o1.id(), o1.version()),
163 ObjectKey(o2.id(), o2.version()),
164 ];
165 let results = reader.multi_get_objects_by_key(&keys);
166 assert_eq!(results.len(), 2);
167 assert_eq!(results[0].as_ref(), Some(&o1));
168 assert_eq!(results[1].as_ref(), Some(&o2));
169 }
170}