3737 solana_account:: ReadableAccount ,
3838 solana_address_lookup_table_interface:: state:: AddressLookupTable ,
3939 solana_clock:: { Slot , UnixTimestamp , DEFAULT_TICKS_PER_SECOND } ,
40- solana_entry:: entry:: { create_ticks, Entry , MaxDataShredsLen } ,
40+ solana_entry:: {
41+ block_component:: BlockComponent ,
42+ entry:: { create_ticks, Entry , MaxDataShredsLen } ,
43+ } ,
4144 solana_genesis_config:: { GenesisConfig , DEFAULT_GENESIS_ARCHIVE , DEFAULT_GENESIS_FILE } ,
4245 solana_hash:: Hash ,
4346 solana_keypair:: Keypair ,
@@ -3523,14 +3526,13 @@ impl Blockstore {
35233526 . map ( |x| x. 0 )
35243527 }
35253528
3526- /// Returns the entry vector for the slot starting with `shred_start_index`, the number of
3527- /// shreds that comprise the entry vector, and whether the slot is full (consumed all shreds).
3528- pub fn get_slot_entries_with_shred_info (
3529+ /// Helper function that contains the common logic for getting slot data with shred info
3530+ fn get_slot_data_with_shred_info_common (
35293531 & self ,
35303532 slot : Slot ,
35313533 start_index : u64 ,
35323534 allow_dead_slots : bool ,
3533- ) -> Result < ( Vec < Entry > , u64 , bool ) > {
3535+ ) -> Result < Option < ( CompletedRanges , SlotMeta , u64 ) > > {
35343536 let ( completed_ranges, slot_meta) = self . get_completed_ranges ( slot, start_index) ?;
35353537
35363538 // Check if the slot is dead *after* fetching completed ranges to avoid a race
@@ -3540,7 +3542,7 @@ impl Blockstore {
35403542 if self . is_dead ( slot) && !allow_dead_slots {
35413543 return Err ( BlockstoreError :: DeadSlot ) ;
35423544 } else if completed_ranges. is_empty ( ) {
3543- return Ok ( ( vec ! [ ] , 0 , false ) ) ;
3545+ return Ok ( None ) ;
35443546 }
35453547
35463548 let slot_meta = slot_meta. unwrap ( ) ;
@@ -3549,10 +3551,48 @@ impl Blockstore {
35493551 . map ( |& Range { end, .. } | u64:: from ( end) - start_index)
35503552 . unwrap_or ( 0 ) ;
35513553
3552- let entries = self . get_slot_entries_in_block ( slot, completed_ranges, Some ( & slot_meta) ) ?;
3554+ Ok ( Some ( ( completed_ranges, slot_meta, num_shreds) ) )
3555+ }
3556+
3557+ /// Returns the entry vector for the slot starting with `shred_start_index`, the number of
3558+ /// shreds that comprise the entry vector, and whether the slot is full (consumed all shreds).
3559+ pub fn get_slot_entries_with_shred_info (
3560+ & self ,
3561+ slot : Slot ,
3562+ start_index : u64 ,
3563+ allow_dead_slots : bool ,
3564+ ) -> Result < ( Vec < Entry > , u64 , bool ) > {
3565+ let Some ( ( completed_ranges, slot_meta, num_shreds) ) =
3566+ self . get_slot_data_with_shred_info_common ( slot, start_index, allow_dead_slots) ?
3567+ else {
3568+ return Ok ( ( vec ! [ ] , 0 , false ) ) ;
3569+ } ;
3570+
3571+ let entries = self . get_slot_entries_in_block ( slot, & completed_ranges, Some ( & slot_meta) ) ?;
35533572 Ok ( ( entries, num_shreds, slot_meta. is_full ( ) ) )
35543573 }
35553574
3575+ /// Returns the components vector for the slot starting with `shred_start_index`, the number of
3576+ /// shreds that comprise the components vector, and whether the slot is full (consumed all
3577+ /// shreds).
3578+ pub fn get_slot_components_with_shred_info (
3579+ & self ,
3580+ slot : Slot ,
3581+ start_index : u64 ,
3582+ allow_dead_slots : bool ,
3583+ ) -> Result < ( Vec < BlockComponent > , Vec < Range < u32 > > , bool ) > {
3584+ let Some ( ( completed_ranges, slot_meta, _) ) =
3585+ self . get_slot_data_with_shred_info_common ( slot, start_index, allow_dead_slots) ?
3586+ else {
3587+ return Ok ( ( vec ! [ ] , vec ! [ ] , false ) ) ;
3588+ } ;
3589+
3590+ let components =
3591+ self . get_slot_components_in_block ( slot, & completed_ranges, Some ( & slot_meta) ) ?;
3592+ debug_assert_eq ! ( completed_ranges. len( ) , components. len( ) ) ;
3593+ Ok ( ( components, completed_ranges, slot_meta. is_full ( ) ) )
3594+ }
3595+
35563596 /// Gets accounts used in transactions in the slot range [starting_slot, ending_slot].
35573597 /// Additionally returns a bool indicating if the set may be incomplete.
35583598 /// Used by ledger-tool to create a minimized snapshot
@@ -3656,18 +3696,19 @@ impl Blockstore {
36563696 . collect ( )
36573697 }
36583698
3659- /// Fetch the entries corresponding to all of the shred indices in `completed_ranges`
3699+ /// Fetch the data corresponding to all of the shred indices in `completed_ranges`
36603700 /// This function takes advantage of the fact that `completed_ranges` are both
36613701 /// contiguous and in sorted order. To clarify, suppose completed_ranges is as follows:
36623702 /// completed_ranges = [..., (s_i..e_i), (s_i+1..e_i+1), ...]
36633703 /// Then, the following statements are true:
36643704 /// s_i < e_i == s_i+1 < e_i+1
3665- fn get_slot_entries_in_block (
3705+ fn get_slot_data_in_block < T > (
36663706 & self ,
36673707 slot : Slot ,
3668- completed_ranges : CompletedRanges ,
3708+ completed_ranges : & CompletedRanges ,
36693709 slot_meta : Option < & SlotMeta > ,
3670- ) -> Result < Vec < Entry > > {
3710+ mut deserialize : impl FnMut ( Vec < u8 > ) -> Result < Vec < T > > ,
3711+ ) -> Result < Vec < T > > {
36713712 debug_assert ! ( completed_ranges
36723713 . iter( )
36733714 . tuple_windows( )
@@ -3698,7 +3739,7 @@ impl Blockstore {
36983739 } )
36993740 } ) ;
37003741 completed_ranges
3701- . into_iter ( )
3742+ . iter ( )
37023743 . map ( |Range { start, end } | end - start)
37033744 . map ( |num_shreds| {
37043745 shreds
@@ -3707,28 +3748,57 @@ impl Blockstore {
37073748 . process_results ( |shreds| Shredder :: deshred ( shreds) ) ?
37083749 . map_err ( |e| {
37093750 BlockstoreError :: InvalidShredData ( Box :: new ( bincode:: ErrorKind :: Custom (
3710- format ! ( "could not reconstruct entries buffer from shreds: {e:?}" ) ,
3751+ format ! ( "could not reconstruct data buffer from shreds: {e:?}" ) ,
37113752 ) ) )
37123753 } )
3713- . and_then ( |payload| {
3714- <WincodeVec < Entry , MaxDataShredsLen > >:: deserialize ( & payload) . map_err ( |e| {
3715- BlockstoreError :: InvalidShredData ( Box :: new ( bincode:: ErrorKind :: Custom (
3716- format ! ( "could not reconstruct entries: {e:?}" ) ,
3717- ) ) )
3718- } )
3719- } )
3754+ . and_then ( & mut deserialize)
37203755 } )
37213756 . flatten_ok ( )
37223757 . collect ( )
37233758 }
37243759
3760+ /// Fetch the components corresponding to all of the shred indices in `completed_ranges`.
3761+ /// Note that one range in CompletedRanges corresponds to one BlockComponent.
3762+ fn get_slot_components_in_block (
3763+ & self ,
3764+ slot : Slot ,
3765+ completed_ranges : & CompletedRanges ,
3766+ slot_meta : Option < & SlotMeta > ,
3767+ ) -> Result < Vec < BlockComponent > > {
3768+ self . get_slot_data_in_block ( slot, completed_ranges, slot_meta, |payload| {
3769+ wincode:: deserialize ( & payload)
3770+ . map ( |component| vec ! [ component] )
3771+ . map_err ( |e| {
3772+ BlockstoreError :: InvalidShredData ( Box :: new ( bincode:: ErrorKind :: Custom (
3773+ format ! ( "could not reconstruct block component: {e:?}" ) ,
3774+ ) ) )
3775+ } )
3776+ } )
3777+ }
3778+
3779+ /// Fetch the entries corresponding to all of the shred indices in `completed_ranges`.
3780+ fn get_slot_entries_in_block (
3781+ & self ,
3782+ slot : Slot ,
3783+ completed_ranges : & CompletedRanges ,
3784+ slot_meta : Option < & SlotMeta > ,
3785+ ) -> Result < Vec < Entry > > {
3786+ self . get_slot_data_in_block ( slot, completed_ranges, slot_meta, |payload| {
3787+ <WincodeVec < Entry , MaxDataShredsLen > >:: deserialize ( & payload) . map_err ( |e| {
3788+ BlockstoreError :: InvalidShredData ( Box :: new ( bincode:: ErrorKind :: Custom ( format ! (
3789+ "could not reconstruct entries: {e:?}"
3790+ ) ) ) )
3791+ } )
3792+ } )
3793+ }
3794+
37253795 pub fn get_entries_in_data_block (
37263796 & self ,
37273797 slot : Slot ,
37283798 range : Range < u32 > ,
37293799 slot_meta : Option < & SlotMeta > ,
37303800 ) -> Result < Vec < Entry > > {
3731- self . get_slot_entries_in_block ( slot, vec ! [ range] , slot_meta)
3801+ self . get_slot_entries_in_block ( slot, & vec ! [ range] , slot_meta)
37323802 }
37333803
37343804 /// Performs checks on the last fec set of a replayed slot, and returns the block_id.
0 commit comments