Skip to content

Commit

Permalink
p2p/discover: schedule revalidation also when all nodes are excluded (e…
Browse files Browse the repository at this point in the history
…thereum#30239)

## Issue

If `nextTime` has passed, but all nodes are excluded, `get` would return
`nil` and `run` would therefore not invoke `schedule`. Then, we schedule
a timer for the past, as neither `nextTime` value has been updated. This
creates a busy loop, as the timer immediately returns.

## Fix

With this PR, revalidation will be also rescheduled when all nodes are
excluded.

---------

Co-authored-by: lightclient <lightclient@protonmail.com>
  • Loading branch information
dknopik and lightclient authored Jul 31, 2024
1 parent 6e33dbf commit de6d597
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions p2p/discover/table_reval.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,18 @@ func (tr *tableRevalidation) nodeEndpointChanged(tab *Table, n *tableNode) {
// It returns the next time it should be invoked, which is used in the Table main loop
// to schedule a timer. However, run can be called at any time.
func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) (nextTime mclock.AbsTime) {
if n := tr.fast.get(now, &tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n)
tr.fast.schedule(now, &tab.rand)
}
if n := tr.slow.get(now, &tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n)
tr.slow.schedule(now, &tab.rand)
reval := func(list *revalidationList) {
if list.nextTime <= now {
if n := list.get(now, &tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n)
}
// Update nextTime regardless if any requests were started because
// current value has passed.
list.schedule(now, &tab.rand)
}
}
reval(&tr.fast)
reval(&tr.slow)

return min(tr.fast.nextTime, tr.slow.nextTime)
}
Expand Down Expand Up @@ -200,7 +204,7 @@ type revalidationList struct {

// get returns a random node from the queue. Nodes in the 'exclude' map are not returned.
func (list *revalidationList) get(now mclock.AbsTime, rand randomSource, exclude map[enode.ID]struct{}) *tableNode {
if now < list.nextTime || len(list.nodes) == 0 {
if len(list.nodes) == 0 {
return nil
}
for i := 0; i < len(list.nodes)*3; i++ {
Expand Down

0 comments on commit de6d597

Please sign in to comment.