# `EEVM.Block.Requests`
[🔗](https://github.com/mw2000/eevm/blob/v0.1.0/lib/eevm/block/requests.ex#L1)

EIP-7685 execution-layer requests: the typed messages a block passes to the
consensus layer from Prague on, and the header's `requests_hash` that
commits to them.

A request is a type byte followed by its payload. A block's requests are,
in type order and leaving out every type whose payload is empty:

| Type | EIP | Payload |
|------|-----|---------|
| `0x00` | EIP-6110 | Every `DepositEvent` the deposit contract logged in the block's receipts, each as `pubkey ++ withdrawal_credentials ++ amount ++ signature ++ index` |
| `0x01` | EIP-7002 | The output of the end-of-block system call to the withdrawal request contract `0x00000961Ef480Eb55e80D19ad83579A64c007002` |
| `0x02` | EIP-7251 | The output of the end-of-block system call to the consolidation request contract `0x0000BBdDc7CE488642fb579F8B00f3a590007251` |

`EEVM.Block.execute/4` collects them after the block's withdrawals, returns
them as `EEVM.Block.Result` `requests`, and checks the header's
`requests_hash` against `hash/1`; `EEVM.Block.build/4` fills it in.

# `error`

```elixir
@type error() ::
  :invalid_deposit_event_layout
  | :system_contract_empty
  | :system_contract_call_failed
```

Why request collection failed; each makes the block invalid.

# `request`

```elixir
@type request() :: binary()
```

A type byte followed by the request payload.

# `collect`

```elixir
@spec collect(
  EEVM.Database.t(),
  EEVM.BlockEnv.t(),
  [EEVM.Block.Receipt.t()],
  EEVM.Config.t(),
  non_neg_integer()
) :: {:ok, [request()], EEVM.Database.t()} | {:error, error()}
```

Collects a block's requests once its transactions and withdrawals have
been applied to `db`.

Deposits are read from `receipts` (logs of `deposit_contract` whose first
topic is the `DepositEvent` signature). The withdrawal and consolidation
request contracts are then called in that order, and their storage changes
are kept in the returned database.

Returns `{:ok, requests, db}`, or `{:error, reason}` when a deposit log
isn't laid out as the EIP-6110 `DepositEvent`
(`:invalid_deposit_event_layout`), a request contract has no code
(`:system_contract_empty`), or its call fails
(`:system_contract_call_failed`). Each makes the block invalid.

# `hash`

```elixir
@spec hash([request()]) :: &lt;&lt;_::256&gt;&gt;
```

Returns the EIP-7685 `requests_hash` of `requests`:
`sha256(sha256(request_0) ++ sha256(request_1) ++ ...)`.

## Example

    iex> EEVM.Block.Requests.hash([]) |> EEVM.hex()
    "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

# `mainnet_deposit_contract`

```elixir
@spec mainnet_deposit_contract() :: non_neg_integer()
```

Returns the mainnet EIP-6110 deposit contract address, the default `:deposit_contract_address`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
