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