mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
p2p/discover: move node to fast revalidation list on inbound endpoint update
This commit is contained in:
parent
ddcabb198f
commit
3148497f2b
2 changed files with 22 additions and 17 deletions
|
|
@ -513,12 +513,9 @@ func (tab *Table) handleAddNode(req addNodeOp) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
b := tab.bucket(req.node.ID())
|
b := tab.bucket(req.node.ID())
|
||||||
n, wasUpdated := tab.bumpInBucket(b, req.node.Node, req.isInbound)
|
n, _ := tab.bumpInBucket(b, req.node.Node, req.isInbound)
|
||||||
if n != nil {
|
if n != nil {
|
||||||
// Already in bucket.
|
// Already in bucket.
|
||||||
if wasUpdated {
|
|
||||||
n.isValidatedLive = false
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if len(b.entries) >= bucketSize {
|
if len(b.entries) >= bucketSize {
|
||||||
|
|
@ -627,7 +624,9 @@ func (tab *Table) bumpInBucket(b *bucket, newRecord *enode.Node, isInbound bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there is an endpoint update and validate against IP limits.
|
// Check if there is an endpoint update and validate against IP limits.
|
||||||
if newRecord.IPAddr() != b.entries[i].IPAddr() {
|
ipchanged := newRecord.IPAddr() != n.IPAddr()
|
||||||
|
portchanged := newRecord.UDP() != n.UDP()
|
||||||
|
if ipchanged {
|
||||||
tab.removeIP(b, n.IP())
|
tab.removeIP(b, n.IP())
|
||||||
if !tab.addIP(b, newRecord.IP()) {
|
if !tab.addIP(b, newRecord.IP()) {
|
||||||
// It doesn't fit with the limit, put the previous record back.
|
// It doesn't fit with the limit, put the previous record back.
|
||||||
|
|
@ -636,8 +635,15 @@ func (tab *Table) bumpInBucket(b *bucket, newRecord *enode.Node, isInbound bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply update.
|
||||||
n.Node = newRecord
|
n.Node = newRecord
|
||||||
return n, true
|
|
||||||
|
// Endpoint changes cause the node to be considered unverified.
|
||||||
|
if ipchanged || portchanged {
|
||||||
|
tab.revalidation.nodeEndpointChanged(tab, n)
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
return n, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tab *Table) handleTrackRequest(op trackRequestOp) {
|
func (tab *Table) handleTrackRequest(op trackRequestOp) {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,12 @@ func (tr *tableRevalidation) nodeRemoved(n *node) {
|
||||||
n.revalList.remove(n)
|
n.revalList.remove(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nodeEndpointChanged is called when a change in IP or port is detected.
|
||||||
|
func (tr *tableRevalidation) nodeEndpointChanged(tab *Table, n *node) {
|
||||||
|
n.isValidatedLive = false
|
||||||
|
tr.moveToList(&tr.fast, n, tab.cfg.Clock.Now(), &tab.rand)
|
||||||
|
}
|
||||||
|
|
||||||
// run performs node revalidation.
|
// run performs node revalidation.
|
||||||
// It returns the next time it should be invoked, which is used in the Table main loop
|
// 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.
|
// to schedule a timer. However, run can be called at any time.
|
||||||
|
|
@ -146,11 +152,11 @@ func (tr *tableRevalidation) handleResponse(tab *Table, resp revalidationRespons
|
||||||
defer tab.mutex.Unlock()
|
defer tab.mutex.Unlock()
|
||||||
|
|
||||||
if !resp.didRespond {
|
if !resp.didRespond {
|
||||||
// Revalidation failed.
|
|
||||||
n.livenessChecks /= 3
|
n.livenessChecks /= 3
|
||||||
if n.livenessChecks <= 0 {
|
if n.livenessChecks <= 0 {
|
||||||
tab.deleteInBucket(b, n.ID())
|
tab.deleteInBucket(b, n.ID())
|
||||||
} else {
|
} else {
|
||||||
|
tab.log.Debug("Node revalidation failed", "b", b.index, "id", n.ID(), "checks", n.livenessChecks, "q", n.revalList.name)
|
||||||
tr.moveToList(&tr.fast, n, now, &tab.rand)
|
tr.moveToList(&tr.fast, n, now, &tab.rand)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -159,22 +165,15 @@ func (tr *tableRevalidation) handleResponse(tab *Table, resp revalidationRespons
|
||||||
// The node responded.
|
// The node responded.
|
||||||
n.livenessChecks++
|
n.livenessChecks++
|
||||||
n.isValidatedLive = true
|
n.isValidatedLive = true
|
||||||
|
tab.log.Debug("Node revalidated", "b", b.index, "id", n.ID(), "checks", n.livenessChecks, "q", n.revalList.name)
|
||||||
var endpointChanged bool
|
var endpointChanged bool
|
||||||
if resp.newRecord != nil {
|
if resp.newRecord != nil {
|
||||||
_, endpointChanged = tab.bumpInBucket(b, resp.newRecord, false)
|
_, endpointChanged = tab.bumpInBucket(b, resp.newRecord, false)
|
||||||
if endpointChanged {
|
|
||||||
// If the node changed its advertised endpoint, the updated ENR is not served
|
|
||||||
// until it has been revalidated.
|
|
||||||
n.isValidatedLive = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tab.log.Debug("Revalidated node", "b", b.index, "id", n.ID(), "checks", n.livenessChecks, "q", n.revalList)
|
|
||||||
|
|
||||||
// Move node over to slow queue after first validation.
|
// Node moves to slow list if it passed and hasn't changed.
|
||||||
if !endpointChanged {
|
if !endpointChanged {
|
||||||
tr.moveToList(&tr.slow, n, now, &tab.rand)
|
tr.moveToList(&tr.slow, n, now, &tab.rand)
|
||||||
} else {
|
|
||||||
tr.moveToList(&tr.fast, n, now, &tab.rand)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue