# BLS-001: Optional BlsCache Parameter on Validation Functions

> **Authoritative requirement:** [BLS-001](../NORMATIVE.md#BLS-001)
> **Verification:** [VERIFICATION.md](../VERIFICATION.md)
> **Tracking:** [TRACKING.yaml](../TRACKING.yaml)
> **Spec reference:** [SPEC.md](../../../../resources/SPEC.md) — Section 5.1

---

## Summary

Both `validate_spend_bundle()` and `validate_block()` must accept an `Option<&mut BlsCache>` parameter that controls BLS signature caching behavior during validation. This parameter is the primary integration point for the BLS cache subsystem within `dig-clvm`. When the caller provides `Some(&mut cache)`, verified BLS12-381 signature pairings are stored in the cache and reused on subsequent calls, avoiding redundant cryptographic verification. When the caller provides `None`, all signature verification proceeds from scratch with no caching.

This design mirrors the Chia L1 architecture where the mempool manager maintains a `BlsCache` instance across validation calls. On L1, `pre_validate_spendbundle()` at [`mempool_manager.py:428`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool_manager.py#L428) passes a cache through `validate_clvm_and_signature()` at [`:445`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool_manager.py#L445), and block validation at [`multiprocess_validation.py:62`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L62) can reuse cached pairings. The `Option` wrapper gives callers full control: validators maintaining a mempool pass `Some`, while one-off validation tasks pass `None`.

The `&mut BlsCache` reference ensures the cache is updated in place, accumulating verified pairings across calls without requiring the caller to manage return values. This is critical for the mempool-to-block reuse pattern described in [BLS-003](BLS-003.md) and the correctness invariant in [BLS-005](BLS-005.md).

---

## Specification

### Function Signatures

Both public validation entry points must include the `bls_cache` parameter:

```rust
use chia_bls::BlsCache;

/// Validate a spend bundle against L2 consensus rules.
pub fn validate_spend_bundle(
    bundle: &SpendBundle,
    context: &ValidationContext,
    config: &ValidationConfig,
    bls_cache: Option<&mut BlsCache>,  // <-- required parameter
) -> Result<SpendResult, ValidationError>;

/// Validate a block generator and return combined additions + removals.
pub fn validate_block(
    generator: &BlockGenerator,
    generator_refs: &[Vec<u8>],
    context: &ValidationContext,
    config: &ValidationConfig,
    bls_cache: Option<&mut BlsCache>,  // <-- required parameter
) -> Result<SpendResult, ValidationError>;
```

### Cache Behavior on `Some`

When `bls_cache` is `Some(&mut cache)`:

1. Before verifying each BLS pairing `(public_key, message, signature)`, check the cache for a matching entry.
2. If the pairing is cached and valid, skip cryptographic verification and count it as verified.
3. If the pairing is not cached, perform full BLS12-381 verification via `chia-bls`.
4. On successful verification, insert the pairing into the cache for future reuse.
5. The mutable reference ensures the cache is updated in place across calls.

### Cache Behavior on `None`

When `bls_cache` is `None`:

1. All BLS pairings are verified from scratch using `chia-bls`.
2. No caching state is created, maintained, or returned.
3. The validation result must be identical to the `Some` path (per [BLS-005](BLS-005.md)).

### Internal Delegation

The `bls_cache` parameter must be threaded through to the underlying `chia-consensus` functions that perform BLS verification. The `BlsCache` type from `chia-bls` is designed to be passed into these functions directly.

---

## Acceptance Criteria

- [ ] `validate_spend_bundle()` compiles and accepts `Option<&mut BlsCache>` as its fourth parameter
- [ ] `validate_block()` compiles and accepts `Option<&mut BlsCache>` as its fifth parameter
- [ ] Calling `validate_spend_bundle()` with `Some(&mut BlsCache::default())` succeeds for a valid bundle
- [ ] Calling `validate_block()` with `Some(&mut BlsCache::default())` succeeds for a valid block generator
- [ ] The `BlsCache` instance is mutated (contains entries) after a successful `Some` validation call
- [ ] Both functions are publicly exported from the crate root

---

## Implementation Notes

- The `BlsCache` type must be imported from `chia-bls`, not custom-defined (see [BLS-004](BLS-004.md)).
- The `Option` wrapper is chosen over a default parameter because Rust does not support default arguments, and `Option` makes the caller's intent explicit.
- The `&mut` reference is required rather than ownership because the caller typically retains the cache across multiple calls (mempool-to-block reuse pattern).
- Thread safety: `BlsCache` is not `Send` or `Sync`. If concurrent validation is needed, the caller is responsible for synchronization (e.g., `Mutex<BlsCache>`).

---

## Verification

### Test Plan

1. **Compilation test**: Verify both functions compile with the `Option<&mut BlsCache>` parameter by writing a test that calls each with both `Some` and `None`.

2. **Unit test -- Some path**:
   - Create a `BlsCache::default()`.
   - Construct a valid `SpendBundle` using `chia-sdk-test::Simulator`.
   - Call `validate_spend_bundle()` with `Some(&mut cache)`.
   - Assert the result is `Ok(SpendResult { .. })`.
   - Assert the cache is non-empty after the call (at least one pairing cached).

3. **Unit test -- None path**:
   - Construct the same valid `SpendBundle`.
   - Call `validate_spend_bundle()` with `None`.
   - Assert the result is `Ok(SpendResult { .. })`.
   - Assert the result matches the `Some` path result exactly.

4. **Block validation test**:
   - Build a block generator from validated bundles.
   - Call `validate_block()` with `Some(&mut BlsCache::default())`.
   - Assert success and cache population.

5. **API surface test**:
   - Verify both functions are accessible from an external crate via `dig_clvm::validate_spend_bundle` and `dig_clvm::validate_block`.

### Expected Test Files

- `tests/cache_tests.rs` -- BLS-001 compilation and basic cache parameter tests

---

## Source Citations

- Chia L1 mempool validation: [`mempool_manager.py:428-445`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool_manager.py#L428)
- Chia L1 block validation: [`multiprocess_validation.py:62`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L62)
- `BlsCache` type: [`chia-bls` crate](https://crates.io/crates/chia-bls)
- dig-clvm public API: [SPEC.md Section 5.1](../../../../resources/SPEC.md)

---

## References

- [BLS-002](BLS-002.md) -- None cache works correctly (complementary behavior)
- [BLS-003](BLS-003.md) -- Mempool-to-block reuse (primary use case for `Some` path)
- [BLS-004](BLS-004.md) -- Uses `chia-bls::BlsCache` directly (type constraint)
- [BLS-005](BLS-005.md) -- Cache does not affect correctness (invariant)
