# BLK-004: `BlockGeneratorResult` Structure

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

---

## Summary

BLK-004 defines the structure of `BlockGeneratorResult`, the return type of `build_block_generator()`. This struct MUST contain seven fields: `generator` (the compressed CLVM block program), `block_refs` (heights of referenced previous block generators), `aggregated_signature` (BLS aggregate of all included bundle signatures), `additions` (coins created), `removals` (coins spent), `cost` (total CLVM cost), and `bundles_included` (count of bundles that fit within the cost budget).

The structure mirrors Chia L1's `NewBlockGenerator` at [`generator_types.py:28`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/generator_types.py#L28), extended with additional fields that dig-clvm needs for its block-building workflow. On L1, `NewBlockGenerator` carries the generator program and block references; dig-clvm adds `additions`, `removals`, `cost`, and `bundles_included` so the caller has a complete picture of the block's contents without needing a separate validation pass.

The `BlockGeneratorResult` serves as the bridge between block construction ([BLK-001](BLK-001.md)) and block validation ([BLK-006](BLK-006.md)). The `generator` field can be passed directly to `validate_block()` for round-trip verification, and the `aggregated_signature` is included in the block header. The `additions` and `removals` allow the caller to update its UTXO state immediately after building the block.

---

## Specification

### Struct Definition

```rust
pub struct BlockGeneratorResult {
    /// The compressed block-level CLVM program produced by
    /// solution_generator_backrefs(). Contains all spends with
    /// CLVM back-references for deduplication.
    pub generator: BlockGenerator,

    /// Block heights of referenced previous generators for cross-block
    /// back-references. Mirrors L1's NewBlockGenerator.block_refs.
    /// May be empty if no cross-block references are used.
    pub block_refs: Vec<u32>,

    /// Aggregated BLS signature across all included bundles.
    /// Computed per BLK-005.
    pub aggregated_signature: Signature,

    /// Coins created by all included spends (CREATE_COIN conditions).
    pub additions: Vec<Coin>,

    /// Coins spent by all included spends (the input coins).
    pub removals: Vec<Coin>,

    /// Total CLVM cost of all included spends.
    pub cost: Cost,

    /// Number of bundles included (may be less than input length
    /// if the cost limit was reached). See BLK-002.
    pub bundles_included: usize,
}
```

### Field Specifications

| Field | Type | Description | Constraint |
|-------|------|-------------|------------|
| `generator` | `BlockGenerator` | Compressed CLVM block program from `solution_generator_backrefs()` | MUST be executable by `run_block_generator2()` |
| `block_refs` | `Vec<u32>` | Heights of previous blocks whose generators are referenced | MUST be sorted ascending; may be empty |
| `aggregated_signature` | `Signature` | BLS aggregate of included bundle signatures | MUST equal `bls_aggregate(bundle.sig for bundle in included)` per [BLK-005](BLK-005.md) |
| `additions` | `Vec<Coin>` | New coins created by `CREATE_COIN` conditions | Union of additions from all included bundles |
| `removals` | `Vec<Coin>` | Coins consumed (spent) by included bundles | Union of removals from all included bundles |
| `cost` | `Cost` (`u64`) | Total CLVM execution cost | `cost <= max_cost` (the budget passed to `build_block_generator()`) |
| `bundles_included` | `usize` | Count of bundles that fit | `0 <= bundles_included <= bundles.len()` |

### Invariants

1. `additions` MUST contain exactly the coins produced by `CREATE_COIN` conditions across all included spends.
2. `removals` MUST contain exactly the coins being spent by all included bundles.
3. `cost` MUST equal the sum of CLVM execution costs for all included bundles.
4. `bundles_included` MUST equal the number of bundles whose spends appear in the generator.
5. `generator` MUST be the output of `solution_generator_backrefs()` as required by [BLK-003](BLK-003.md).
6. `aggregated_signature` MUST satisfy the BLS aggregation rule in [BLK-005](BLK-005.md).

### L1 Correspondence

| dig-clvm Field | L1 `NewBlockGenerator` Field | Source |
|----------------|------------------------------|--------|
| `generator` | `program` | [`generator_types.py:28`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/generator_types.py#L28) |
| `block_refs` | `block_refs` | [`generator_types.py:28`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/generator_types.py#L28) |
| `aggregated_signature` | Aggregated separately in block header | L1 block header |
| `additions` | Computed by `tx_removals_and_additions()` | [`generator_tools.py:54`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/generator_tools.py#L54) |
| `removals` | Computed by `tx_removals_and_additions()` | [`generator_tools.py:54`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/generator_tools.py#L54) |
| `cost` | Part of `SpendBundleConditions` | `chia-consensus` |
| `bundles_included` | Implicit in L1 (all items that fit) | [`mempool.py:505`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool.py#L505) |

---

## Acceptance Criteria

- [ ] `BlockGeneratorResult` struct compiles with all seven fields matching the exact types specified
- [ ] `generator` field is of type `BlockGenerator` (from `chia_consensus::run_block_generator`)
- [ ] `aggregated_signature` field is of type `Signature` (from `chia-bls`)
- [ ] `additions` and `removals` are `Vec<Coin>` (from `chia-protocol`)
- [ ] After building from N bundles where M fit, `bundles_included == M` and `cost <= max_cost`
- [ ] The `additions` in the result match the union of `CREATE_COIN` outputs from the M included bundles

---

## Implementation Notes

- The `BlockGenerator` type is re-exported from `chia_consensus::run_block_generator::BlockGenerator` as specified in [SPEC.md Section 5](../../../../resources/SPEC.md).
- The `Signature` type comes from `chia-bls`. It represents a BLS12-381 G2 point.
- The `Coin` type comes from `chia-protocol` and contains `parent_coin_info`, `puzzle_hash`, and `amount`.
- The `block_refs` field supports cross-block back-references where a generator in the current block references puzzle bytecodes from a previous block's generator. For DIG's initial implementation, this may always be empty. When cross-block references are used, the corresponding generator data must be passed to `validate_block()` as `generator_refs`.
- The `bundles_included` field allows the caller to know how many bundles from the mempool were actually included, enabling it to remove those bundles from the mempool after the block is committed.

---

## Verification

### Test Plan

| Test Case | Input | Expected Outcome |
|-----------|-------|------------------|
| All fields present | Build from one bundle | Result has all 7 fields populated, `bundles_included == 1` |
| Cost accuracy | Build from bundles with known costs | `result.cost` equals sum of individual costs |
| Additions correctness | Build from bundle creating coins A, B | `result.additions` contains exactly A, B |
| Removals correctness | Build from bundle spending coins X, Y | `result.removals` contains exactly X, Y |
| Partial inclusion | 3 bundles, only 2 fit | `bundles_included == 2`, additions/removals from only those 2 |
| Generator type | Build any block | `result.generator` is `BlockGenerator` (compile-time enforced) |

### Verification Method

- **Unit test**: Build a block from known bundles with predictable additions, removals, and costs. Assert each field of `BlockGeneratorResult` matches expectations.
- **Compile-time check**: The struct field types are enforced by the Rust compiler. Any type mismatch will be caught at compile time.

---

## Source Citations

- L1 `NewBlockGenerator`: [`generator_types.py:28`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/generator_types.py#L28)
- L1 `BlockGenerator`: [`generator_types.py:15`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/generator_types.py#L15)
- L1 additions/removals extraction: [`generator_tools.py:54`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/generator_tools.py#L54)
- dig-clvm SPEC.md struct definition: [SPEC.md Section 5](../../../../resources/SPEC.md)

---

## References

- [BLK-001](BLK-001.md) — `build_block_generator` entry point (returns this struct)
- [BLK-002](BLK-002.md) — Cost-aware bundle iteration (determines `bundles_included`)
- [BLK-003](BLK-003.md) — `solution_generator_backrefs` (produces `generator`)
- [BLK-005](BLK-005.md) — Aggregated signature (populates `aggregated_signature`)
- [BLK-006](BLK-006.md) — `validate_block` (consumes `generator` from this struct)
- [BLK-009](BLK-009.md) — Round-trip consistency (validates against this struct's contents)
