github.com/ethereum/go-ethereum@v1.16.1/p2p/discover/node.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package discover 18 19 import ( 20 "slices" 21 "sort" 22 "time" 23 24 "github.com/ethereum/go-ethereum/p2p/enode" 25 ) 26 27 type BucketNode struct { 28 Node *enode.Node `json:"node"` 29 AddedToTable time.Time `json:"addedToTable"` 30 AddedToBucket time.Time `json:"addedToBucket"` 31 Checks int `json:"checks"` 32 Live bool `json:"live"` 33 } 34 35 // tableNode is an entry in Table. 36 type tableNode struct { 37 *enode.Node 38 revalList *revalidationList 39 addedToTable time.Time // first time node was added to bucket or replacement list 40 addedToBucket time.Time // time it was added in the actual bucket 41 livenessChecks uint // how often liveness was checked 42 isValidatedLive bool // true if existence of node is considered validated right now 43 } 44 45 func unwrapNodes(ns []*tableNode) []*enode.Node { 46 result := make([]*enode.Node, len(ns)) 47 for i, n := range ns { 48 result[i] = n.Node 49 } 50 return result 51 } 52 53 func (n *tableNode) String() string { 54 return n.Node.String() 55 } 56 57 // nodesByDistance is a list of nodes, ordered by distance to target. 58 type nodesByDistance struct { 59 entries []*enode.Node 60 target enode.ID 61 } 62 63 // push adds the given node to the list, keeping the total size below maxElems. 64 func (h *nodesByDistance) push(n *enode.Node, maxElems int) { 65 ix := sort.Search(len(h.entries), func(i int) bool { 66 return enode.DistCmp(h.target, h.entries[i].ID(), n.ID()) > 0 67 }) 68 69 end := len(h.entries) 70 if len(h.entries) < maxElems { 71 h.entries = append(h.entries, n) 72 } 73 if ix < end { 74 // Slide existing entries down to make room. 75 // This will overwrite the entry we just appended. 76 copy(h.entries[ix+1:], h.entries[ix:]) 77 h.entries[ix] = n 78 } 79 } 80 81 type nodeType interface { 82 ID() enode.ID 83 } 84 85 // containsID reports whether ns contains a node with the given ID. 86 func containsID[N nodeType](ns []N, id enode.ID) bool { 87 for _, n := range ns { 88 if n.ID() == id { 89 return true 90 } 91 } 92 return false 93 } 94 95 // deleteNode removes a node from the list. 96 func deleteNode[N nodeType](list []N, id enode.ID) []N { 97 return slices.DeleteFunc(list, func(n N) bool { 98 return n.ID() == id 99 }) 100 }