# BLK-007: Delegates to `run_block_generator2`

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

---

## Summary

BLK-007 requires that `validate_block()` MUST delegate generator execution to `chia_consensus::run_block_generator2()`, matching Chia L1's post-hard-fork execution path. This function is the Rust implementation that L1 calls at [`multiprocess_validation.py:69`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L69) via `chia_rs`. dig-clvm MUST NOT implement its own generator execution logic.

On Chia L1, there are two generator execution functions: `run_block_generator()` (pre-hard-fork, used for historical blocks) and `run_block_generator2()` (post-hard-fork, used for new blocks). DIG uses `fork_height=0`, meaning all blocks use the post-hard-fork rules from genesis. Therefore, dig-clvm exclusively uses `run_block_generator2()` and never needs `run_block_generator()`. This simplification is safe because DIG has no legacy blocks that predate the hard fork.

By delegating to `chia_consensus::run_block_generator2()`, dig-clvm achieves parity with L1 by construction. The function handles CLVM execution, back-reference resolution, condition extraction, and cost accounting. It accepts the generator program, generator references for cross-block back-references, the maximum cost budget, and execution flags, and returns `SpendBundleConditions` containing all conditions produced by the spends in the block. dig-clvm then applies additional validation checks per [BLK-008](BLK-008.md).

---

## Specification

### Required Delegation

```rust
// Inside validate_block(), the generator execution MUST be:
let conditions = run_block_generator2(
    &mut allocator,
    generator.program.as_ref(),
    &generator_refs_data,
    config.max_cost,
    flags,
)?;
```

### `run_block_generator2` Behavior

The function from `chia-consensus`:

1. **Deserializes** the generator program into the CLVM allocator
2. **Resolves back-references** using `generator_refs` data from previous blocks
3. **Executes** the CLVM program, which produces a list of spend outputs
4. **Extracts conditions** from each spend output (CREATE_COIN, AGG_SIG_*, time locks, etc.)
5. **Tracks cost** for all CLVM operations, failing if `max_cost` is exceeded
6. **Returns** `SpendBundleConditions` containing all spends, conditions, and total cost

### DIG-Specific: `fork_height = 0`

DIG always operates in post-hard-fork mode:

```rust
// DIG uses fork_height=0, so we always use run_block_generator2
// (never run_block_generator which is for pre-fork blocks)
let flags = DONT_VALIDATE_SIGNATURE_FLAG  // if configured
    | MEMPOOL_MODE_FLAG;                   // if mempool validation
```

This means:
- All blocks use `run_block_generator2()` rules from the very first block
- No need to check fork height or switch between generator versions
- No need to support the pre-fork `run_block_generator()` function

### Behavioral Rules

1. **Delegation required**: `validate_block()` MUST call `run_block_generator2()` from `chia-consensus`. No hand-rolled CLVM execution, condition parsing, or cost tracking is permitted for the generator execution step.

2. **Post-hard-fork only**: `run_block_generator2()` (not `run_block_generator()`) MUST be used for all blocks. DIG has no pre-fork blocks.

3. **Cost passthrough**: The `max_cost` from `ValidationConfig` MUST be passed through to `run_block_generator2()`.

4. **Flags passthrough**: Execution flags (e.g., `MEMPOOL_MODE`, `DONT_VALIDATE_SIGNATURE`) from `ValidationConfig.flags` MUST be passed through to `run_block_generator2()`.

5. **Error propagation**: Errors from `run_block_generator2()` (cost exceeded, invalid CLVM, etc.) MUST be propagated as `ValidationError` variants.

### L1 Correspondence

| dig-clvm | Chia L1 | Source |
|----------|---------|--------|
| `run_block_generator2()` call | `run_block_generator2()` call | [`multiprocess_validation.py:69`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L69) |
| Always post-fork | Conditional on `fork_height` | [`multiprocess_validation.py:62-72`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L62) |
| `chia-consensus` crate | `chia_rs` Python binding | [`multiprocess_validation.py:20-21`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L20) |

---

## Acceptance Criteria

- [ ] `validate_block()` calls `run_block_generator2()` from `chia-consensus` (verified by code review / grep)
- [ ] No hand-rolled CLVM execution exists in `validate_block()`
- [ ] `run_block_generator()` (pre-fork version) is never called anywhere in dig-clvm
- [ ] Cost limit from `ValidationConfig` is correctly passed to `run_block_generator2()`
- [ ] Execution flags from `ValidationConfig` are correctly passed to `run_block_generator2()`
- [ ] Errors from `run_block_generator2()` are wrapped in `ValidationError` and returned

---

## Implementation Notes

- `run_block_generator2()` is imported from `chia_consensus::run_block_generator`. On L1, this same Rust function is called via `chia_rs` Python bindings at `multiprocess_validation.py:69`.
- The function returns `SpendBundleConditions`, which contains all spend conditions, total cost, and aggregation information. This is the same type returned by `run_spendbundle()` in Path A.
- DIG's `fork_height=0` simplification means we can hardcode the use of `run_block_generator2()`. On L1, there's a conditional: `if height >= fork_height: run_block_generator2() else: run_block_generator()`. DIG skips this conditional entirely.
- The `Allocator` needed by `run_block_generator2()` should be created locally within `validate_block()` and not shared across calls. Each validation gets a fresh allocator.

---

## Verification

### Test Plan

| Test Case | Input | Expected Outcome |
|-----------|-------|------------------|
| Code review | Source of `validate_block()` | Contains call to `run_block_generator2()` |
| No pre-fork function | Full codebase grep | `run_block_generator()` (v1) is never called |
| Cost passthrough | Generator exceeding config.max_cost | `Err(ValidationError::CostExceeded)` |
| Flag passthrough | `MEMPOOL_MODE` flag set | Generator execution uses mempool rules (stricter) |
| Valid execution | Generator from `build_block_generator()` | Returns `Ok(SpendResult)` with correct conditions |
| Invalid CLVM | Malformed generator bytes | Returns `Err(ValidationError)` wrapping the CLVM error |

### Verification Method

- **Code review**: Grep the `validate_block()` implementation for `run_block_generator2`. Confirm no alternative generator execution exists (no `run_program`, no `run_block_generator` v1).
- **Unit test**: Build a generator via `build_block_generator()`, pass it to `validate_block()`. Assert the result matches expected conditions.
- **Cost enforcement test**: Build a generator, then validate it with a `max_cost` lower than the generator's actual cost. Assert `CostExceeded` error.

---

## Source Citations

- Chia L1 `run_block_generator2()` call: [`multiprocess_validation.py:69`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L69)
- Chia L1 `_run_block()` (fork height check): [`multiprocess_validation.py:62`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L62)
- `run_block_generator2` import: [`multiprocess_validation.py:20-21`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/multiprocess_validation.py#L20)

---

## References

- [BLK-006](BLK-006.md) — `validate_block` entry point (calls this function)
- [BLK-008](BLK-008.md) — Additional validation checks applied after generator execution
- [BLK-003](BLK-003.md) — `solution_generator_backrefs` (produces the generator executed here)
- [SPEC.md Section 2.1](../../../../resources/SPEC.md) — `clvmr` runtime (underlying CLVM execution)
- [SPEC.md Section 6](../../../../resources/SPEC.md) — Path B flow diagram
