# TYP-007: StorageStats Struct

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

---

## Summary

StorageStats provides a snapshot of the block store's contents and dimensions, used for monitoring, diagnostics, and API responses.

---

## Specification

```rust
/// Statistics about the contents and size of the block store.
///
/// Returned by `BlockStore::stats()` for monitoring and diagnostics.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct StorageStats {
    /// Total number of blocks stored (all chains, including forks).
    pub block_count: u64,

    /// Number of blocks in the canonical chain.
    pub canonical_block_count: u64,

    /// Total number of headers stored.
    pub header_count: u64,

    /// Total number of checkpoints stored.
    pub checkpoint_count: u64,

    /// Total number of attested blocks stored.
    pub attested_count: u64,

    /// Height of the current chain tip, or None if the store is empty.
    pub tip_height: Option<u64>,

    /// Minimum retained block height, or None if no pruning has occurred.
    pub min_height: Option<u64>,

    /// Total approximate size on disk in bytes.
    pub total_size_bytes: u64,
}
```

### Default Values

When derived via `Default`:

| Field | Default |
|-------|---------|
| `block_count` | `0` |
| `canonical_block_count` | `0` |
| `header_count` | `0` |
| `checkpoint_count` | `0` |
| `attested_count` | `0` |
| `tip_height` | `None` |
| `min_height` | `None` |
| `total_size_bytes` | `0` |

### Usage

```rust
impl BlockStore {
    /// Compute current storage statistics by querying RocksDB metadata.
    pub fn stats(&self) -> Result<StorageStats, BlockStoreError> {
        // Count entries in each column family
        // Read tip and min_height from CF_METADATA
        // Estimate total_size_bytes from RocksDB properties
    }
}
```

---

## Acceptance Criteria

- [x] `StorageStats` has all 8 fields as specified
- [x] `StorageStats` derives `Debug`, `Clone`, `Default`, `PartialEq`, `Eq`
- [x] `StorageStats::default()` has all counts set to 0
- [x] `StorageStats::default()` has `tip_height` and `min_height` as `None`
- [x] `StorageStats::default()` has `total_size_bytes` set to 0
- [x] Individual fields can be set and read correctly
- [x] Can be used without a RocksDB instance (pure data struct)

---

## Implementation Notes

- Define in `src/types/storage_stats.rs`.
- This is a pure data struct with no methods beyond what `Default` provides.
- `BlockStore::stats()` (defined in the block_storage domain) populates this struct.
- `total_size_bytes` can be estimated via RocksDB's `GetAggregatedIntProperty("rocksdb.estimate-live-data-size")`.

---

## Test Plan

| Test Name | Type | Description |
|-----------|------|-------------|
| `test_default_counts_zero` | unit | `StorageStats::default()` has all count fields == 0 |
| `test_default_tip_height_none` | unit | `StorageStats::default().tip_height` is None |
| `test_default_min_height_none` | unit | `StorageStats::default().min_height` is None |
| `test_default_size_zero` | unit | `StorageStats::default().total_size_bytes` == 0 |
| `test_set_and_read_fields` | unit | Construct with specific values, verify each field |
| `test_clone_equality` | unit | Clone a stats struct, assert == original |
| `test_debug_format` | unit | Format with `{:?}`, verify no panic |

---

## Expected Test Files

- `tests/typ_007_tests.rs`
