table.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  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. // Package discover implements the Node Discovery Protocol.
  17. //
  18. // The Node Discovery protocol provides a way to find RLPx nodes that
  19. // can be connected to. It uses a Kademlia-like protocol to maintain a
  20. // distributed database of the IDs and endpoints of all listening
  21. // nodes.
  22. package discover
  23. import (
  24. "crypto/ecdsa"
  25. crand "crypto/rand"
  26. "encoding/binary"
  27. "fmt"
  28. mrand "math/rand"
  29. "net"
  30. "sort"
  31. "sync"
  32. "time"
  33. "github.com/ethereum/go-ethereum/common"
  34. "github.com/ethereum/go-ethereum/crypto"
  35. "github.com/ethereum/go-ethereum/log"
  36. "github.com/ethereum/go-ethereum/p2p/enode"
  37. "github.com/ethereum/go-ethereum/p2p/netutil"
  38. )
  39. const (
  40. alpha = 3 // Kademlia concurrency factor
  41. bucketSize = 16 // Kademlia bucket size
  42. maxReplacements = 10 // Size of per-bucket replacement list
  43. // We keep buckets for the upper 1/15 of distances because
  44. // it's very unlikely we'll ever encounter a node that's closer.
  45. hashBits = len(common.Hash{}) * 8
  46. nBuckets = hashBits / 15 // Number of buckets
  47. bucketMinDistance = hashBits - nBuckets // Log distance of closest bucket
  48. // IP address limits.
  49. bucketIPLimit, bucketSubnet = 2, 24 // at most 2 addresses from the same /24
  50. tableIPLimit, tableSubnet = 10, 24
  51. maxFindnodeFailures = 5 // Nodes exceeding this limit are dropped
  52. refreshInterval = 30 * time.Minute
  53. revalidateInterval = 10 * time.Second
  54. copyNodesInterval = 30 * time.Second
  55. seedMinTableTime = 5 * time.Minute
  56. seedCount = 30
  57. seedMaxAge = 5 * 24 * time.Hour
  58. )
  59. type Table struct {
  60. mutex sync.Mutex // protects buckets, bucket content, nursery, rand
  61. buckets [nBuckets]*bucket // index of known nodes by distance
  62. nursery []*node // bootstrap nodes
  63. rand *mrand.Rand // source of randomness, periodically reseeded
  64. ips netutil.DistinctNetSet
  65. db *enode.DB // database of known nodes
  66. net transport
  67. refreshReq chan chan struct{}
  68. initDone chan struct{}
  69. closeReq chan struct{}
  70. closed chan struct{}
  71. nodeAddedHook func(*node) // for testing
  72. }
  73. // transport is implemented by the UDP transport.
  74. // it is an interface so we can test without opening lots of UDP
  75. // sockets and without generating a private key.
  76. type transport interface {
  77. self() *enode.Node
  78. ping(enode.ID, *net.UDPAddr) error
  79. findnode(toid enode.ID, addr *net.UDPAddr, target encPubkey) ([]*node, error)
  80. close()
  81. }
  82. // bucket contains nodes, ordered by their last activity. the entry
  83. // that was most recently active is the first element in entries.
  84. type bucket struct {
  85. entries []*node // live entries, sorted by time of last contact
  86. replacements []*node // recently seen nodes to be used if revalidation fails
  87. ips netutil.DistinctNetSet
  88. }
  89. func newTable(t transport, db *enode.DB, bootnodes []*enode.Node) (*Table, error) {
  90. tab := &Table{
  91. net: t,
  92. db: db,
  93. refreshReq: make(chan chan struct{}),
  94. initDone: make(chan struct{}),
  95. closeReq: make(chan struct{}),
  96. closed: make(chan struct{}),
  97. rand: mrand.New(mrand.NewSource(0)),
  98. ips: netutil.DistinctNetSet{Subnet: tableSubnet, Limit: tableIPLimit},
  99. }
  100. if err := tab.setFallbackNodes(bootnodes); err != nil {
  101. return nil, err
  102. }
  103. for i := range tab.buckets {
  104. tab.buckets[i] = &bucket{
  105. ips: netutil.DistinctNetSet{Subnet: bucketSubnet, Limit: bucketIPLimit},
  106. }
  107. }
  108. tab.seedRand()
  109. tab.loadSeedNodes()
  110. go tab.loop()
  111. return tab, nil
  112. }
  113. func (tab *Table) self() *enode.Node {
  114. return tab.net.self()
  115. }
  116. func (tab *Table) seedRand() {
  117. var b [8]byte
  118. crand.Read(b[:])
  119. tab.mutex.Lock()
  120. tab.rand.Seed(int64(binary.BigEndian.Uint64(b[:])))
  121. tab.mutex.Unlock()
  122. }
  123. // ReadRandomNodes fills the given slice with random nodes from the table. The results
  124. // are guaranteed to be unique for a single invocation, no node will appear twice.
  125. func (tab *Table) ReadRandomNodes(buf []*enode.Node) (n int) {
  126. if !tab.isInitDone() {
  127. return 0
  128. }
  129. tab.mutex.Lock()
  130. defer tab.mutex.Unlock()
  131. // Find all non-empty buckets and get a fresh slice of their entries.
  132. var buckets [][]*node
  133. for _, b := range &tab.buckets {
  134. if len(b.entries) > 0 {
  135. buckets = append(buckets, b.entries)
  136. }
  137. }
  138. if len(buckets) == 0 {
  139. return 0
  140. }
  141. // Shuffle the buckets.
  142. for i := len(buckets) - 1; i > 0; i-- {
  143. j := tab.rand.Intn(len(buckets))
  144. buckets[i], buckets[j] = buckets[j], buckets[i]
  145. }
  146. // Move head of each bucket into buf, removing buckets that become empty.
  147. var i, j int
  148. for ; i < len(buf); i, j = i+1, (j+1)%len(buckets) {
  149. b := buckets[j]
  150. buf[i] = unwrapNode(b[0])
  151. buckets[j] = b[1:]
  152. if len(b) == 1 {
  153. buckets = append(buckets[:j], buckets[j+1:]...)
  154. }
  155. if len(buckets) == 0 {
  156. break
  157. }
  158. }
  159. return i + 1
  160. }
  161. // Close terminates the network listener and flushes the node database.
  162. func (tab *Table) Close() {
  163. if tab.net != nil {
  164. tab.net.close()
  165. }
  166. select {
  167. case <-tab.closed:
  168. // already closed.
  169. case tab.closeReq <- struct{}{}:
  170. <-tab.closed // wait for refreshLoop to end.
  171. }
  172. }
  173. // setFallbackNodes sets the initial points of contact. These nodes
  174. // are used to connect to the network if the table is empty and there
  175. // are no known nodes in the database.
  176. func (tab *Table) setFallbackNodes(nodes []*enode.Node) error {
  177. for _, n := range nodes {
  178. if err := n.ValidateComplete(); err != nil {
  179. return fmt.Errorf("bad bootstrap node %q: %v", n, err)
  180. }
  181. }
  182. tab.nursery = wrapNodes(nodes)
  183. return nil
  184. }
  185. // isInitDone returns whether the table's initial seeding procedure has completed.
  186. func (tab *Table) isInitDone() bool {
  187. select {
  188. case <-tab.initDone:
  189. return true
  190. default:
  191. return false
  192. }
  193. }
  194. // Resolve searches for a specific node with the given ID.
  195. // It returns nil if the node could not be found.
  196. func (tab *Table) Resolve(n *enode.Node) *enode.Node {
  197. // If the node is present in the local table, no
  198. // network interaction is required.
  199. hash := n.ID()
  200. tab.mutex.Lock()
  201. cl := tab.closest(hash, 1)
  202. tab.mutex.Unlock()
  203. if len(cl.entries) > 0 && cl.entries[0].ID() == hash {
  204. return unwrapNode(cl.entries[0])
  205. }
  206. // Otherwise, do a network lookup.
  207. result := tab.lookup(encodePubkey(n.Pubkey()), true)
  208. for _, n := range result {
  209. if n.ID() == hash {
  210. return unwrapNode(n)
  211. }
  212. }
  213. return nil
  214. }
  215. // LookupRandom finds random nodes in the network.
  216. func (tab *Table) LookupRandom() []*enode.Node {
  217. var target encPubkey
  218. crand.Read(target[:])
  219. return unwrapNodes(tab.lookup(target, true))
  220. }
  221. // lookup performs a network search for nodes close to the given target. It approaches the
  222. // target by querying nodes that are closer to it on each iteration. The given target does
  223. // not need to be an actual node identifier.
  224. func (tab *Table) lookup(targetKey encPubkey, refreshIfEmpty bool) []*node {
  225. var (
  226. target = enode.ID(crypto.Keccak256Hash(targetKey[:]))
  227. asked = make(map[enode.ID]bool)
  228. seen = make(map[enode.ID]bool)
  229. reply = make(chan []*node, alpha)
  230. pendingQueries = 0
  231. result *nodesByDistance
  232. )
  233. // don't query further if we hit ourself.
  234. // unlikely to happen often in practice.
  235. asked[tab.self().ID()] = true
  236. for {
  237. tab.mutex.Lock()
  238. // generate initial result set
  239. result = tab.closest(target, bucketSize)
  240. tab.mutex.Unlock()
  241. if len(result.entries) > 0 || !refreshIfEmpty {
  242. break
  243. }
  244. // The result set is empty, all nodes were dropped, refresh.
  245. // We actually wait for the refresh to complete here. The very
  246. // first query will hit this case and run the bootstrapping
  247. // logic.
  248. <-tab.refresh()
  249. refreshIfEmpty = false
  250. }
  251. for {
  252. // ask the alpha closest nodes that we haven't asked yet
  253. for i := 0; i < len(result.entries) && pendingQueries < alpha; i++ {
  254. n := result.entries[i]
  255. if !asked[n.ID()] {
  256. asked[n.ID()] = true
  257. pendingQueries++
  258. go tab.findnode(n, targetKey, reply)
  259. }
  260. }
  261. if pendingQueries == 0 {
  262. // we have asked all closest nodes, stop the search
  263. break
  264. }
  265. // wait for the next reply
  266. for _, n := range <-reply {
  267. if n != nil && !seen[n.ID()] {
  268. seen[n.ID()] = true
  269. result.push(n, bucketSize)
  270. }
  271. }
  272. pendingQueries--
  273. }
  274. return result.entries
  275. }
  276. func (tab *Table) findnode(n *node, targetKey encPubkey, reply chan<- []*node) {
  277. fails := tab.db.FindFails(n.ID())
  278. r, err := tab.net.findnode(n.ID(), n.addr(), targetKey)
  279. if err != nil || len(r) == 0 {
  280. fails++
  281. tab.db.UpdateFindFails(n.ID(), fails)
  282. log.Trace("Findnode failed", "id", n.ID(), "failcount", fails, "err", err)
  283. if fails >= maxFindnodeFailures {
  284. log.Trace("Too many findnode failures, dropping", "id", n.ID(), "failcount", fails)
  285. tab.delete(n)
  286. }
  287. } else if fails > 0 {
  288. tab.db.UpdateFindFails(n.ID(), fails-1)
  289. }
  290. // Grab as many nodes as possible. Some of them might not be alive anymore, but we'll
  291. // just remove those again during revalidation.
  292. for _, n := range r {
  293. tab.add(n)
  294. }
  295. reply <- r
  296. }
  297. func (tab *Table) refresh() <-chan struct{} {
  298. done := make(chan struct{})
  299. select {
  300. case tab.refreshReq <- done:
  301. case <-tab.closed:
  302. close(done)
  303. }
  304. return done
  305. }
  306. // loop schedules refresh, revalidate runs and coordinates shutdown.
  307. func (tab *Table) loop() {
  308. var (
  309. revalidate = time.NewTimer(tab.nextRevalidateTime())
  310. refresh = time.NewTicker(refreshInterval)
  311. copyNodes = time.NewTicker(copyNodesInterval)
  312. refreshDone = make(chan struct{}) // where doRefresh reports completion
  313. revalidateDone chan struct{} // where doRevalidate reports completion
  314. waiting = []chan struct{}{tab.initDone} // holds waiting callers while doRefresh runs
  315. )
  316. defer refresh.Stop()
  317. defer revalidate.Stop()
  318. defer copyNodes.Stop()
  319. // Start initial refresh.
  320. go tab.doRefresh(refreshDone)
  321. loop:
  322. for {
  323. select {
  324. case <-refresh.C:
  325. tab.seedRand()
  326. if refreshDone == nil {
  327. refreshDone = make(chan struct{})
  328. go tab.doRefresh(refreshDone)
  329. }
  330. case req := <-tab.refreshReq:
  331. waiting = append(waiting, req)
  332. if refreshDone == nil {
  333. refreshDone = make(chan struct{})
  334. go tab.doRefresh(refreshDone)
  335. }
  336. case <-refreshDone:
  337. for _, ch := range waiting {
  338. close(ch)
  339. }
  340. waiting, refreshDone = nil, nil
  341. case <-revalidate.C:
  342. revalidateDone = make(chan struct{})
  343. go tab.doRevalidate(revalidateDone)
  344. case <-revalidateDone:
  345. revalidate.Reset(tab.nextRevalidateTime())
  346. revalidateDone = nil
  347. case <-copyNodes.C:
  348. go tab.copyLiveNodes()
  349. case <-tab.closeReq:
  350. break loop
  351. }
  352. }
  353. if refreshDone != nil {
  354. <-refreshDone
  355. }
  356. for _, ch := range waiting {
  357. close(ch)
  358. }
  359. if revalidateDone != nil {
  360. <-revalidateDone
  361. }
  362. close(tab.closed)
  363. }
  364. // doRefresh performs a lookup for a random target to keep buckets
  365. // full. seed nodes are inserted if the table is empty (initial
  366. // bootstrap or discarded faulty peers).
  367. func (tab *Table) doRefresh(done chan struct{}) {
  368. defer close(done)
  369. // Load nodes from the database and insert
  370. // them. This should yield a few previously seen nodes that are
  371. // (hopefully) still alive.
  372. tab.loadSeedNodes()
  373. // Run self lookup to discover new neighbor nodes.
  374. // We can only do this if we have a secp256k1 identity.
  375. var key ecdsa.PublicKey
  376. if err := tab.self().Load((*enode.Secp256k1)(&key)); err == nil {
  377. tab.lookup(encodePubkey(&key), false)
  378. }
  379. // The Kademlia paper specifies that the bucket refresh should
  380. // perform a lookup in the least recently used bucket. We cannot
  381. // adhere to this because the findnode target is a 512bit value
  382. // (not hash-sized) and it is not easily possible to generate a
  383. // sha3 preimage that falls into a chosen bucket.
  384. // We perform a few lookups with a random target instead.
  385. for i := 0; i < 3; i++ {
  386. var target encPubkey
  387. crand.Read(target[:])
  388. tab.lookup(target, false)
  389. }
  390. }
  391. func (tab *Table) loadSeedNodes() {
  392. seeds := wrapNodes(tab.db.QuerySeeds(seedCount, seedMaxAge))
  393. seeds = append(seeds, tab.nursery...)
  394. for i := range seeds {
  395. seed := seeds[i]
  396. age := log.Lazy{Fn: func() interface{} { return time.Since(tab.db.LastPongReceived(seed.ID())) }}
  397. log.Debug("Found seed node in database", "id", seed.ID(), "addr", seed.addr(), "age", age)
  398. tab.add(seed)
  399. }
  400. }
  401. // doRevalidate checks that the last node in a random bucket is still live
  402. // and replaces or deletes the node if it isn't.
  403. func (tab *Table) doRevalidate(done chan<- struct{}) {
  404. defer func() { done <- struct{}{} }()
  405. last, bi := tab.nodeToRevalidate()
  406. if last == nil {
  407. // No non-empty bucket found.
  408. return
  409. }
  410. // Ping the selected node and wait for a pong.
  411. err := tab.net.ping(last.ID(), last.addr())
  412. tab.mutex.Lock()
  413. defer tab.mutex.Unlock()
  414. b := tab.buckets[bi]
  415. if err == nil {
  416. // The node responded, move it to the front.
  417. log.Debug("Revalidated node", "b", bi, "id", last.ID())
  418. b.bump(last)
  419. return
  420. }
  421. // No reply received, pick a replacement or delete the node if there aren't
  422. // any replacements.
  423. if r := tab.replace(b, last); r != nil {
  424. log.Debug("Replaced dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "r", r.ID(), "rip", r.IP())
  425. } else {
  426. log.Debug("Removed dead node", "b", bi, "id", last.ID(), "ip", last.IP())
  427. }
  428. }
  429. // nodeToRevalidate returns the last node in a random, non-empty bucket.
  430. func (tab *Table) nodeToRevalidate() (n *node, bi int) {
  431. tab.mutex.Lock()
  432. defer tab.mutex.Unlock()
  433. for _, bi = range tab.rand.Perm(len(tab.buckets)) {
  434. b := tab.buckets[bi]
  435. if len(b.entries) > 0 {
  436. last := b.entries[len(b.entries)-1]
  437. return last, bi
  438. }
  439. }
  440. return nil, 0
  441. }
  442. func (tab *Table) nextRevalidateTime() time.Duration {
  443. tab.mutex.Lock()
  444. defer tab.mutex.Unlock()
  445. return time.Duration(tab.rand.Int63n(int64(revalidateInterval)))
  446. }
  447. // copyLiveNodes adds nodes from the table to the database if they have been in the table
  448. // longer then minTableTime.
  449. func (tab *Table) copyLiveNodes() {
  450. tab.mutex.Lock()
  451. defer tab.mutex.Unlock()
  452. now := time.Now()
  453. for _, b := range &tab.buckets {
  454. for _, n := range b.entries {
  455. if now.Sub(n.addedAt) >= seedMinTableTime {
  456. tab.db.UpdateNode(unwrapNode(n))
  457. }
  458. }
  459. }
  460. }
  461. // closest returns the n nodes in the table that are closest to the
  462. // given id. The caller must hold tab.mutex.
  463. func (tab *Table) closest(target enode.ID, nresults int) *nodesByDistance {
  464. // This is a very wasteful way to find the closest nodes but
  465. // obviously correct. I believe that tree-based buckets would make
  466. // this easier to implement efficiently.
  467. close := &nodesByDistance{target: target}
  468. for _, b := range &tab.buckets {
  469. for _, n := range b.entries {
  470. close.push(n, nresults)
  471. }
  472. }
  473. return close
  474. }
  475. func (tab *Table) len() (n int) {
  476. for _, b := range &tab.buckets {
  477. n += len(b.entries)
  478. }
  479. return n
  480. }
  481. // bucket returns the bucket for the given node ID hash.
  482. func (tab *Table) bucket(id enode.ID) *bucket {
  483. d := enode.LogDist(tab.self().ID(), id)
  484. if d <= bucketMinDistance {
  485. return tab.buckets[0]
  486. }
  487. return tab.buckets[d-bucketMinDistance-1]
  488. }
  489. // add attempts to add the given node to its corresponding bucket. If the bucket has space
  490. // available, adding the node succeeds immediately. Otherwise, the node is added if the
  491. // least recently active node in the bucket does not respond to a ping packet.
  492. //
  493. // The caller must not hold tab.mutex.
  494. func (tab *Table) add(n *node) {
  495. if n.ID() == tab.self().ID() {
  496. return
  497. }
  498. tab.mutex.Lock()
  499. defer tab.mutex.Unlock()
  500. b := tab.bucket(n.ID())
  501. if !tab.bumpOrAdd(b, n) {
  502. // Node is not in table. Add it to the replacement list.
  503. tab.addReplacement(b, n)
  504. }
  505. }
  506. // addThroughPing adds the given node to the table. Compared to plain
  507. // 'add' there is an additional safety measure: if the table is still
  508. // initializing the node is not added. This prevents an attack where the
  509. // table could be filled by just sending ping repeatedly.
  510. //
  511. // The caller must not hold tab.mutex.
  512. func (tab *Table) addThroughPing(n *node) {
  513. if !tab.isInitDone() {
  514. return
  515. }
  516. tab.add(n)
  517. }
  518. // stuff adds nodes the table to the end of their corresponding bucket
  519. // if the bucket is not full. The caller must not hold tab.mutex.
  520. func (tab *Table) stuff(nodes []*node) {
  521. tab.mutex.Lock()
  522. defer tab.mutex.Unlock()
  523. for _, n := range nodes {
  524. if n.ID() == tab.self().ID() {
  525. continue // don't add self
  526. }
  527. b := tab.bucket(n.ID())
  528. if len(b.entries) < bucketSize {
  529. tab.bumpOrAdd(b, n)
  530. }
  531. }
  532. }
  533. // delete removes an entry from the node table. It is used to evacuate dead nodes.
  534. func (tab *Table) delete(node *node) {
  535. tab.mutex.Lock()
  536. defer tab.mutex.Unlock()
  537. tab.deleteInBucket(tab.bucket(node.ID()), node)
  538. }
  539. func (tab *Table) addIP(b *bucket, ip net.IP) bool {
  540. if netutil.IsLAN(ip) {
  541. return true
  542. }
  543. if !tab.ips.Add(ip) {
  544. log.Debug("IP exceeds table limit", "ip", ip)
  545. return false
  546. }
  547. if !b.ips.Add(ip) {
  548. log.Debug("IP exceeds bucket limit", "ip", ip)
  549. tab.ips.Remove(ip)
  550. return false
  551. }
  552. return true
  553. }
  554. func (tab *Table) removeIP(b *bucket, ip net.IP) {
  555. if netutil.IsLAN(ip) {
  556. return
  557. }
  558. tab.ips.Remove(ip)
  559. b.ips.Remove(ip)
  560. }
  561. func (tab *Table) addReplacement(b *bucket, n *node) {
  562. for _, e := range b.replacements {
  563. if e.ID() == n.ID() {
  564. return // already in list
  565. }
  566. }
  567. if !tab.addIP(b, n.IP()) {
  568. return
  569. }
  570. var removed *node
  571. b.replacements, removed = pushNode(b.replacements, n, maxReplacements)
  572. if removed != nil {
  573. tab.removeIP(b, removed.IP())
  574. }
  575. }
  576. // replace removes n from the replacement list and replaces 'last' with it if it is the
  577. // last entry in the bucket. If 'last' isn't the last entry, it has either been replaced
  578. // with someone else or became active.
  579. func (tab *Table) replace(b *bucket, last *node) *node {
  580. if len(b.entries) == 0 || b.entries[len(b.entries)-1].ID() != last.ID() {
  581. // Entry has moved, don't replace it.
  582. return nil
  583. }
  584. // Still the last entry.
  585. if len(b.replacements) == 0 {
  586. tab.deleteInBucket(b, last)
  587. return nil
  588. }
  589. r := b.replacements[tab.rand.Intn(len(b.replacements))]
  590. b.replacements = deleteNode(b.replacements, r)
  591. b.entries[len(b.entries)-1] = r
  592. tab.removeIP(b, last.IP())
  593. return r
  594. }
  595. // bump moves the given node to the front of the bucket entry list
  596. // if it is contained in that list.
  597. func (b *bucket) bump(n *node) bool {
  598. for i := range b.entries {
  599. if b.entries[i].ID() == n.ID() {
  600. // move it to the front
  601. copy(b.entries[1:], b.entries[:i])
  602. b.entries[0] = n
  603. return true
  604. }
  605. }
  606. return false
  607. }
  608. // bumpOrAdd moves n to the front of the bucket entry list or adds it if the list isn't
  609. // full. The return value is true if n is in the bucket.
  610. func (tab *Table) bumpOrAdd(b *bucket, n *node) bool {
  611. if b.bump(n) {
  612. return true
  613. }
  614. if len(b.entries) >= bucketSize || !tab.addIP(b, n.IP()) {
  615. return false
  616. }
  617. b.entries, _ = pushNode(b.entries, n, bucketSize)
  618. b.replacements = deleteNode(b.replacements, n)
  619. n.addedAt = time.Now()
  620. if tab.nodeAddedHook != nil {
  621. tab.nodeAddedHook(n)
  622. }
  623. return true
  624. }
  625. func (tab *Table) deleteInBucket(b *bucket, n *node) {
  626. b.entries = deleteNode(b.entries, n)
  627. tab.removeIP(b, n.IP())
  628. }
  629. // pushNode adds n to the front of list, keeping at most max items.
  630. func pushNode(list []*node, n *node, max int) ([]*node, *node) {
  631. if len(list) < max {
  632. list = append(list, nil)
  633. }
  634. removed := list[len(list)-1]
  635. copy(list[1:], list)
  636. list[0] = n
  637. return list, removed
  638. }
  639. // deleteNode removes n from list.
  640. func deleteNode(list []*node, n *node) []*node {
  641. for i := range list {
  642. if list[i].ID() == n.ID() {
  643. return append(list[:i], list[i+1:]...)
  644. }
  645. }
  646. return list
  647. }
  648. // nodesByDistance is a list of nodes, ordered by
  649. // distance to target.
  650. type nodesByDistance struct {
  651. entries []*node
  652. target enode.ID
  653. }
  654. // push adds the given node to the list, keeping the total size below maxElems.
  655. func (h *nodesByDistance) push(n *node, maxElems int) {
  656. ix := sort.Search(len(h.entries), func(i int) bool {
  657. return enode.DistCmp(h.target, h.entries[i].ID(), n.ID()) > 0
  658. })
  659. if len(h.entries) < maxElems {
  660. h.entries = append(h.entries, n)
  661. }
  662. if ix == len(h.entries) {
  663. // farther away than all nodes we already have.
  664. // if there was room for it, the node is now the last element.
  665. } else {
  666. // slide existing entries down to make room
  667. // this will overwrite the entry we just appended.
  668. copy(h.entries[ix+1:], h.entries[ix:])
  669. h.entries[ix] = n
  670. }
  671. }