# Week 5
Hi everyone, this week I wasn't able to attend EthCC at Brussels due to Visa issues and I had a few blockers in my PRs which only Mr. Radek would be able to solve. Due to him being present at EthCC, he wasn't able to reply much except a few things here and there. One was to add relevant tests to the ``is_better_update`` PR I opened last week.
## Implementation and Testing of the ``is_better_update`` function
Reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#is_better_update
My implementation in Prysm:
```go
func IsBetterUpdate(newUpdate, oldUpdate *ethpbv2.LightClientUpdate) bool {
maxActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Len()
newNumActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Count()
oldNumActiveParticipants := oldUpdate.SyncAggregate.SyncCommitteeBits.Count()
newHasSupermajority := newNumActiveParticipants*3 >= maxActiveParticipants*2
oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2
if newHasSupermajority != oldHasSupermajority {
return newHasSupermajority
}
if !newHasSupermajority && newNumActiveParticipants != oldNumActiveParticipants {
return newNumActiveParticipants > oldNumActiveParticipants
}
// Compare presence of relevant sync committee
newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.AttestedHeader.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot)))
oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.AttestedHeader.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot)))
if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee {
return newHasRelevantSyncCommittee
}
// Compare indication of any finality
newHasFinality := IsFinalityUpdate(newUpdate)
oldHasFinality := IsFinalityUpdate(oldUpdate)
if newHasFinality != oldHasFinality {
return newHasFinality
}
// Compare sync committee finality
if newHasFinality {
newHasSyncCommitteeFinality := slots.ToEpoch(newUpdate.FinalizedHeader.Slot) == slots.ToEpoch(newUpdate.AttestedHeader.Slot)
oldHasSyncCommitteeFinality := slots.ToEpoch(oldUpdate.FinalizedHeader.Slot) == slots.ToEpoch(oldUpdate.AttestedHeader.Slot)
if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality {
return newHasSyncCommitteeFinality
}
}
// Tiebreaker 1: Sync committee participation beyond supermajority
if newNumActiveParticipants != oldNumActiveParticipants {
return newNumActiveParticipants > oldNumActiveParticipants
}
// Tiebreaker 2: Prefer older data (fewer changes to best)
if newUpdate.AttestedHeader.Slot != oldUpdate.AttestedHeader.Slot {
return newUpdate.AttestedHeader.Slot < oldUpdate.AttestedHeader.Slot
}
return newUpdate.SignatureSlot < oldUpdate.SignatureSlot
}
```
This implementation requires 2 other much smaller helper functions `is_sync_committee_update` and `is_finality_update` which I had to implement too.
Reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#is_sync_committee_update
```go
func IsSyncCommitteeUpdate(update *ethpbv2.LightClientUpdate) bool {
nextSyncCommitteeBranch := make([][]byte, fieldparams.NextSyncCommitteeBranchDepth)
return !reflect.DeepEqual(update.NextSyncCommitteeBranch, nextSyncCommitteeBranch)
}
```
Reference: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#is_finality_update
```go
func IsFinalityUpdate(update *ethpbv2.LightClientUpdate) bool {
finalityBranch := make([][]byte, blockchain.FinalityBranchNumOfLeaves)
return !reflect.DeepEqual(update.FinalityBranch, finalityBranch)
}
```
Now coming to the implementation of `is_better_update` , each return statement inside an `if` requires 2 tests, one which satisfies the condition of the `if` statement and another that doesn't.
I have setup the functions required to run the tests and have written one test which satisfies the condition of the following `if` statement:
```go
if newHasSupermajority != oldHasSupermajority {
return newHasSupermajority
}
```
Right now, there are some issues in the test as it is failing. Mr Radek is yet to review it. Once I figure out the fix I'll be updating the code here too. Also I didn't link the functions used to setup the test as it would make this document too big but you can find them [here](https://github.com/rupam-04/prysm/blob/7d9a99c83f5020adbf6a9ea032d0ead53cff9703/beacon-chain/rpc/eth/light-client/helpers_test.go#L19-#L260).