def _get_blocks_at_height( blocks: BlockchainInterface, prev_b: BlockRecord, target_height: uint32, max_num_blocks: uint32 = uint32(1), ) -> List[BlockRecord]: """ Return a consecutive list of BlockRecords starting at target_height, returning a maximum of max_num_blocks. Assumes all block records are present. Does a slot linear search, if the blocks are not in the path of the peak. Can only fetch ancestors of prev_b. Args: blocks: dict from header hash to BlockRecord. prev_b: prev_b (to start backwards search). target_height: target block to start max_num_blocks: max number of blocks to fetch (although less might be fetched) """ if blocks.contains_height(prev_b.height): header_hash = blocks.height_to_hash(prev_b.height) if header_hash == prev_b.header_hash: # Efficient fetching, since we are fetching ancestor blocks within the heaviest chain. We can directly # use the height_to_block_record method block_list: List[BlockRecord] = [] for h in range(target_height, target_height + max_num_blocks): assert blocks.contains_height(uint32(h)) block_list.append(blocks.height_to_block_record(uint32(h))) return block_list # Slow fetching, goes back one by one, since we are in a fork curr_b: BlockRecord = prev_b target_blocks = [] while curr_b.height >= target_height: if curr_b.height < target_height + max_num_blocks: target_blocks.append(curr_b) if curr_b.height == 0: break curr_b = blocks.block_record(curr_b.prev_hash) return list(reversed(target_blocks))
def _get_blocks_at_height( sub_blocks: BlockchainInterface, prev_sb: SubBlockRecord, target_height: uint32, max_num_sub_blocks: uint32 = uint32(1), ) -> List[SubBlockRecord]: """ Return a consecutive list of SubBlockRecords starting at target_height, returning a maximum of max_num_sub_blocks. Assumes all sub-block records are present. Does a slot linear search, if the sub-blocks are not in the path of the peak. Args: sub_blocks: dict from header hash to SubBlockRecord. prev_sb: prev_sb (to start backwards search). target_height: target sub-block to start max_num_sub_blocks: max number of sub-blocks to fetch (although less might be fetched) """ if sub_blocks.contains_height(prev_sb.height): header_hash = sub_blocks.height_to_hash(prev_sb.height) if header_hash == prev_sb.header_hash: # Efficient fetching, since we are fetching ancestor blocks within the heaviest chain block_list: List[SubBlockRecord] = [] for h in range(target_height, target_height + max_num_sub_blocks): assert sub_blocks.contains_height(uint32(h)) block_list.append( sub_blocks.height_to_sub_block_record(uint32(h))) return block_list # slow fetching, goes back one by one curr_b: SubBlockRecord = prev_sb target_blocks = [] while curr_b.height >= target_height: if curr_b.height < target_height + max_num_sub_blocks: target_blocks.append(curr_b) if curr_b.height == 0: break curr_b = sub_blocks.sub_block_record(curr_b.prev_hash) return list(reversed(target_blocks))