diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 00b3ec449e6eb0..2d0c312a34f7f4 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -3516,7 +3516,25 @@ fn find_slot_meta_in_cached_state<'a>( } } -// Chaining based on latest discussion here: https://github.com/solana-labs/solana/pull/2253 +/// For each entry in `working_set` whose `did_insert_occur` is true, this +/// function handles its chaining effect by updating the SlotMeta of both +/// the slot and its parent slot to reflect the slot descends from the +/// parent slot. In addition, when a slot is newly connected, it also +/// checks whether any of its direct and indirect children slots are connected +/// or not. +/// +/// This function may update column families [`cf::SlotMeta`] and +/// [`cf::Orphans`]. +/// +/// For more information about the chaining, check the previous discussion here: +/// https://github.com/solana-labs/solana/pull/2253 +/// +/// Arguments: +/// - `db`: the blockstore db that stores both shreds and their metadata. +/// - `write_batch`: the write batch which includes all the updates of the +/// the current write and ensures their atomicity. +/// - `working_set`: a slot-id to SlotMetaWorkingSetEntry map. This function +/// will remove all entries which insertion did not actually occur. fn handle_chaining( db: &Database, write_batch: &mut WriteBatch, @@ -3538,6 +3556,34 @@ fn handle_chaining( Ok(()) } +/// A helper function of handle_chaining which handles the chaining based +/// on the `SlotMetaWorkingSetEntry` of the specified `slot`. Specifically, +/// it handles the following two things: +/// +/// 1. based on the `SlotMetaWorkingSetEntry` for `slot`, check if `slot` +/// did not previously have a parent slot but does now. If `slot` satisfies +/// this condition, update the Orphan property of both `slot` and its parent +/// slot based on their current orphan status. Specifically: +/// - updates the orphan property of slot to no longer be an orphan because +/// it has a parent. +/// - adds the parent to the orphan column family if the parent's parent is +/// currently unknown. +/// +/// 2. if the `SlotMetaWorkingSetEntry` for `slot` indicates this slot +/// is newly connected to a parent slot, then this function will update +/// the is_connected property of all its direct and indirect children slots. +/// +/// This function may update column family [`cf::Orphans`] and indirectly +/// update SlotMeta from its output parameter `new_chained_slots`. +/// +/// Arguments: +/// `db`: the underlying db for blockstore +/// `write_batch`: the write batch which includes all the updates of the +/// the current write and ensures their atomicity. +/// `working_set`: the working set which include the specified `slot` +/// `new_chained_slots`: an output parameter which includes all the slots +/// which connectivity have been updated. +/// `slot`: the slot which we want to handle its chaining effect. fn handle_chaining_for_slot( db: &Database, write_batch: &mut WriteBatch, @@ -3620,12 +3666,26 @@ fn handle_chaining_for_slot( Ok(()) } +/// Traverse all the direct and indirect children slots and apply the specified +/// `slot_function`. +/// +/// Arguments: +/// `db`: the blockstore db that stores shreds and their metadata. +/// `slot`: starting slot to traverse. +/// `slot_meta`: the SlotMeta of the above `slot`. +/// `working_set`: a slot-id to SlotMetaWorkingSetEntry map which is used +/// to traverse the graph. +/// `passed_visisted_slots`: all the traversed slots which have passed the +/// slot_function. This may also include the input `slot`. +/// `slot_function`: a function which updates the SlotMeta of the visisted +/// slots and determine whether to further traverse the children slots of +/// a given slot. fn traverse_children_mut( db: &Database, slot: Slot, slot_meta: &Rc>, working_set: &HashMap, - new_chained_slots: &mut HashMap>>, + passed_visisted_slots: &mut HashMap>>, slot_function: F, ) -> Result<()> where @@ -3641,7 +3701,7 @@ where let next_slot = find_slot_meta_else_create( db, working_set, - new_chained_slots, + passed_visisted_slots, *next_slot_index, )?; next_slots.push((*next_slot_index, next_slot));