cmd/devp2p: improve crawl timestamp handling

This commit is contained in:
Felix Lange 2019-10-18 12:18:26 +02:00
parent 00d05619d8
commit 1098aef26a
3 changed files with 28 additions and 20 deletions

View file

@ -111,38 +111,40 @@ func (c *crawler) runIterator(done chan<- enode.Iterator, it enode.Iterator) {
}
func (c *crawler) updateNode(n *enode.Node) {
existing, ok := c.output[n.ID()]
node, ok := c.output[n.ID()]
// Skip validation of recently-seen nodes.
if ok && time.Since(existing.LastSeen) < c.revalidateInterval {
if ok && time.Since(node.LastCheck) < c.revalidateInterval {
return
}
// Request the node record.
nn, err := c.disc.RequestENR(n)
node.LastCheck = truncNow()
if err != nil {
if existing.Checks == 0 {
if node.Score == 0 {
// Node doesn't implement EIP-868.
log.Debug("Skipping node", "id", n.ID())
return
}
existing.Checks /= 2
node.Score /= 2
} else {
if !ok {
existing.FirstSeen = truncNow()
node.N = nn
node.Seq = nn.Seq()
node.Score++
if node.FirstResponse.IsZero() {
node.FirstResponse = node.LastCheck
}
existing.N = nn
existing.Seq = nn.Seq()
existing.LastSeen = truncNow()
existing.Checks++
node.LastResponse = node.LastCheck
}
// Store/update node in output set.
if existing.Checks <= 0 {
if node.Score <= 0 {
log.Info("Removing node", "id", n.ID())
delete(c.output, n.ID())
} else {
log.Info("Updating node", "id", n.ID(), "seq", existing.Seq, "checks", existing.Checks)
c.output[n.ID()] = existing
log.Info("Updating node", "id", n.ID(), "seq", n.Seq(), "score", node.Score)
c.output[n.ID()] = node
}
}

View file

@ -36,11 +36,17 @@ const jsonIndent = " "
type nodeSet map[enode.ID]nodeJSON
type nodeJSON struct {
Seq uint64 `json:"seq"`
N *enode.Node `json:"record"`
FirstSeen time.Time `json:"firstSeen,omitempty"`
LastSeen time.Time `json:"lastSeen,omitempty"`
Checks int `json:"checks"`
Seq uint64 `json:"seq"`
N *enode.Node `json:"record"`
// The score tracks how many liveness checks were performed. It is incremented by one
// every time the node passes a check, and halved every time it doesn't.
Score int `json:"score,omitempty"`
// These two track the time of last successful contact.
FirstResponse time.Time `json:"firstResponse,omitempty"`
LastResponse time.Time `json:"lastResponse,omitempty"`
// This one tracks the time of our last attempt to contact the node.
LastCheck time.Time `json:"lastCheck,omitempty"`
}
func loadNodesJSON(file string) nodeSet {
@ -79,7 +85,7 @@ func (ns nodeSet) nodes() []*enode.Node {
func (ns nodeSet) add(nodes ...*enode.Node) {
for _, n := range nodes {
ns[n.ID()] = nodeJSON{Seq: n.Seq(), N: n, FirstSeen: truncNow()}
ns[n.ID()] = nodeJSON{Seq: n.Seq(), N: n}
}
}

View file

@ -148,7 +148,7 @@ func minAgeFilter(args []string) (nodeFilter, error) {
return nil, err
}
f := func(n nodeJSON) bool {
age := n.LastSeen.Sub(n.FirstSeen)
age := n.LastResponse.Sub(n.FirstResponse)
return age >= minage
}
return f, nil