p2p/discover: return nextTime from run()

This commit is contained in:
Felix Lange 2024-04-20 10:07:20 +02:00
parent dc3f78bb81
commit c1afb3c0cc
2 changed files with 44 additions and 40 deletions

View file

@ -66,7 +66,7 @@ type Table struct {
mutex sync.Mutex // protects buckets, bucket content, nursery, rand mutex sync.Mutex // protects buckets, bucket content, nursery, rand
buckets [nBuckets]*bucket // index of known nodes by distance buckets [nBuckets]*bucket // index of known nodes by distance
nursery []*node // bootstrap nodes nursery []*node // bootstrap nodes
rand *reseedingRandom // source of randomness, periodically reseeded rand reseedingRandom // source of randomness, periodically reseeded
ips netutil.DistinctNetSet ips netutil.DistinctNetSet
revalidation tableRevalidation revalidation tableRevalidation
@ -77,7 +77,7 @@ type Table struct {
// loop channels // loop channels
refreshReq chan chan struct{} refreshReq chan chan struct{}
revalidateResp chan revalidationResponse revalResponseCh chan revalidationResponse
addNodeCh chan addNodeRequest addNodeCh chan addNodeRequest
addNodeHandled chan struct{} addNodeHandled chan struct{}
findFailureCh chan *node findFailureCh chan *node
@ -120,14 +120,13 @@ func newTable(t transport, db *enode.DB, cfg Config) (*Table, error) {
cfg: cfg, cfg: cfg,
log: cfg.Log, log: cfg.Log,
refreshReq: make(chan chan struct{}), refreshReq: make(chan chan struct{}),
revalidateResp: make(chan revalidationResponse), revalResponseCh: make(chan revalidationResponse),
addNodeCh: make(chan addNodeRequest), addNodeCh: make(chan addNodeRequest),
addNodeHandled: make(chan struct{}), addNodeHandled: make(chan struct{}),
findFailureCh: make(chan *node), findFailureCh: make(chan *node),
initDone: make(chan struct{}), initDone: make(chan struct{}),
closeReq: make(chan struct{}), closeReq: make(chan struct{}),
closed: make(chan struct{}), closed: make(chan struct{}),
rand: new(reseedingRandom),
ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit}, ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit},
} }
for i := range tab.buckets { for i := range tab.buckets {
@ -349,17 +348,18 @@ func (tab *Table) loop() {
loop: loop:
for { for {
nextTime := tab.revalidation.run(tab, tab.cfg.Clock.Now())
revalTimer.Schedule(nextTime)
reseedRandTimer.Schedule(tab.rand.nextReseedTime()) reseedRandTimer.Schedule(tab.rand.nextReseedTime())
revalTimer.Schedule(tab.revalidation.nextTime())
select { select {
case <-reseedRandTimer.C(): case <-reseedRandTimer.C():
tab.rand.seed(tab.cfg.Clock.Now()) tab.rand.seed(tab.cfg.Clock.Now())
case <-revalTimer.C(): case <-revalTimer.C():
tab.revalidation.run(tab, mclock.Now())
case r := <-tab.revalidateResp: case r := <-tab.revalResponseCh:
tab.revalidation.handleResponse(tab, r) tab.revalidation.handleResponse(tab, r)
case addreq := <-tab.addNodeCh: case addreq := <-tab.addNodeCh:

View file

@ -50,7 +50,7 @@ func (tr *tableRevalidation) init(cfg *Config) {
// nodeAdded is called when the table receives a new node. // nodeAdded is called when the table receives a new node.
func (tr *tableRevalidation) nodeAdded(tab *Table, n *node) { func (tr *tableRevalidation) nodeAdded(tab *Table, n *node) {
tr.newNodes.push(n, tab.cfg.Clock.Now(), tab.rand) tr.newNodes.push(n, tab.cfg.Clock.Now(), &tab.rand)
} }
// nodeRemoved is called when a node was removed from the table. // nodeRemoved is called when a node was removed from the table.
@ -61,22 +61,26 @@ func (tr *tableRevalidation) nodeRemoved(n *node) {
} }
} }
// nextTime returns the next time run() should be invoked. // run performs node revalidation.
// The Table main loop uses this to schedule a timer. // It returns the next time it should be invoked, which is used in the Table main loop
func (tr *tableRevalidation) nextTime() mclock.AbsTime { // to schedule a timer. However, run can be called at any time.
return min(tr.newNodes.nextTime, tr.nodes.nextTime) func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) (nextTime mclock.AbsTime) {
if n := tr.newNodes.get(now, &tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n, true)
tr.newNodes.schedule(now, &tab.rand)
}
if n := tr.nodes.get(now, &tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n, false)
tr.nodes.schedule(now, &tab.rand)
} }
// run performs node revalidation. if tr.newNodes.nextTime == never {
func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) { return tr.nodes.nextTime
if n := tr.newNodes.get(now, tab.rand, tr.activeReq); n != nil {
tr.startRequest(tab, n, true)
tr.newNodes.schedule(now, tab.rand)
} }
if n := tr.nodes.get(now, tab.rand, tr.activeReq); n != nil { if tr.nodes.nextTime == never {
tr.startRequest(tab, n, false) return tr.newNodes.nextTime
tr.nodes.schedule(now, tab.rand)
} }
return min(tr.newNodes.nextTime, tr.nodes.nextTime)
} }
// startRequest spawns a revalidation request for node n. // startRequest spawns a revalidation request for node n.
@ -111,7 +115,7 @@ func (tab *Table) doRevalidate(resp revalidationResponse, node *enode.Node) {
} }
select { select {
case tab.revalidateResp <- resp: case tab.revalResponseCh <- resp:
case <-tab.closed: case <-tab.closed:
} }
} }
@ -150,7 +154,7 @@ func (tr *tableRevalidation) handleResponse(tab *Table, resp revalidationRespons
// Move node over to main queue after first validation. // Move node over to main queue after first validation.
if resp.isNewNode { if resp.isNewNode {
tr.newNodes.remove(n) tr.newNodes.remove(n)
tr.nodes.push(n, tab.cfg.Clock.Now(), tab.rand) tr.nodes.push(n, tab.cfg.Clock.Now(), &tab.rand)
} }
// Store potential seeds in database. // Store potential seeds in database.