# Week 8
Hi everyone, Rupam here. This week I moved forward with the next step on our roadmap for implementing light client support in Prysm, which is adding corresponding `full_node.md` changes from Capella and Deneb. This is a pretty long and complicated task and I've started with implementing a function to calculate field roots of the `BeaconBlockBody` struct in Prysm.
## Implementation
The `BeaconBlockBody` struct in Prysm looks like this:
```go
type BeaconBlockBody struct {
version int
randaoReveal [field_params.BLSSignatureLength]byte
eth1Data *eth.Eth1Data
graffiti [field_params.RootLength]byte
proposerSlashings []*eth.ProposerSlashing
attesterSlashings []*eth.AttesterSlashing
attesterSlashingsElectra []*eth.AttesterSlashingElectra
attestations []*eth.Attestation
attestationsElectra []*eth.AttestationElectra
deposits []*eth.Deposit
voluntaryExits []*eth.SignedVoluntaryExit
syncAggregate *eth.SyncAggregate
executionPayload interfaces.ExecutionData
executionPayloadHeader interfaces.ExecutionData
blsToExecutionChanges []*eth.SignedBLSToExecutionChange
blobKzgCommitments [][]byte
}
```
Depending on the fork version, the number of fields changes like:
* 8 for Phase0
* 9 for Altair
* 10 for Bellatrix
* 11 for Capella
* 12 for Deneb
* 12 for Electra
The implementation of the field root calculating function should be in a way so that it can calculate field roots irrespective of the fork.
The first step to make then would be this:
```go
var fieldRoots [][]byte
switch blockBody.version {
version.Phase0:
fieldRoots = make([][]byte, 8)
case version.Altair:
fieldRoots = make([][]byte, 9)
case version.Bellatrix:
fieldRoots = make([][]byte, 10)
case version.Capella:
fieldRoots = make([][]byte, 11)
case version.Deneb:
fieldRoots = make([][]byte, 12)
case version.Electra:
fieldRoots = make([][]byte, 12)
default:
return nil, fmt.Errorf("unknown block body version %s", version.String(blockBody.version))
}
```
This makes sure that the number of fields changes according to the fork.
Now take into account fields like `attesterSlashingsElectra` and `attestationsElectra` which are particular to only Electra and newer forks. They can be tackled the following way:
```go
if blockBody.version < version.Electra {
attesterSlashingsRoot, err := ssz.SliceRoot(blockBody.attesterSlashings, field_params.MaxAttesterSlashings)
if err != nil {
return nil, errors.Wrap(err, "could not compute attester slashings merkleization")
}
fieldRoots[4] = attesterSlashingsRoot[:]
} else {
attesterSlashingsElectraRoot, err := ssz.SliceRoot(blockBody.attesterSlashingsElectra, field_params.MaxAttesterSlashingsElectra)
if err != nil {
return nil, errors.Wrap(err, "could not compute attester slashings electra merkleization")
}
fieldRoots[4] = attesterSlashingsElectraRoot[:]
}
```
Since `attesterSlashings` will only be used for forks older than Electra and `attesterSlashingsElectra` will only be used for Electra and newer forks, we add a simple `if-else` statement which checks for the fork version and populates the `fieldRoots` list accordingly.
This week I managed to do it upto the `voluntaryExits` field. Next week I will probably be wrapping this up and moving forward with the next steps.
You can find my PR here: https://github.com/prysmaticlabs/prysm/pull/14278