# BLK-014: Get Blocks in Range (`get_blocks_in_range`)

| Link | Path |
|------|------|
| **Normative** | [NORMATIVE.md](../NORMATIVE.md) |
| **Verification** | [VERIFICATION.md](../VERIFICATION.md) |
| **Tracking** | [TRACKING.yaml](../TRACKING.yaml) |
| **Spec** | [SPEC.md](../../../../resources/SPEC.md) Section 5.3, 15.3 |

---

## Summary

`get_blocks_in_range(&self, start_height: u64, end_height: u64) -> Result<Vec<L2Block>>` retrieves canonical blocks in a height range with inclusive bounds on both ends. Returns blocks in ascending height order.

---

## Specification

```rust
/// Retrieves canonical blocks in a height range [start, end] inclusive.
/// Returns blocks in height order.
pub fn get_blocks_in_range(
    &self,
    start_height: u64,
    end_height: u64,
) -> Result<Vec<L2Block>> {
    if start_height > end_height {
        return Ok(Vec::new());
    }

    let mut blocks = Vec::with_capacity((end_height - start_height + 1) as usize);
    for height in start_height..=end_height {
        if let Some(block) = self.get_block_by_height(height)? {
            blocks.push(block);
        }
    }
    Ok(blocks)
}
```

### Semantics

- **Inclusive range**: Both `start_height` and `end_height` are included.
- **Empty range**: If `start_height > end_height`, returns an empty `Vec` (not an error).
- **Missing heights**: Heights with no canonical entry are silently skipped.
- **Height validation**: Heights beyond the current tip simply have no canonical entry and are skipped.
- **Order**: Blocks are returned in ascending height order.

---

## Acceptance Criteria

- [ ] Returns blocks in `[start_height, end_height]` inclusive
- [ ] Returns blocks in ascending height order
- [ ] Returns empty vec when `start_height > end_height`
- [ ] Skips heights with no canonical entry
- [ ] Heights beyond tip are handled gracefully (no error)
- [ ] Each block is fully deserialized and decompressed

---

## Test Plan

| Test Name | Type | Description |
|-----------|------|-------------|
| `test_blocks_in_range_basic` | unit | Store blocks 0-9, request range 3-7, verify 5 blocks returned in order |
| `test_blocks_in_range_empty` | unit | Request range 7-3 (inverted), verify empty vec |
| `test_blocks_in_range_full` | unit | Request range 0-9 for 10-block chain, verify all 10 returned |
| `test_blocks_in_range_beyond_tip` | unit | Request range 0-20 for 10-block chain, verify only 10 blocks returned |
| `test_blocks_in_range_single` | unit | Request range 5-5, verify single block returned |

---

## Expected Test Files

- `tests/blk_014_tests.rs`
