Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

Fix getting validators map for local relay #20

Merged
merged 10 commits into from
Dec 20, 2022
Merged

Fix getting validators map for local relay #20

merged 10 commits into from
Dec 20, 2022

Conversation

avalonche
Copy link
Contributor

📝 Summary

Previously the local relay used the onForkChoice hook to update the validator mapping. However now that the hook is unused, the builder does not update the mapping when the local relay option is enabled.

📚 References


builder/beacon_client.go Outdated Show resolved Hide resolved
builder/beacon_client.go Outdated Show resolved Hide resolved
builder/config.go Outdated Show resolved Hide resolved
if nextSlotEpoch != b.currentEpoch {
nextSlotEpoch := nextSlot / b.slotsInEpoch
// if slot at half epoch, fetch next epoch's proposers
if nextSlotEpoch != b.currentEpoch || nextSlot%b.slotsInEpoch == b.slotsInEpoch/2 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking through this, this won't work if there is no validator registered at the mid-epoch slot (won't be called for that slot)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can do this the same way the boost relay does it - have a go routine that updates the validator map in the background while subscribed to the head block

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, should work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the remote relay uses the same logic

builder/builder/relay.go

Lines 100 to 108 in 6b30dbb

if r.lastRequestedSlot == 0 || nextSlot/32 > r.lastRequestedSlot/32 {
// Every epoch request validators map
go func() {
err := r.updateValidatorsMap(nextSlot, 1)
if err != nil {
log.Error("could not update validators map", "err", err)
}
}()
}
did we see any corner cases around the epoch change?

builder/local_relay.go Show resolved Hide resolved
b.mu.Lock()
defer b.mu.Unlock()

if b.currentSlot+1 != requestedSlot {
return PubkeyHex(""), errors.New("slot out of sync")
if (requestedSlot / b.slotsInEpoch) > b.currentEpoch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, since b.currentEpoch is set elsewhere, calling this function twice with the same requestedSlot (which is possible) causes currEpochProposerMap to be cycled twice which might be incorrect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't really understand how it'll be cycled twice if b.currentEpoch is strictly increasing. Could you give an example?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call it twice in a row with the same requestedSlot and the asignment to currEpochProposerMap will happen twice as currentEpoch is not set in this function

builder/beacon_client.go Show resolved Hide resolved
builder/beacon_client.go Outdated Show resolved Hide resolved
builder/beacon_client.go Outdated Show resolved Hide resolved
builder/beacon_client.go Outdated Show resolved Hide resolved
timer := time.NewTicker(durationPerEpoch / 2)
for {
select {
case <-timer.C:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the ticker tick straight away? To trigger it right away (and not wait) you could set it to zero initially.
Or factor out the update routine to a function and call it before the ticker loop for initial setup (and it's okay to wait if it fails to connect).

}

currentEpoch := currentSlot / b.slotsInEpoch
if currentEpoch > b.currentEpoch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's actually a race for b.currentEpoch between this loop and onForkchoiceUpdate
I wonder if just keeping a most up to date slot proposer map instead of two copies would solve most if not all of those issues.
The slot proposer map contains slots from this and the next epochs, so you have a whole epoch of runway to update it (if that fails, there are bigger issues than the builder).
Instead of keeping nextEpochProposerMap and currEpochProposerMap you could just keep currEpochProposerMap up to date in this loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onForkchoiceUpdate is not used anymore, hence the PR. We should remove it.

@Ruteri Ruteri mentioned this pull request Dec 19, 2022
@avalonche avalonche merged commit c3c62dd into main Dec 20, 2022
avalonche added a commit that referenced this pull request Feb 7, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
avalonche added a commit that referenced this pull request Mar 9, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
avalonche added a commit that referenced this pull request Mar 15, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
avalonche added a commit that referenced this pull request Mar 17, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
avalonche added a commit that referenced this pull request Mar 22, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
avalonche added a commit that referenced this pull request Jul 6, 2023
* Fix getting validators map for local relay

* pr comments

* add timer for updating known validators

* improvement to local validator map fetching

* lock for map updating

* properly lock updates

* get current slot if the mapping is empty

* remove onForkchoiceUpdate

* graceful shutdown

* Split initial proposer sync from the proposer fetch loop (#28)

Co-authored-by: Mateusz Morusiewicz <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants