# Dev Update #9
Hello,
Since my [last update](https://hackmd.io/@kevinbogner/dev-update-8), I opened a [draft PR](https://github.com/sigp/lighthouse/pull/3790) for the `sync_committee_rewards`, which is still our primary focus. We all realized that the implementation is *more complex than initially anticipated*. Today, I will break down the challenges we are facing in a *non-technical way*. Explaining our obstacles is a good exercise for me to make sure I understand the concept and is also helpful for people not involved in the topic to understand it better.
We mainly discovered the following issues that need to be solved:
- [using the correct *state*](#State),
- [selecting the right *validators*](#Validators), and
- [handling *edge-cases*](#Edge-cases).
Next, I want to dig deeper into each of these obstacles.
## State
To calculate the rewards accurately, we want to select the proper *state*. The state of Ethereum is an extensive data set containing accounts and balances and a machine state. EVM specifies a ruleset that defines that the state gets changed from block to block.[^1]
*Technically* for the calculation, we should use the state from *before* the block is applied, so the *pre-state*. However, the `compute_sync_aggregate_rewards()` function that we use for calculation only changes on the epoch boundary (when `slot % 32 == 0`). So we will get the *same result* for using *pre-block* and *post-block states*. Therefore we will use the post-state because the implementation is more straightforward.
This concept took us some time and explanation from sproul to fully understand.
## Validators
Another challenge is getting the validators (`validator_index`) that participated in the sync committee. Their job as a validator is to sign every beacon chain header.[^2] That's why we need to check if the validator *voted correctly* by getting the `participation_bit`. If this is the case (`participation_bit == true`), the validator is eligible to get `sync_committee_rewards`; else (`participation_bit == false`), they could get penalized.
## Edge-cases
There are also some edge cases that require special treatment. If a validator gets penalized while already having a balance of 0, the `decrease_balance()` function *shouldn't result in a negative validator balance*. Additionally, validators can be in a sync committee multiple times while receiving different rewards and penalties.
Sproul suggests the following algorithm to cover both edge cases:
```rust
let mut balances = committee_indices.iter().map(|i| (i, state.balances[i])).collect::<HashMap<usize, u64>>();
let mut total_proposer_rewards = 0;
// 1. Apply rewards while keeping track of balance updates exactly as the spec does.
for (validator_index, participant_bit) in committee_indices.zip(sync_aggregate.sync_committee_bits) {
let participant_balance = balances.get_mut(validator_index);
if participant_bit {
// Increase participant balance
*participant_balance += participant_reward;
// Increase proposer balance
*balances.get_mut(proposer_index) += proposer_reward_per_bit;
total_proposer_rewards += proposer_rewards_per_bit;
} else {
// Decrease participant balance
*participant_balance = participant_balance.saturating_sub(participant_reward);
}
}
// Work out the total balance diff for each validator.
let rewards = balances.iter().map(|i, new_balance| {
let reward = if i != proposer_index {
new_balance as i64 - state.balances[i] as i64
} else {
new_balance as i64 - states.balances[i] as i64 - total_proposer_rewards
};
ValidatorReward {
validator_index: i,
reward
}
}).collect();
```
## Next
I'm confident we will cover these obstacles until my next development update. However, until then, some work needs to be done.
[^1]: [Ethereum Virtual Machine (ethereum.org)](https://ethereum.org/en/developers/docs/evm/#:~:text=Ethereum's%20state%20is%20a%20large,are%20defined%20by%20the%20EVM.)
[^2]: [Modelling the Impact of Altair (pintail)](https://pintail.xyz/posts/modelling-the-impact-of-altair/#sync-committees)