table.go 21 KB

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