---
# System prepended metadata

title: EPF Cohort 3 Dev Update 5 (pavignol)

---

# EPF Cohort 3 Dev Update 5 (pavignol)

Here are the Prysm validator features that I’ve been working on last week:

## Added a REST API implementation for Validator's `GetBeaconBlock`

During my previous update, I talked about how implementing `ProposeBeaconBlock` was a big change (although not very complex) because generics in Go are not as powerful yet as the equivalent in other languages (e.g. templates in C++). But little did I know that `GetBeaconBlock` was going to be worse.

`GetBeaconBlock` is the endpoint that validators query when they want the beacon node to produce a valid, non-signed block and send it to them. The validator then signs the block and calls `ProposeBeaconBlock` to broadcast the signed block to the beacon network. Both endpoints are very similar at first glance since they both deal with similar structures, but the additional complexity in `GetBeaconBlock` is caused by the need to validate every single field that the beacon node returns.

Every single integer and hex-encoded string needs to be validated before it gets converted to an integer or bytes to make sure that we don't panic and can gracefully fail when interacting with a buggy or non-compliant beacon node. `ProposeBeaconBlock` didn't have this problem since it's a `POST` endpoint that doesn't return any data, so the only data that we deal with is data that we already verified is valid internally.

So, in addition to the same complexity of converting between `JSON` and `protobuf` structs that we had to deal with `ProposeBeaconBlock`, the implementation of `GetBeaconBlock` is full of statements that look like the following:

```go
blockProposerIndex, err := strconv.ParseUint(block.ProposerIndex, 10, 64)
if err != nil {
    return nil, errors.Wrapf(err, "failed to parse proposer index `%s`", block.ProposerIndex)
}

parentRoot, err := hexutil.Decode(block.ParentRoot)
if err != nil {
    return nil, errors.Wrapf(err, "failed to decode parent root `%s`", block.ParentRoot)
}
```

This code can look repetitive and is never fun to write, but it is necessary in order to have a robust validator implementation that doesn't randomly crash and that can output helpful error messages to the user when it fails.

But the implementation is not the only place where `GetBeaconBlock` is more complex than `ProposeBeaconBlock`; tests are also more complex for the same reason. Whereas `ProposeBeaconBlock` doesn't need to test for any potential failures after sending the `POST` request, `GetBeaconBlock` needs to make sure that every potential bad output doesn't cause a panic and outputs the expected error message.

Luckily, [table-driven tests](https://dave.cheney.net/2019/05/07/prefer-table-driven-tests) take some of the pain away. My approach here was to have a function that generates a valid output, and then each test case would change a single field at a time by putting an invalid value and making sure that we get the expected error message.

If you're interested to see what this change looks like, you can look at the [PR](https://github.com/prysmaticlabs/prysm/pull/11772).

## Added a REST API implementation for Validator's `PrepareBeaconProposer` and `ProposeExit`

`PrepareBeaconProposer` and `ProposeExit` are the complete opposite of `GetBeaconBlock` and `ProposeBeaconBlock`. Indeed, those APIs deal with a very small amount of data and the mapping between the beacon API and the protobuf structs is pretty much 1 to 1. Also, there's absolutely no validation aside from handling a bad HTTP response, so the tests are also very straightforward. I was able to implement both endpoints and their tests within an hour, including running the E2E tests. There's not a lot more to say about those endpoints, but feel free to check out the [PrepareBeaconProposer PR](https://github.com/prysmaticlabs/prysm/pull/11784) and the [ProposeExit PR](https://github.com/prysmaticlabs/prysm/pull/11785).