1use crate::authority::AuthorityState;
5use crate::checkpoints::CheckpointStore;
6use crate::epoch::committee_store::CommitteeStore;
7use crate::execution_cache::ExecutionCacheTraitPointers;
8use crate::rpc_index::CoinIndexInfo;
9use crate::rpc_index::OwnerIndexInfo;
10use crate::rpc_index::OwnerIndexKey;
11use crate::rpc_index::RpcIndexStore;
12use move_core_types::language_storage::StructTag;
13use parking_lot::Mutex;
14use std::sync::Arc;
15use sui_types::base_types::ObjectID;
16use sui_types::base_types::SequenceNumber;
17use sui_types::base_types::SuiAddress;
18use sui_types::base_types::TransactionDigest;
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::full_checkpoint_content::ObjectSet;
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::ChildObjectResolver;
36use sui_types::storage::CoinInfo;
37use sui_types::storage::DynamicFieldKey;
38use sui_types::storage::LedgerBitmapBucketIterator;
39use sui_types::storage::LedgerTxSeqDigest;
40use sui_types::storage::LedgerTxSeqDigestIterator;
41use sui_types::storage::ObjectStore;
42use sui_types::storage::OwnedObjectInfo;
43use sui_types::storage::RpcIndexes;
44use sui_types::storage::RpcStateReader;
45use sui_types::storage::WriteStore;
46use sui_types::storage::error::Error as StorageError;
47use sui_types::storage::error::Result;
48use sui_types::storage::{ObjectKey, OverlayBackingPackageStore, ReadStore};
49use sui_types::transaction::VerifiedTransaction;
50use tap::Pipe;
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 get_highest_verified_checkpoint(&self) -> Result<VerifiedCheckpoint, StorageError> {
111 self.checkpoint_store
112 .get_highest_verified_checkpoint()
113 .map(|maybe_checkpoint| {
114 maybe_checkpoint
115 .expect("storage should have been initialized with genesis checkpoint")
116 })
117 .map_err(Into::into)
118 }
119
120 fn get_highest_synced_checkpoint(&self) -> Result<VerifiedCheckpoint, StorageError> {
121 self.checkpoint_store
122 .get_highest_synced_checkpoint()
123 .map(|maybe_checkpoint| {
124 maybe_checkpoint
125 .expect("storage should have been initialized with genesis checkpoint")
126 })
127 .map_err(Into::into)
128 }
129
130 fn get_lowest_available_checkpoint(&self) -> Result<CheckpointSequenceNumber, StorageError> {
131 if let Some(highest_pruned_cp) = self
132 .checkpoint_store
133 .get_highest_pruned_checkpoint_seq_number()
134 .map_err(Into::<StorageError>::into)?
135 {
136 Ok(highest_pruned_cp + 1)
137 } else {
138 Ok(0)
139 }
140 }
141
142 fn get_full_checkpoint_contents(
143 &self,
144 sequence_number: Option<CheckpointSequenceNumber>,
145 digest: &CheckpointContentsDigest,
146 ) -> Option<VersionedFullCheckpointContents> {
147 #[cfg(debug_assertions)]
148 if let Some(sequence_number) = sequence_number {
149 if let Some(loaded_sequence_number) = self
153 .checkpoint_store
154 .get_sequence_number_by_contents_digest(digest)
155 .expect("db error")
156 {
157 assert_eq!(loaded_sequence_number, sequence_number);
158 }
159 }
160
161 let sequence_number = sequence_number.or_else(|| {
162 self.checkpoint_store
163 .get_sequence_number_by_contents_digest(digest)
164 .expect("db error")
165 });
166 if let Some(sequence_number) = sequence_number {
167 if let Ok(Some(contents)) = self
173 .checkpoint_store
174 .get_full_checkpoint_contents_by_sequence_number(sequence_number)
175 .tap_err(|e| {
176 error!(
177 "error getting full checkpoint contents for checkpoint {:?}: {:?}",
178 sequence_number, e
179 )
180 })
181 {
182 return Some(contents);
183 }
184 }
185
186 self.checkpoint_store
192 .get_checkpoint_contents(digest)
193 .expect("db error")
194 .and_then(|contents| {
195 let mut transactions = Vec::with_capacity(contents.size());
196 for tx in contents.iter() {
197 if let (Some(t), Some(e)) = (
198 self.get_transaction(&tx.transaction),
199 self.cache_traits
200 .transaction_cache_reader
201 .get_effects(&tx.effects),
202 ) {
203 transactions.push(sui_types::base_types::ExecutionData::new(
204 (*t).clone().into_inner(),
205 e,
206 ))
207 } else {
208 return None;
209 }
210 }
211 Some(
212 VersionedFullCheckpointContents::from_contents_and_execution_data(
213 contents,
214 transactions.into_iter(),
215 ),
216 )
217 })
218 }
219
220 fn get_committee(&self, epoch: EpochId) -> Option<Arc<Committee>> {
221 self.committee_store.get_committee(&epoch).unwrap()
222 }
223
224 fn get_transaction(&self, digest: &TransactionDigest) -> Option<Arc<VerifiedTransaction>> {
225 self.cache_traits
226 .transaction_cache_reader
227 .get_transaction_block(digest)
228 }
229
230 fn multi_get_transactions(
231 &self,
232 digests: &[TransactionDigest],
233 ) -> Vec<Option<Arc<VerifiedTransaction>>> {
234 self.cache_traits
235 .transaction_cache_reader
236 .multi_get_transaction_blocks(digests)
237 }
238
239 fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects> {
240 self.cache_traits
241 .transaction_cache_reader
242 .get_executed_effects(digest)
243 }
244
245 fn multi_get_transaction_effects(
246 &self,
247 digests: &[TransactionDigest],
248 ) -> Vec<Option<TransactionEffects>> {
249 self.cache_traits
250 .transaction_cache_reader
251 .multi_get_executed_effects(digests)
252 }
253
254 fn get_events(&self, digest: &TransactionDigest) -> Option<TransactionEvents> {
255 self.cache_traits
256 .transaction_cache_reader
257 .get_events(digest)
258 }
259
260 fn multi_get_events(&self, digests: &[TransactionDigest]) -> Vec<Option<TransactionEvents>> {
261 self.cache_traits
262 .transaction_cache_reader
263 .multi_get_events(digests)
264 }
265
266 fn get_unchanged_loaded_runtime_objects(
267 &self,
268 digest: &TransactionDigest,
269 ) -> Option<Vec<ObjectKey>> {
270 self.cache_traits
271 .transaction_cache_reader
272 .get_unchanged_loaded_runtime_objects(digest)
273 }
274
275 fn get_transaction_checkpoint(
276 &self,
277 digest: &TransactionDigest,
278 ) -> Option<CheckpointSequenceNumber> {
279 self.cache_traits
280 .checkpoint_cache
281 .deprecated_get_transaction_checkpoint(digest)
282 .map(|(_epoch, checkpoint)| checkpoint)
283 }
284
285 fn get_latest_checkpoint(&self) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
286 self.checkpoint_store
287 .get_highest_executed_checkpoint()
288 .expect("db error")
289 .ok_or_else(|| {
290 sui_types::storage::error::Error::missing("unable to get latest checkpoint")
291 })
292 }
293
294 fn get_checkpoint_contents_by_digest(
295 &self,
296 digest: &CheckpointContentsDigest,
297 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
298 self.checkpoint_store
299 .get_checkpoint_contents(digest)
300 .expect("db error")
301 }
302
303 fn get_checkpoint_contents_by_sequence_number(
304 &self,
305 sequence_number: CheckpointSequenceNumber,
306 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
307 match self.get_checkpoint_by_sequence_number(sequence_number) {
308 Some(checkpoint) => self.get_checkpoint_contents_by_digest(&checkpoint.content_digest),
309 None => None,
310 }
311 }
312}
313
314impl ObjectStore for RocksDbStore {
315 fn get_object(&self, object_id: &sui_types::base_types::ObjectID) -> Option<Object> {
316 self.cache_traits.object_store.get_object(object_id)
317 }
318
319 fn get_object_by_key(
320 &self,
321 object_id: &sui_types::base_types::ObjectID,
322 version: sui_types::base_types::VersionNumber,
323 ) -> Option<Object> {
324 self.cache_traits
325 .object_store
326 .get_object_by_key(object_id, version)
327 }
328}
329
330impl WriteStore for RocksDbStore {
331 fn insert_checkpoint(
332 &self,
333 checkpoint: &VerifiedCheckpoint,
334 ) -> Result<(), sui_types::storage::error::Error> {
335 if let Some(EndOfEpochData {
336 next_epoch_committee,
337 ..
338 }) = checkpoint.end_of_epoch_data.as_ref()
339 {
340 let next_committee = next_epoch_committee.iter().cloned().collect();
341 let committee =
342 Committee::new(checkpoint.epoch().checked_add(1).unwrap(), next_committee);
343 self.insert_committee(committee)?;
344 }
345
346 self.checkpoint_store
347 .insert_verified_checkpoint(checkpoint)
348 .map_err(Into::into)
349 }
350
351 fn update_highest_synced_checkpoint(
352 &self,
353 checkpoint: &VerifiedCheckpoint,
354 ) -> Result<(), sui_types::storage::error::Error> {
355 let mut locked = self.highest_synced_checkpoint.lock();
356 if locked.is_some() && locked.unwrap() >= checkpoint.sequence_number {
357 return Ok(());
358 }
359 self.checkpoint_store
360 .update_highest_synced_checkpoint(checkpoint)
361 .map_err(sui_types::storage::error::Error::custom)?;
362 *locked = Some(checkpoint.sequence_number);
363 Ok(())
364 }
365
366 fn update_highest_verified_checkpoint(
367 &self,
368 checkpoint: &VerifiedCheckpoint,
369 ) -> Result<(), sui_types::storage::error::Error> {
370 let mut locked = self.highest_verified_checkpoint.lock();
371 if locked.is_some() && locked.unwrap() >= checkpoint.sequence_number {
372 return Ok(());
373 }
374 self.checkpoint_store
375 .update_highest_verified_checkpoint(checkpoint)
376 .map_err(sui_types::storage::error::Error::custom)?;
377 *locked = Some(checkpoint.sequence_number);
378 Ok(())
379 }
380
381 fn insert_checkpoint_contents(
382 &self,
383 checkpoint: &VerifiedCheckpoint,
384 contents: VerifiedCheckpointContents,
385 ) -> Result<(), sui_types::storage::error::Error> {
386 self.cache_traits
387 .state_sync_store
388 .multi_insert_transaction_and_effects(contents.transactions());
389 self.checkpoint_store
390 .insert_verified_checkpoint_contents(checkpoint, contents)
391 .map_err(Into::into)
392 }
393
394 fn insert_committee(
395 &self,
396 new_committee: Committee,
397 ) -> Result<(), sui_types::storage::error::Error> {
398 self.committee_store
399 .insert_new_committee(&new_committee)
400 .unwrap();
401 Ok(())
402 }
403}
404
405pub struct RestReadStore {
406 state: Arc<AuthorityState>,
407 rocks: RocksDbStore,
408}
409
410impl RestReadStore {
411 pub fn new(state: Arc<AuthorityState>, rocks: RocksDbStore) -> Self {
412 Self { state, rocks }
413 }
414
415 fn index(&self) -> sui_types::storage::error::Result<&RpcIndexStore> {
416 self.state
417 .rpc_index
418 .as_deref()
419 .ok_or_else(|| sui_types::storage::error::Error::custom("rest index store is disabled"))
420 }
421}
422
423impl ObjectStore for RestReadStore {
424 fn get_object(&self, object_id: &sui_types::base_types::ObjectID) -> Option<Object> {
425 self.rocks.get_object(object_id)
426 }
427
428 fn get_object_by_key(
429 &self,
430 object_id: &sui_types::base_types::ObjectID,
431 version: sui_types::base_types::VersionNumber,
432 ) -> Option<Object> {
433 self.rocks.get_object_by_key(object_id, version)
434 }
435}
436
437impl ReadStore for RestReadStore {
438 fn get_committee(&self, epoch: EpochId) -> Option<Arc<Committee>> {
439 self.rocks.get_committee(epoch)
440 }
441
442 fn get_latest_checkpoint(&self) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
443 self.rocks.get_latest_checkpoint()
444 }
445
446 fn get_highest_verified_checkpoint(
447 &self,
448 ) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
449 self.rocks.get_highest_verified_checkpoint()
450 }
451
452 fn get_highest_synced_checkpoint(
453 &self,
454 ) -> sui_types::storage::error::Result<VerifiedCheckpoint> {
455 self.rocks.get_highest_synced_checkpoint()
456 }
457
458 fn get_lowest_available_checkpoint(
459 &self,
460 ) -> sui_types::storage::error::Result<CheckpointSequenceNumber> {
461 self.rocks.get_lowest_available_checkpoint()
462 }
463
464 fn get_checkpoint_by_digest(&self, digest: &CheckpointDigest) -> Option<VerifiedCheckpoint> {
465 self.rocks.get_checkpoint_by_digest(digest)
466 }
467
468 fn get_checkpoint_by_sequence_number(
469 &self,
470 sequence_number: CheckpointSequenceNumber,
471 ) -> Option<VerifiedCheckpoint> {
472 self.rocks
473 .get_checkpoint_by_sequence_number(sequence_number)
474 }
475
476 fn get_checkpoint_contents_by_digest(
477 &self,
478 digest: &CheckpointContentsDigest,
479 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
480 self.rocks.get_checkpoint_contents_by_digest(digest)
481 }
482
483 fn get_checkpoint_contents_by_sequence_number(
484 &self,
485 sequence_number: CheckpointSequenceNumber,
486 ) -> Option<sui_types::messages_checkpoint::CheckpointContents> {
487 self.rocks
488 .get_checkpoint_contents_by_sequence_number(sequence_number)
489 }
490
491 fn get_transaction(&self, digest: &TransactionDigest) -> Option<Arc<VerifiedTransaction>> {
492 self.rocks.get_transaction(digest)
493 }
494
495 fn multi_get_transactions(
496 &self,
497 digests: &[TransactionDigest],
498 ) -> Vec<Option<Arc<VerifiedTransaction>>> {
499 self.rocks.multi_get_transactions(digests)
500 }
501
502 fn get_transaction_effects(&self, digest: &TransactionDigest) -> Option<TransactionEffects> {
503 self.rocks.get_transaction_effects(digest)
504 }
505
506 fn multi_get_transaction_effects(
507 &self,
508 digests: &[TransactionDigest],
509 ) -> Vec<Option<TransactionEffects>> {
510 self.rocks.multi_get_transaction_effects(digests)
511 }
512
513 fn get_events(&self, digest: &TransactionDigest) -> Option<TransactionEvents> {
514 self.rocks.get_events(digest)
515 }
516
517 fn multi_get_events(&self, digests: &[TransactionDigest]) -> Vec<Option<TransactionEvents>> {
518 self.rocks.multi_get_events(digests)
519 }
520
521 fn get_full_checkpoint_contents(
522 &self,
523 sequence_number: Option<CheckpointSequenceNumber>,
524 digest: &CheckpointContentsDigest,
525 ) -> Option<VersionedFullCheckpointContents> {
526 self.rocks
527 .get_full_checkpoint_contents(sequence_number, digest)
528 }
529
530 fn get_unchanged_loaded_runtime_objects(
531 &self,
532 digest: &TransactionDigest,
533 ) -> Option<Vec<ObjectKey>> {
534 self.rocks.get_unchanged_loaded_runtime_objects(digest)
535 }
536
537 fn get_transaction_checkpoint(
538 &self,
539 digest: &TransactionDigest,
540 ) -> Option<CheckpointSequenceNumber> {
541 self.rocks.get_transaction_checkpoint(digest)
542 }
543}
544
545impl ChildObjectResolver for RestReadStore {
546 fn read_child_object(
547 &self,
548 parent: &ObjectID,
549 child: &ObjectID,
550 child_version_upper_bound: SequenceNumber,
551 ) -> SuiResult<Option<Object>> {
552 Ok(self.get_object(child).and_then(|o| {
553 if o.version() <= child_version_upper_bound
554 && o.owner == Owner::ObjectOwner((*parent).into())
555 {
556 Some(o)
557 } else {
558 None
559 }
560 }))
561 }
562
563 fn get_object_received_at_version(
564 &self,
565 _owner: &ObjectID,
566 _receiving_object_id: &ObjectID,
567 _receive_object_at_version: SequenceNumber,
568 _epoch_id: EpochId,
569 ) -> SuiResult<Option<Object>> {
570 Err(SuiErrorKind::UnsupportedFeatureError {
571 error: "RestReadStore does not support receiving objects".to_string(),
572 }
573 .into())
574 }
575}
576
577impl RpcStateReader for RestReadStore {
578 fn get_lowest_available_checkpoint_objects(
579 &self,
580 ) -> sui_types::storage::error::Result<CheckpointSequenceNumber> {
581 Ok(self
582 .state
583 .get_object_cache_reader()
584 .get_highest_pruned_checkpoint()
585 .map(|cp| cp + 1)
586 .unwrap_or(0))
587 }
588
589 fn get_chain_identifier(&self) -> Result<sui_types::digests::ChainIdentifier> {
590 Ok(self.state.get_chain_identifier())
591 }
592
593 fn indexes(&self) -> Option<&dyn RpcIndexes> {
594 Some(self)
595 }
596
597 fn get_struct_layout_with_overlay(
598 &self,
599 struct_tag: &move_core_types::language_storage::StructTag,
600 overlay: &ObjectSet,
601 ) -> Result<Option<move_core_types::annotated_value::MoveTypeLayout>> {
602 let backing_store = self.state.get_backing_package_store();
603 let overlay_store = OverlayBackingPackageStore::new(overlay, backing_store.as_ref());
604 let epoch_store = self.state.load_epoch_store_one_call_per_task();
605 epoch_store
606 .executor()
607 .type_layout_resolver(epoch_store.protocol_config(), Box::new(overlay_store))
609 .get_annotated_layout(struct_tag)
610 .map(|layout| layout.into_layout())
611 .map(Some)
612 .map_err(StorageError::custom)
613 }
614}
615
616impl RpcIndexes for RestReadStore {
617 fn get_epoch_info(&self, epoch: EpochId) -> Result<Option<sui_types::storage::EpochInfo>> {
618 self.index()?
619 .get_epoch_info(epoch)
620 .map_err(StorageError::custom)
621 }
622
623 fn owned_objects_iter(
624 &self,
625 owner: SuiAddress,
626 object_type: Option<StructTag>,
627 cursor: Option<OwnedObjectInfo>,
628 ) -> Result<Box<dyn Iterator<Item = Result<OwnedObjectInfo, TypedStoreError>> + '_>> {
629 let cursor = cursor.map(|cursor| OwnerIndexKey {
630 owner: cursor.owner,
631 object_type: cursor.object_type,
632 inverted_balance: cursor.balance.map(std::ops::Not::not),
633 object_id: cursor.object_id,
634 });
635
636 let iter = self
637 .index()?
638 .owner_iter(owner, object_type, cursor)?
639 .map(|result| {
640 result.map(
641 |(
642 OwnerIndexKey {
643 owner,
644 object_id,
645 object_type,
646 inverted_balance,
647 },
648 OwnerIndexInfo { version },
649 )| {
650 OwnedObjectInfo {
651 owner,
652 object_type,
653 balance: inverted_balance.map(std::ops::Not::not),
654 object_id,
655 version,
656 }
657 },
658 )
659 });
660
661 Ok(Box::new(iter) as _)
662 }
663
664 fn dynamic_field_iter(
665 &self,
666 parent: ObjectID,
667 cursor: Option<ObjectID>,
668 ) -> sui_types::storage::error::Result<
669 Box<dyn Iterator<Item = Result<DynamicFieldKey, TypedStoreError>> + '_>,
670 > {
671 let iter = self.index()?.dynamic_field_iter(parent, cursor)?;
672 Ok(Box::new(iter) as _)
673 }
674
675 fn get_coin_info(
676 &self,
677 coin_type: &StructTag,
678 ) -> sui_types::storage::error::Result<Option<CoinInfo>> {
679 self.index()?
680 .get_coin_info(coin_type)?
681 .map(
682 |CoinIndexInfo {
683 coin_metadata_object_id,
684 treasury_object_id,
685 regulated_coin_metadata_object_id,
686 }| CoinInfo {
687 coin_metadata_object_id,
688 treasury_object_id,
689 regulated_coin_metadata_object_id,
690 },
691 )
692 .pipe(Ok)
693 }
694
695 fn get_balance(
696 &self,
697 owner: &SuiAddress,
698 coin_type: &StructTag,
699 ) -> sui_types::storage::error::Result<Option<BalanceInfo>> {
700 self.index()?
701 .get_balance(owner, coin_type)?
702 .map(|info| info.into())
703 .pipe(Ok)
704 }
705
706 fn balance_iter(
707 &self,
708 owner: &SuiAddress,
709 cursor: Option<(SuiAddress, StructTag)>,
710 ) -> sui_types::storage::error::Result<BalanceIterator<'_>> {
711 let cursor_key =
712 cursor.map(|(owner, coin_type)| crate::rpc_index::BalanceKey { owner, coin_type });
713
714 Ok(Box::new(
715 self.index()?
716 .balance_iter(*owner, cursor_key)?
717 .map(|result| {
718 result
719 .map(|(key, info)| (key.coin_type, info.into()))
720 .map_err(Into::into)
721 }),
722 ))
723 }
724
725 fn package_versions_iter(
726 &self,
727 original_id: ObjectID,
728 cursor: Option<u64>,
729 ) -> sui_types::storage::error::Result<
730 Box<dyn Iterator<Item = Result<(u64, ObjectID), TypedStoreError>> + '_>,
731 > {
732 let iter = self.index()?.package_versions_iter(original_id, cursor)?;
733 Ok(
734 Box::new(iter.map(|result| result.map(|(key, info)| (key.version, info.storage_id))))
735 as _,
736 )
737 }
738
739 fn get_highest_indexed_checkpoint_seq_number(
740 &self,
741 ) -> sui_types::storage::error::Result<Option<CheckpointSequenceNumber>> {
742 self.index()?
743 .get_highest_indexed_checkpoint_seq_number()
744 .map_err(Into::into)
745 }
746
747 fn ledger_tx_seq_digest(&self, tx_seq: u64) -> Result<Option<LedgerTxSeqDigest>> {
748 self.index()?
749 .ledger_tx_seq_digest(tx_seq)
750 .map_err(Into::into)
751 }
752
753 fn ledger_tx_seq_digest_multi_get(
754 &self,
755 tx_seqs: &[u64],
756 ) -> Result<Vec<Option<LedgerTxSeqDigest>>> {
757 self.index()?
758 .ledger_tx_seq_digest_multi_get(tx_seqs)
759 .map_err(Into::into)
760 }
761
762 fn ledger_tx_seq_digest_iter(
763 &self,
764 start: u64,
765 end_exclusive: u64,
766 descending: bool,
767 ) -> Result<LedgerTxSeqDigestIterator<'_>> {
768 self.index()?
769 .ledger_tx_seq_digest_iter(start, end_exclusive, descending)
770 .map_err(Into::into)
771 }
772
773 fn transaction_bitmap_bucket_iter(
774 &self,
775 dimension_key: Vec<u8>,
776 start_bucket: u64,
777 end_bucket_exclusive: u64,
778 descending: bool,
779 ) -> Result<LedgerBitmapBucketIterator<'_>> {
780 self.index()?
781 .transaction_bitmap_bucket_iter(
782 dimension_key,
783 start_bucket,
784 end_bucket_exclusive,
785 descending,
786 )
787 .map_err(Into::into)
788 }
789
790 fn event_bitmap_bucket_iter(
791 &self,
792 dimension_key: Vec<u8>,
793 start_bucket: u64,
794 end_bucket_exclusive: u64,
795 descending: bool,
796 ) -> Result<LedgerBitmapBucketIterator<'_>> {
797 self.index()?
798 .event_bitmap_bucket_iter(
799 dimension_key,
800 start_bucket,
801 end_bucket_exclusive,
802 descending,
803 )
804 .map_err(Into::into)
805 }
806}