1use crate::authority::AuthorityState;
5use crate::checkpoints::CheckpointStore;
6use crate::epoch::committee_store::CommitteeStore;
7use crate::execution_cache::ExecutionCacheTraitPointers;
8use move_core_types::language_storage::StructTag;
9use parking_lot::Mutex;
10use std::sync::Arc;
11use sui_rpc_store::RpcStoreReader;
12use sui_types::base_types::ObjectID;
13use sui_types::base_types::SequenceNumber;
14use sui_types::base_types::SuiAddress;
15use sui_types::base_types::TransactionDigest;
16use sui_types::committee::Committee;
17use sui_types::committee::EpochId;
18use sui_types::effects::{TransactionEffects, TransactionEvents};
19use sui_types::error::{SuiErrorKind, SuiResult};
20use sui_types::full_checkpoint_content::ObjectSet;
21use sui_types::messages_checkpoint::CheckpointContentsDigest;
22use sui_types::messages_checkpoint::CheckpointDigest;
23use sui_types::messages_checkpoint::CheckpointSequenceNumber;
24use sui_types::messages_checkpoint::EndOfEpochData;
25use sui_types::messages_checkpoint::VerifiedCheckpoint;
26use sui_types::messages_checkpoint::VerifiedCheckpointContents;
27use sui_types::messages_checkpoint::VersionedFullCheckpointContents;
28use sui_types::object::Object;
29use sui_types::object::Owner;
30use sui_types::storage::BalanceInfo;
31use sui_types::storage::BalanceIterator;
32use sui_types::storage::CoinInfo;
33use sui_types::storage::DynamicFieldKey;
34use sui_types::storage::LedgerBitmapBucketIterator;
35use sui_types::storage::LedgerTxSeqDigest;
36use sui_types::storage::LedgerTxSeqDigestIterator;
37use sui_types::storage::ObjectStore;
38use sui_types::storage::OwnedObjectInfo;
39use sui_types::storage::RpcIndexes;
40use sui_types::storage::RpcStateReader;
41use sui_types::storage::RuntimeObjectResolver;
42use sui_types::storage::WriteStore;
43use sui_types::storage::error::Error as StorageError;
44use sui_types::storage::error::Result;
45use sui_types::storage::{BackingPackageStore, PackageObject};
46use sui_types::storage::{ObjectKey, OverlayBackingPackageStore, ReadStore};
47use sui_types::transaction::VerifiedTransaction;
48use tap::TapFallible;
49use tracing::error;
50use typed_store::TypedStoreError;
51
52#[derive(Clone)]
53pub struct RocksDbStore {
54 cache_traits: ExecutionCacheTraitPointers,
55
56 committee_store: Arc<CommitteeStore>,
57 checkpoint_store: Arc<CheckpointStore>,
58 highest_verified_checkpoint: Arc<Mutex<Option<u64>>>,
60 highest_synced_checkpoint: Arc<Mutex<Option<u64>>>,
61}
62
63impl RocksDbStore {
64 pub fn new(
65 cache_traits: ExecutionCacheTraitPointers,
66 committee_store: Arc<CommitteeStore>,
67 checkpoint_store: Arc<CheckpointStore>,
68 ) -> Self {
69 Self {
70 cache_traits,
71 committee_store,
72 checkpoint_store,
73 highest_verified_checkpoint: Arc::new(Mutex::new(None)),
74 highest_synced_checkpoint: Arc::new(Mutex::new(None)),
75 }
76 }
77
78 pub fn get_objects(&self, object_keys: &[ObjectKey]) -> Vec<Option<Object>> {
79 self.cache_traits
80 .object_cache_reader
81 .multi_get_objects_by_key(object_keys)
82 }
83
84 pub fn get_last_executed_checkpoint(&self) -> Option<VerifiedCheckpoint> {
85 self.checkpoint_store
86 .get_highest_executed_checkpoint()
87 .expect("db error")
88 }
89}
90
91impl ReadStore for RocksDbStore {
92 fn get_checkpoint_by_digest(&self, digest: &CheckpointDigest) -> Option<VerifiedCheckpoint> {
93 self.checkpoint_store
94 .get_checkpoint_by_digest(digest)
95 .expect("db error")
96 }
97
98 fn get_checkpoint_by_sequence_number(
99 &self,
100 sequence_number: CheckpointSequenceNumber,
101 ) -> Option<VerifiedCheckpoint> {
102 self.checkpoint_store
103 .get_checkpoint_by_sequence_number(sequence_number)
104 .expect("db error")
105 }
106
107 fn multi_get_checkpoint_by_sequence_number(
108 &self,
109 sequence_numbers: &[CheckpointSequenceNumber],
110 ) -> Vec<Option<VerifiedCheckpoint>> {
111 self.checkpoint_store
112 .multi_get_checkpoint_by_sequence_number(sequence_numbers)
113 .expect("db error")
114 }
115
116 fn get_highest_verified_checkpoint(&self) -> Result<VerifiedCheckpoint, StorageError> {
117 self.checkpoint_store
118 .get_highest_verified_checkpoint()
119 .map(|maybe_checkpoint| {
120 maybe_checkpoint
121 .expect("storage should have been initialized with genesis checkpoint")
122 })
123 .map_err(Into::into)
124 }
125
126 fn get_highest_synced_checkpoint(&self) -> Result<VerifiedCheckpoint, StorageError> {
127 self.checkpoint_store
128 .get_highest_synced_checkpoint()
129 .map(|maybe_checkpoint| {
130 maybe_checkpoint
131 .expect("storage should have been initialized with genesis checkpoint")
132 })
133 .map_err(Into::into)
134 }
135
136 fn get_lowest_available_checkpoint(&self) -> Result<CheckpointSequenceNumber, StorageError> {
137 if let Some(highest_pruned_cp) = self
138 .checkpoint_store
139 .get_highest_pruned_checkpoint_seq_number()
140 .map_err(Into::<StorageError>::into)?
141 {
142 Ok(highest_pruned_cp + 1)
143 } else {
144 Ok(0)
145 }
146 }
147
148 fn get_full_checkpoint_contents(
149 &self,
150 sequence_number: Option<CheckpointSequenceNumber>,
151 digest: &CheckpointContentsDigest,
152 ) -> Option<VersionedFullCheckpointContents> {
153 #[cfg(debug_assertions)]
154 if let Some(sequence_number) = sequence_number {
155 if let Some(loaded_sequence_number) = self
159 .checkpoint_store
160 .get_sequence_number_by_contents_digest(digest)
161 .expect("db error")
162 {
163 assert_eq!(loaded_sequence_number, sequence_number);
164 }
165 }
166
167 let sequence_number = sequence_number.or_else(|| {
168 self.checkpoint_store
169 .get_sequence_number_by_contents_digest(digest)
170 .expect("db error")
171 });
172 if let Some(sequence_number) = sequence_number {
173 if let Ok(Some(contents)) = self
179 .checkpoint_store
180 .get_full_checkpoint_contents_by_sequence_number(sequence_number)
181 .tap_err(|e| {
182 error!(
183 "error getting full checkpoint contents for checkpoint {:?}: {:?}",
184 sequence_number, e
185 )
186 })
187 {
188 return Some(contents);
189 }
190 }
191
192 self.checkpoint_store
198 .get_checkpoint_contents(digest)
199 .expect("db error")
200 .and_then(|contents| {
201 let mut transactions = Vec::with_capacity(contents.size());
202 for tx in contents.iter() {
203 if let (Some(t), Some(e)) = (
204 self.get_transaction(&tx.transaction),
205 self.cache_traits
206 .transaction_cache_reader
207 .get_effects(&tx.effects),
208 ) {
209 transactions.push(sui_types::base_types::ExecutionData::new(
210 (*t).clone().into_inner(),
211 e,
212 ))
213 } else {
214 return None;
215 }
216 }
217 Some(
218 VersionedFullCheckpointContents::from_contents_and_execution_data(
219 contents,
220 transactions.into_iter(),
221 ),
222 )
223 })
224 }
225
226 fn get_committee(&self, epoch: EpochId) -> Option<Arc<Committee>> {
227 self.committee_store.get_committee(&epoch).unwrap()
228 }
229
230 fn get_transaction(&self, digest: &TransactionDigest) -> Option<Arc<VerifiedTransaction>> {
231 self.cache_traits
232 .transaction_cache_reader
233 .get_transaction_block(digest)
234 }
235
236 fn multi_get_transactions(
237 &self,
238 digests: &[TransactionDigest],
239 ) -> Vec<Option<Arc<VerifiedTransaction>>> {
240 self.cache_traits
241 .transaction_cache_reader
242 .multi_get_transaction_blocks(digests)
243 }
244
245 fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects> {
246 self.cache_traits
247 .transaction_cache_reader
248 .get_executed_effects(digest)
249 }
250
251 fn multi_get_transaction_effects(
252 &self,
253 digests: &[TransactionDigest],
254 ) -> Vec<Option<TransactionEffects>> {
255 self.cache_traits
256 .transaction_cache_reader
257 .multi_get_executed_effects(digests)
258 }
259
260 fn get_events(&self, digest: &TransactionDigest) -> Option<TransactionEvents> {
261 self.cache_traits
262 .transaction_cache_reader
263 .get_events(digest)
264 }
265
266 fn multi_get_events(&self, digests: &[TransactionDigest]) -> Vec<Option<TransactionEvents>> {
267 self.cache_traits
268 .transaction_cache_reader
269 .multi_get_events(digests)
270 }
271
272 fn get_unchanged_loaded_runtime_objects(
273 &self,
274 digest: &TransactionDigest,
275 ) -> Option<Vec<ObjectKey>> {
276 self.cache_traits
277 .transaction_cache_reader
278 .get_unchanged_loaded_runtime_objects(digest)
279 }
280
281 fn multi_get_unchanged_loaded_runtime_objects(
282 &self,
283 digests: &[TransactionDigest],
284 ) -> Vec<Option<Vec<ObjectKey>>> {
285 self.cache_traits
286 .transaction_cache_reader
287 .multi_get_unchanged_loaded_runtime_objects(digests)
288 }
289
290 fn get_transaction_checkpoint(
291 &self,
292 digest: &TransactionDigest,
293 ) -> Option<CheckpointSequenceNumber> {
294 self.cache_traits
295 .checkpoint_cache
296 .deprecated_get_transaction_checkpoint(digest)
297 .map(|(_epoch, checkpoint)| checkpoint)
298 }
299
300 fn get_latest_checkpoint(&self) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
301 self.checkpoint_store
302 .get_highest_executed_checkpoint()
303 .expect("db error")
304 .ok_or_else(|| {
305 sui_types::storage::error::Error::missing("unable to get latest checkpoint")
306 })
307 }
308
309 fn get_checkpoint_contents_by_digest(
310 &self,
311 digest: &CheckpointContentsDigest,
312 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
313 self.checkpoint_store
314 .get_checkpoint_contents(digest)
315 .expect("db error")
316 }
317
318 fn get_checkpoint_contents_by_sequence_number(
319 &self,
320 sequence_number: CheckpointSequenceNumber,
321 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
322 match self.get_checkpoint_by_sequence_number(sequence_number) {
323 Some(checkpoint) => self.get_checkpoint_contents_by_digest(&checkpoint.content_digest),
324 None => None,
325 }
326 }
327}
328
329impl ObjectStore for RocksDbStore {
330 fn get_object(&self, object_id: &sui_types::base_types::ObjectID) -> Option<Object> {
331 self.cache_traits.object_store.get_object(object_id)
332 }
333
334 fn get_object_by_key(
335 &self,
336 object_id: &sui_types::base_types::ObjectID,
337 version: sui_types::base_types::VersionNumber,
338 ) -> Option<Object> {
339 self.cache_traits
340 .object_store
341 .get_object_by_key(object_id, version)
342 }
343
344 fn multi_get_objects_by_key(&self, object_keys: &[ObjectKey]) -> Vec<Option<Object>> {
345 self.cache_traits
346 .object_cache_reader
347 .multi_get_objects_by_key(object_keys)
348 }
349}
350
351impl WriteStore for RocksDbStore {
352 fn insert_checkpoint(
353 &self,
354 checkpoint: &VerifiedCheckpoint,
355 ) -> Result<(), sui_types::storage::error::Error> {
356 if let Some(EndOfEpochData {
357 next_epoch_committee,
358 ..
359 }) = checkpoint.end_of_epoch_data.as_ref()
360 {
361 let next_committee = next_epoch_committee.iter().cloned().collect();
362 let committee =
363 Committee::new(checkpoint.epoch().checked_add(1).unwrap(), next_committee);
364 self.insert_committee(committee)?;
365 }
366
367 self.checkpoint_store
368 .insert_verified_checkpoint(checkpoint)
369 .map_err(Into::into)
370 }
371
372 fn update_highest_synced_checkpoint(
373 &self,
374 checkpoint: &VerifiedCheckpoint,
375 ) -> Result<(), sui_types::storage::error::Error> {
376 let mut locked = self.highest_synced_checkpoint.lock();
377 if locked.is_some() && locked.unwrap() >= checkpoint.sequence_number {
378 return Ok(());
379 }
380 self.checkpoint_store
381 .update_highest_synced_checkpoint(checkpoint)
382 .map_err(sui_types::storage::error::Error::custom)?;
383 *locked = Some(checkpoint.sequence_number);
384 Ok(())
385 }
386
387 fn update_highest_verified_checkpoint(
388 &self,
389 checkpoint: &VerifiedCheckpoint,
390 ) -> Result<(), sui_types::storage::error::Error> {
391 let mut locked = self.highest_verified_checkpoint.lock();
392 if locked.is_some() && locked.unwrap() >= checkpoint.sequence_number {
393 return Ok(());
394 }
395 self.checkpoint_store
396 .update_highest_verified_checkpoint(checkpoint)
397 .map_err(sui_types::storage::error::Error::custom)?;
398 *locked = Some(checkpoint.sequence_number);
399 Ok(())
400 }
401
402 fn insert_checkpoint_contents(
403 &self,
404 checkpoint: &VerifiedCheckpoint,
405 contents: VerifiedCheckpointContents,
406 ) -> Result<(), sui_types::storage::error::Error> {
407 self.cache_traits
408 .state_sync_store
409 .multi_insert_transaction_and_effects(contents.transactions());
410 self.checkpoint_store
411 .insert_verified_checkpoint_contents(checkpoint, contents)
412 .map_err(Into::into)
413 }
414
415 fn insert_committee(
416 &self,
417 new_committee: Committee,
418 ) -> Result<(), sui_types::storage::error::Error> {
419 self.committee_store
420 .insert_new_committee(&new_committee)
421 .unwrap();
422 Ok(())
423 }
424}
425
426pub struct RestReadStore {
427 state: Arc<AuthorityState>,
428 rocks: RocksDbStore,
429}
430
431impl RestReadStore {
432 pub fn new(state: Arc<AuthorityState>, rocks: RocksDbStore) -> Self {
433 Self { state, rocks }
434 }
435}
436
437impl ObjectStore for RestReadStore {
438 fn get_object(&self, object_id: &sui_types::base_types::ObjectID) -> Option<Object> {
439 self.rocks.get_object(object_id)
440 }
441
442 fn get_object_by_key(
443 &self,
444 object_id: &sui_types::base_types::ObjectID,
445 version: sui_types::base_types::VersionNumber,
446 ) -> Option<Object> {
447 self.rocks.get_object_by_key(object_id, version)
448 }
449
450 fn multi_get_objects_by_key(&self, object_keys: &[ObjectKey]) -> Vec<Option<Object>> {
451 self.rocks.multi_get_objects_by_key(object_keys)
452 }
453}
454
455impl ReadStore for RestReadStore {
456 fn get_committee(&self, epoch: EpochId) -> Option<Arc<Committee>> {
457 self.rocks.get_committee(epoch)
458 }
459
460 fn get_latest_checkpoint(&self) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
461 self.rocks.get_latest_checkpoint()
462 }
463
464 fn get_highest_verified_checkpoint(
465 &self,
466 ) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
467 self.rocks.get_highest_verified_checkpoint()
468 }
469
470 fn get_highest_synced_checkpoint(
471 &self,
472 ) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
473 self.rocks.get_highest_synced_checkpoint()
474 }
475
476 fn get_lowest_available_checkpoint(
477 &self,
478 ) -> sui_types::storage::error::Result<CheckpointSequenceNumber> {
479 self.rocks.get_lowest_available_checkpoint()
480 }
481
482 fn get_checkpoint_by_digest(&self, digest: &CheckpointDigest) -> Option<VerifiedCheckpoint> {
483 self.rocks.get_checkpoint_by_digest(digest)
484 }
485
486 fn get_checkpoint_by_sequence_number(
487 &self,
488 sequence_number: CheckpointSequenceNumber,
489 ) -> Option<VerifiedCheckpoint> {
490 self.rocks
491 .get_checkpoint_by_sequence_number(sequence_number)
492 }
493
494 fn multi_get_checkpoint_by_sequence_number(
495 &self,
496 sequence_numbers: &[CheckpointSequenceNumber],
497 ) -> Vec<Option<VerifiedCheckpoint>> {
498 self.rocks
499 .multi_get_checkpoint_by_sequence_number(sequence_numbers)
500 }
501
502 fn get_checkpoint_contents_by_digest(
503 &self,
504 digest: &CheckpointContentsDigest,
505 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
506 self.rocks.get_checkpoint_contents_by_digest(digest)
507 }
508
509 fn get_checkpoint_contents_by_sequence_number(
510 &self,
511 sequence_number: CheckpointSequenceNumber,
512 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
513 self.rocks
514 .get_checkpoint_contents_by_sequence_number(sequence_number)
515 }
516
517 fn get_transaction(&self, digest: &TransactionDigest) -> Option<Arc<VerifiedTransaction>> {
518 self.rocks.get_transaction(digest)
519 }
520
521 fn multi_get_transactions(
522 &self,
523 digests: &[TransactionDigest],
524 ) -> Vec<Option<Arc<VerifiedTransaction>>> {
525 self.rocks.multi_get_transactions(digests)
526 }
527
528 fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects> {
529 self.rocks.get_transaction_effects(digest)
530 }
531
532 fn multi_get_transaction_effects(
533 &self,
534 digests: &[TransactionDigest],
535 ) -> Vec<Option<TransactionEffects>> {
536 self.rocks.multi_get_transaction_effects(digests)
537 }
538
539 fn get_events(&self, digest: &TransactionDigest) -> Option<TransactionEvents> {
540 self.rocks.get_events(digest)
541 }
542
543 fn multi_get_events(&self, digests: &[TransactionDigest]) -> Vec<Option<TransactionEvents>> {
544 self.rocks.multi_get_events(digests)
545 }
546
547 fn get_full_checkpoint_contents(
548 &self,
549 sequence_number: Option<CheckpointSequenceNumber>,
550 digest: &CheckpointContentsDigest,
551 ) -> Option<VersionedFullCheckpointContents> {
552 self.rocks
553 .get_full_checkpoint_contents(sequence_number, digest)
554 }
555
556 fn get_unchanged_loaded_runtime_objects(
557 &self,
558 digest: &TransactionDigest,
559 ) -> Option<Vec<ObjectKey>> {
560 self.rocks.get_unchanged_loaded_runtime_objects(digest)
561 }
562
563 fn multi_get_unchanged_loaded_runtime_objects(
564 &self,
565 digests: &[TransactionDigest],
566 ) -> Vec<Option<Vec<ObjectKey>>> {
567 self.rocks
568 .multi_get_unchanged_loaded_runtime_objects(digests)
569 }
570
571 fn get_transaction_checkpoint(
572 &self,
573 digest: &TransactionDigest,
574 ) -> Option<CheckpointSequenceNumber> {
575 self.rocks.get_transaction_checkpoint(digest)
576 }
577}
578
579impl BackingPackageStore for RestReadStore {
580 fn get_package_object(&self, _package_id: &ObjectID) -> SuiResult<Option<PackageObject>> {
581 Err(SuiErrorKind::UnsupportedFeatureError {
582 error: "RestReadStore does not support loading package objects".to_string(),
583 }
584 .into())
585 }
586}
587
588impl RuntimeObjectResolver for RestReadStore {
589 fn read_child_object(
590 &self,
591 parent: &ObjectID,
592 child: &ObjectID,
593 child_version_upper_bound: SequenceNumber,
594 ) -> SuiResult<Option<Object>> {
595 Ok(self.get_object(child).filter(|o| {
596 o.version() <= child_version_upper_bound
597 && o.owner == Owner::ObjectOwner((*parent).into())
598 }))
599 }
600
601 fn get_object_received_at_version(
602 &self,
603 _owner: &ObjectID,
604 _receiving_object_id: &ObjectID,
605 _receive_object_at_version: SequenceNumber,
606 _epoch_id: EpochId,
607 ) -> SuiResult<Option<Object>> {
608 Err(SuiErrorKind::UnsupportedFeatureError {
609 error: "RestReadStore does not support receiving objects".to_string(),
610 }
611 .into())
612 }
613}
614
615impl RpcStateReader for RestReadStore {
616 fn get_lowest_available_checkpoint_objects(
617 &self,
618 ) -> sui_types::storage::error::Result<CheckpointSequenceNumber> {
619 Ok(self
620 .state
621 .get_object_cache_reader()
622 .get_highest_pruned_checkpoint()
623 .map(|cp| cp + 1)
624 .unwrap_or(0))
625 }
626
627 fn get_chain_identifier(&self) -> Result<sui_types::digests::ChainIdentifier> {
628 Ok(self.state.get_chain_identifier())
629 }
630
631 fn indexes(&self) -> Option<&dyn RpcIndexes> {
632 None
636 }
637
638 fn get_struct_layout_with_overlay(
639 &self,
640 struct_tag: &move_core_types::language_storage::StructTag,
641 overlay: &ObjectSet,
642 ) -> Result<Option<move_core_types::annotated_value::MoveTypeLayout>> {
643 let backing_store = self.state.get_backing_package_store();
644 let overlay_store = OverlayBackingPackageStore::new(overlay, backing_store.as_ref());
645 let epoch_store = self.state.load_epoch_store_one_call_per_task();
646 epoch_store
647 .executor()
648 .type_layout_resolver(epoch_store.protocol_config(), Box::new(overlay_store))
650 .get_annotated_layout(struct_tag)
651 .map(|layout| layout.into_layout())
652 .map(Some)
653 .map_err(StorageError::custom)
654 }
655}
656
657pub struct RpcStoreReadStore {
680 state: Arc<AuthorityState>,
681 rocks: RocksDbStore,
682 reader: RpcStoreReader,
683}
684
685impl RpcStoreReadStore {
686 pub fn new(state: Arc<AuthorityState>, rocks: RocksDbStore, reader: RpcStoreReader) -> Self {
687 Self {
688 state,
689 rocks,
690 reader,
691 }
692 }
693}
694
695impl ObjectStore for RpcStoreReadStore {
696 fn get_object(&self, object_id: &ObjectID) -> Option<Object> {
697 self.rocks.get_object(object_id)
698 }
699
700 fn get_object_by_key(&self, object_id: &ObjectID, version: SequenceNumber) -> Option<Object> {
701 self.rocks.get_object_by_key(object_id, version)
702 }
703
704 fn multi_get_objects_by_key(&self, object_keys: &[ObjectKey]) -> Vec<Option<Object>> {
705 self.rocks.multi_get_objects_by_key(object_keys)
706 }
707}
708
709impl ReadStore for RpcStoreReadStore {
710 fn get_committee(&self, epoch: EpochId) -> Option<Arc<Committee>> {
711 self.rocks.get_committee(epoch)
712 }
713
714 fn get_latest_checkpoint(&self) -> Result<VerifiedCheckpoint> {
715 let latest = self.rocks.get_latest_checkpoint()?;
716 match self.reader.highest_live_committed_checkpoint()? {
724 Some(indexed) if indexed < latest.sequence_number => self
725 .rocks
726 .get_checkpoint_by_sequence_number(indexed)
727 .ok_or_else(|| {
728 StorageError::missing(format!(
729 "live-indexed checkpoint {indexed} missing from the checkpoint store"
730 ))
731 }),
732 Some(_) => Ok(latest),
733 None => Err(StorageError::missing(
741 "the embedded rpc-store's live index has no committed checkpoint yet",
742 )),
743 }
744 }
745
746 fn get_highest_verified_checkpoint(&self) -> Result<VerifiedCheckpoint> {
747 self.rocks.get_highest_verified_checkpoint()
748 }
749
750 fn get_highest_synced_checkpoint(&self) -> Result<VerifiedCheckpoint> {
751 self.rocks.get_highest_synced_checkpoint()
752 }
753
754 fn get_lowest_available_checkpoint(&self) -> Result<CheckpointSequenceNumber> {
755 let perpetual = self.rocks.get_lowest_available_checkpoint()?;
759 let rpc_store = self.reader.get_lowest_available_checkpoint()?;
760 Ok(perpetual.max(rpc_store))
761 }
762
763 fn get_checkpoint_by_digest(&self, digest: &CheckpointDigest) -> Option<VerifiedCheckpoint> {
764 self.rocks.get_checkpoint_by_digest(digest)
765 }
766
767 fn get_checkpoint_by_sequence_number(
768 &self,
769 sequence_number: CheckpointSequenceNumber,
770 ) -> Option<VerifiedCheckpoint> {
771 self.rocks
772 .get_checkpoint_by_sequence_number(sequence_number)
773 }
774
775 fn multi_get_checkpoint_by_sequence_number(
776 &self,
777 sequence_numbers: &[CheckpointSequenceNumber],
778 ) -> Vec<Option<VerifiedCheckpoint>> {
779 self.rocks
780 .multi_get_checkpoint_by_sequence_number(sequence_numbers)
781 }
782
783 fn get_checkpoint_contents_by_digest(
784 &self,
785 digest: &CheckpointContentsDigest,
786 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
787 self.rocks.get_checkpoint_contents_by_digest(digest)
788 }
789
790 fn get_checkpoint_contents_by_sequence_number(
791 &self,
792 sequence_number: CheckpointSequenceNumber,
793 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
794 self.rocks
795 .get_checkpoint_contents_by_sequence_number(sequence_number)
796 }
797
798 fn get_transaction(&self, digest: &TransactionDigest) -> Option<Arc<VerifiedTransaction>> {
799 self.rocks.get_transaction(digest)
800 }
801
802 fn multi_get_transactions(
803 &self,
804 digests: &[TransactionDigest],
805 ) -> Vec<Option<Arc<VerifiedTransaction>>> {
806 self.rocks.multi_get_transactions(digests)
807 }
808
809 fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects> {
810 self.rocks.get_transaction_effects(digest)
811 }
812
813 fn multi_get_transaction_effects(
814 &self,
815 digests: &[TransactionDigest],
816 ) -> Vec<Option<TransactionEffects>> {
817 self.rocks.multi_get_transaction_effects(digests)
818 }
819
820 fn get_events(&self, digest: &TransactionDigest) -> Option<TransactionEvents> {
821 self.rocks.get_events(digest)
822 }
823
824 fn multi_get_events(&self, digests: &[TransactionDigest]) -> Vec<Option<TransactionEvents>> {
825 self.rocks.multi_get_events(digests)
826 }
827
828 fn get_full_checkpoint_contents(
829 &self,
830 sequence_number: Option<CheckpointSequenceNumber>,
831 digest: &CheckpointContentsDigest,
832 ) -> Option<VersionedFullCheckpointContents> {
833 self.rocks
834 .get_full_checkpoint_contents(sequence_number, digest)
835 }
836
837 fn get_unchanged_loaded_runtime_objects(
838 &self,
839 digest: &TransactionDigest,
840 ) -> Option<Vec<ObjectKey>> {
841 self.rocks.get_unchanged_loaded_runtime_objects(digest)
842 }
843
844 fn multi_get_unchanged_loaded_runtime_objects(
845 &self,
846 digests: &[TransactionDigest],
847 ) -> Vec<Option<Vec<ObjectKey>>> {
848 self.rocks
849 .multi_get_unchanged_loaded_runtime_objects(digests)
850 }
851
852 fn get_transaction_checkpoint(
853 &self,
854 digest: &TransactionDigest,
855 ) -> Option<CheckpointSequenceNumber> {
856 self.rocks.get_transaction_checkpoint(digest)
857 }
858}
859
860impl BackingPackageStore for RpcStoreReadStore {
861 fn get_package_object(&self, _package_id: &ObjectID) -> SuiResult<Option<PackageObject>> {
862 Err(SuiErrorKind::UnsupportedFeatureError {
863 error: "RpcStoreReadStore does not support loading package objects".to_string(),
864 }
865 .into())
866 }
867}
868
869impl RuntimeObjectResolver for RpcStoreReadStore {
870 fn read_child_object(
871 &self,
872 parent: &ObjectID,
873 child: &ObjectID,
874 child_version_upper_bound: SequenceNumber,
875 ) -> SuiResult<Option<Object>> {
876 Ok(self.get_object(child).filter(|o| {
877 o.version() <= child_version_upper_bound
878 && o.owner == Owner::ObjectOwner((*parent).into())
879 }))
880 }
881
882 fn get_object_received_at_version(
883 &self,
884 _owner: &ObjectID,
885 _receiving_object_id: &ObjectID,
886 _receive_object_at_version: SequenceNumber,
887 _epoch_id: EpochId,
888 ) -> SuiResult<Option<Object>> {
889 Err(SuiErrorKind::UnsupportedFeatureError {
890 error: "RpcStoreReadStore does not support receiving objects".to_string(),
891 }
892 .into())
893 }
894}
895
896impl RpcStateReader for RpcStoreReadStore {
897 fn get_lowest_available_checkpoint_objects(&self) -> Result<CheckpointSequenceNumber> {
898 let perpetual = self
899 .state
900 .get_object_cache_reader()
901 .get_highest_pruned_checkpoint()
902 .map(|cp| cp + 1)
903 .unwrap_or(0);
904 let rpc_store = self.reader.get_lowest_available_checkpoint_objects()?;
905 Ok(perpetual.max(rpc_store))
906 }
907
908 fn get_chain_identifier(&self) -> Result<sui_types::digests::ChainIdentifier> {
909 Ok(self.state.get_chain_identifier())
910 }
911
912 fn indexes(&self) -> Option<&dyn RpcIndexes> {
913 Some(self)
914 }
915
916 fn get_highest_executed_checkpoint_seq_number(&self) -> Result<CheckpointSequenceNumber> {
917 Ok(*self.rocks.get_latest_checkpoint()?.sequence_number())
922 }
923
924 fn get_struct_layout_with_overlay(
925 &self,
926 struct_tag: &move_core_types::language_storage::StructTag,
927 overlay: &ObjectSet,
928 ) -> Result<Option<move_core_types::annotated_value::MoveTypeLayout>> {
929 let backing_store = self.state.get_backing_package_store();
934 let overlay_store = OverlayBackingPackageStore::new(overlay, backing_store.as_ref());
935 let epoch_store = self.state.load_epoch_store_one_call_per_task();
936 epoch_store
937 .executor()
938 .type_layout_resolver(epoch_store.protocol_config(), Box::new(overlay_store))
939 .get_annotated_layout(struct_tag)
940 .map(|layout| layout.into_layout())
941 .map(Some)
942 .map_err(StorageError::custom)
943 }
944}
945
946impl RpcIndexes for RpcStoreReadStore {
947 fn get_epoch_info(&self, epoch: EpochId) -> Result<Option<sui_types::storage::EpochInfo>> {
948 self.reader.get_epoch_info(epoch)
949 }
950
951 fn owned_objects_iter(
952 &self,
953 owner: SuiAddress,
954 object_type: Option<StructTag>,
955 cursor: Option<OwnedObjectInfo>,
956 ) -> Result<Box<dyn Iterator<Item = Result<OwnedObjectInfo, TypedStoreError>> + '_>> {
957 self.reader.owned_objects_iter(owner, object_type, cursor)
958 }
959
960 fn dynamic_field_iter(
961 &self,
962 parent: ObjectID,
963 cursor: Option<DynamicFieldKey>,
964 ) -> Result<Box<dyn Iterator<Item = Result<DynamicFieldKey, TypedStoreError>> + '_>> {
965 self.reader.dynamic_field_iter(parent, cursor)
966 }
967
968 fn get_coin_info(&self, coin_type: &StructTag) -> Result<Option<CoinInfo>> {
969 self.reader.get_coin_info(coin_type)
970 }
971
972 fn get_balance(
973 &self,
974 owner: &SuiAddress,
975 coin_type: &StructTag,
976 ) -> Result<Option<BalanceInfo>> {
977 self.reader.get_balance(owner, coin_type)
978 }
979
980 fn balance_iter(
981 &self,
982 owner: &SuiAddress,
983 cursor: Option<(SuiAddress, StructTag)>,
984 ) -> Result<BalanceIterator<'_>> {
985 self.reader.balance_iter(owner, cursor)
986 }
987
988 fn package_versions_iter(
989 &self,
990 original_id: ObjectID,
991 cursor: Option<u64>,
992 ) -> Result<Box<dyn Iterator<Item = Result<(u64, ObjectID), TypedStoreError>> + '_>> {
993 self.reader.package_versions_iter(original_id, cursor)
994 }
995
996 fn get_package_version_storage_id(
997 &self,
998 original_id: ObjectID,
999 version: u64,
1000 ) -> Result<Option<ObjectID>> {
1001 self.reader
1002 .get_package_version_storage_id(original_id, version)
1003 }
1004
1005 fn get_package_at_checkpoint(
1006 &self,
1007 original_id: ObjectID,
1008 checkpoint: CheckpointSequenceNumber,
1009 ) -> Result<Option<(u64, ObjectID)>> {
1010 self.reader
1011 .get_package_at_checkpoint(original_id, checkpoint)
1012 }
1013
1014 fn get_highest_indexed_checkpoint_seq_number(
1015 &self,
1016 ) -> Result<Option<CheckpointSequenceNumber>> {
1017 self.reader.get_highest_indexed_checkpoint_seq_number()
1018 }
1019
1020 fn get_highest_live_indexed_checkpoint_seq_number(
1021 &self,
1022 ) -> Result<Option<CheckpointSequenceNumber>> {
1023 self.reader.get_highest_live_indexed_checkpoint_seq_number()
1024 }
1025
1026 fn ledger_tx_seq_digest(&self, tx_seq: u64) -> Result<Option<LedgerTxSeqDigest>> {
1027 self.reader.ledger_tx_seq_digest(tx_seq)
1028 }
1029
1030 fn ledger_tx_seq_digest_multi_get(
1031 &self,
1032 tx_seqs: &[u64],
1033 ) -> Result<Vec<Option<LedgerTxSeqDigest>>> {
1034 self.reader.ledger_tx_seq_digest_multi_get(tx_seqs)
1035 }
1036
1037 fn ledger_tx_seq_digest_iter(
1038 &self,
1039 start: u64,
1040 end_exclusive: u64,
1041 descending: bool,
1042 ) -> Result<LedgerTxSeqDigestIterator<'_>> {
1043 self.reader
1044 .ledger_tx_seq_digest_iter(start, end_exclusive, descending)
1045 }
1046
1047 fn transaction_bitmap_bucket_iter(
1048 &self,
1049 dimension_key: Vec<u8>,
1050 start_bucket: u64,
1051 end_bucket_exclusive: u64,
1052 descending: bool,
1053 ) -> Result<LedgerBitmapBucketIterator<'_>> {
1054 self.reader.transaction_bitmap_bucket_iter(
1055 dimension_key,
1056 start_bucket,
1057 end_bucket_exclusive,
1058 descending,
1059 )
1060 }
1061
1062 fn event_bitmap_bucket_iter(
1063 &self,
1064 dimension_key: Vec<u8>,
1065 start_bucket: u64,
1066 end_bucket_exclusive: u64,
1067 descending: bool,
1068 ) -> Result<LedgerBitmapBucketIterator<'_>> {
1069 self.reader.event_bitmap_bucket_iter(
1070 dimension_key,
1071 start_bucket,
1072 end_bucket_exclusive,
1073 descending,
1074 )
1075 }
1076}