table.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  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/rand"
  25. "encoding/binary"
  26. "fmt"
  27. "net"
  28. "sort"
  29. "sync"
  30. "time"
  31. "github.com/ethereum/go-ethereum/common"
  32. "github.com/ethereum/go-ethereum/crypto"
  33. "github.com/ethereum/go-ethereum/logger"
  34. "github.com/ethereum/go-ethereum/logger/glog"
  35. )
  36. const (
  37. alpha = 3 // Kademlia concurrency factor
  38. bucketSize = 16 // Kademlia bucket size
  39. hashBits = len(common.Hash{}) * 8
  40. nBuckets = hashBits + 1 // Number of buckets
  41. maxBondingPingPongs = 16
  42. maxFindnodeFailures = 5
  43. autoRefreshInterval = 1 * time.Hour
  44. seedCount = 30
  45. seedMaxAge = 5 * 24 * time.Hour
  46. )
  47. type Table struct {
  48. mutex sync.Mutex // protects buckets, their content, and nursery
  49. buckets [nBuckets]*bucket // index of known nodes by distance
  50. nursery []*Node // bootstrap nodes
  51. db *nodeDB // database of known nodes
  52. refreshReq chan chan struct{}
  53. closeReq chan struct{}
  54. closed chan struct{}
  55. bondmu sync.Mutex
  56. bonding map[NodeID]*bondproc
  57. bondslots chan struct{} // limits total number of active bonding processes
  58. nodeAddedHook func(*Node) // for testing
  59. net transport
  60. self *Node // metadata of the local node
  61. }
  62. type bondproc struct {
  63. err error
  64. n *Node
  65. done chan struct{}
  66. }
  67. // transport is implemented by the UDP transport.
  68. // it is an interface so we can test without opening lots of UDP
  69. // sockets and without generating a private key.
  70. type transport interface {
  71. ping(NodeID, *net.UDPAddr) error
  72. waitping(NodeID) error
  73. findnode(toid NodeID, addr *net.UDPAddr, target NodeID) ([]*Node, error)
  74. close()
  75. }
  76. // bucket contains nodes, ordered by their last activity. the entry
  77. // that was most recently active is the first element in entries.
  78. type bucket struct{ entries []*Node }
  79. func newTable(t transport, ourID NodeID, ourAddr *net.UDPAddr, nodeDBPath string) (*Table, error) {
  80. // If no node database was given, use an in-memory one
  81. db, err := newNodeDB(nodeDBPath, Version, ourID)
  82. if err != nil {
  83. return nil, err
  84. }
  85. tab := &Table{
  86. net: t,
  87. db: db,
  88. self: NewNode(ourID, ourAddr.IP, uint16(ourAddr.Port), uint16(ourAddr.Port)),
  89. bonding: make(map[NodeID]*bondproc),
  90. bondslots: make(chan struct{}, maxBondingPingPongs),
  91. refreshReq: make(chan chan struct{}),
  92. closeReq: make(chan struct{}),
  93. closed: make(chan struct{}),
  94. }
  95. for i := 0; i < cap(tab.bondslots); i++ {
  96. tab.bondslots <- struct{}{}
  97. }
  98. for i := range tab.buckets {
  99. tab.buckets[i] = new(bucket)
  100. }
  101. go tab.refreshLoop()
  102. return tab, nil
  103. }
  104. // Self returns the local node.
  105. // The returned node should not be modified by the caller.
  106. func (tab *Table) Self() *Node {
  107. return tab.self
  108. }
  109. // ReadRandomNodes fills the given slice with random nodes from the
  110. // table. It will not write the same node more than once. The nodes in
  111. // the slice are copies and can be modified by the caller.
  112. func (tab *Table) ReadRandomNodes(buf []*Node) (n int) {
  113. tab.mutex.Lock()
  114. defer tab.mutex.Unlock()
  115. // TODO: tree-based buckets would help here
  116. // Find all non-empty buckets and get a fresh slice of their entries.
  117. var buckets [][]*Node
  118. for _, b := range tab.buckets {
  119. if len(b.entries) > 0 {
  120. buckets = append(buckets, b.entries[:])
  121. }
  122. }
  123. if len(buckets) == 0 {
  124. return 0
  125. }
  126. // Shuffle the buckets.
  127. for i := uint32(len(buckets)) - 1; i > 0; i-- {
  128. j := randUint(i)
  129. buckets[i], buckets[j] = buckets[j], buckets[i]
  130. }
  131. // Move head of each bucket into buf, removing buckets that become empty.
  132. var i, j int
  133. for ; i < len(buf); i, j = i+1, (j+1)%len(buckets) {
  134. b := buckets[j]
  135. buf[i] = &(*b[0])
  136. buckets[j] = b[1:]
  137. if len(b) == 1 {
  138. buckets = append(buckets[:j], buckets[j+1:]...)
  139. }
  140. if len(buckets) == 0 {
  141. break
  142. }
  143. }
  144. return i + 1
  145. }
  146. func randUint(max uint32) uint32 {
  147. if max == 0 {
  148. return 0
  149. }
  150. var b [4]byte
  151. rand.Read(b[:])
  152. return binary.BigEndian.Uint32(b[:]) % max
  153. }
  154. // Close terminates the network listener and flushes the node database.
  155. func (tab *Table) Close() {
  156. select {
  157. case <-tab.closed:
  158. // already closed.
  159. case tab.closeReq <- struct{}{}:
  160. <-tab.closed // wait for refreshLoop to end.
  161. }
  162. }
  163. // SetFallbackNodes sets the initial points of contact. These nodes
  164. // are used to connect to the network if the table is empty and there
  165. // are no known nodes in the database.
  166. func (tab *Table) SetFallbackNodes(nodes []*Node) error {
  167. for _, n := range nodes {
  168. if err := n.validateComplete(); err != nil {
  169. return fmt.Errorf("bad bootstrap/fallback node %q (%v)", n, err)
  170. }
  171. }
  172. tab.mutex.Lock()
  173. tab.nursery = make([]*Node, 0, len(nodes))
  174. for _, n := range nodes {
  175. cpy := *n
  176. // Recompute cpy.sha because the node might not have been
  177. // created by NewNode or ParseNode.
  178. cpy.sha = crypto.Keccak256Hash(n.ID[:])
  179. tab.nursery = append(tab.nursery, &cpy)
  180. }
  181. tab.mutex.Unlock()
  182. tab.refresh()
  183. return nil
  184. }
  185. // Resolve searches for a specific node with the given ID.
  186. // It returns nil if the node could not be found.
  187. func (tab *Table) Resolve(targetID NodeID) *Node {
  188. // If the node is present in the local table, no
  189. // network interaction is required.
  190. hash := crypto.Keccak256Hash(targetID[:])
  191. tab.mutex.Lock()
  192. cl := tab.closest(hash, 1)
  193. tab.mutex.Unlock()
  194. if len(cl.entries) > 0 && cl.entries[0].ID == targetID {
  195. return cl.entries[0]
  196. }
  197. // Otherwise, do a network lookup.
  198. result := tab.Lookup(targetID)
  199. for _, n := range result {
  200. if n.ID == targetID {
  201. return n
  202. }
  203. }
  204. return nil
  205. }
  206. // Lookup performs a network search for nodes close
  207. // to the given target. It approaches the target by querying
  208. // nodes that are closer to it on each iteration.
  209. // The given target does not need to be an actual node
  210. // identifier.
  211. func (tab *Table) Lookup(targetID NodeID) []*Node {
  212. return tab.lookup(targetID, true)
  213. }
  214. func (tab *Table) lookup(targetID NodeID, refreshIfEmpty bool) []*Node {
  215. var (
  216. target = crypto.Keccak256Hash(targetID[:])
  217. asked = make(map[NodeID]bool)
  218. seen = make(map[NodeID]bool)
  219. reply = make(chan []*Node, alpha)
  220. pendingQueries = 0
  221. result *nodesByDistance
  222. )
  223. // don't query further if we hit ourself.
  224. // unlikely to happen often in practice.
  225. asked[tab.self.ID] = true
  226. for {
  227. tab.mutex.Lock()
  228. // generate initial result set
  229. result = tab.closest(target, bucketSize)
  230. tab.mutex.Unlock()
  231. if len(result.entries) > 0 || !refreshIfEmpty {
  232. break
  233. }
  234. // The result set is empty, all nodes were dropped, refresh.
  235. // We actually wait for the refresh to complete here. The very
  236. // first query will hit this case and run the bootstrapping
  237. // logic.
  238. <-tab.refresh()
  239. refreshIfEmpty = false
  240. }
  241. for {
  242. // ask the alpha closest nodes that we haven't asked yet
  243. for i := 0; i < len(result.entries) && pendingQueries < alpha; i++ {
  244. n := result.entries[i]
  245. if !asked[n.ID] {
  246. asked[n.ID] = true
  247. pendingQueries++
  248. go func() {
  249. // Find potential neighbors to bond with
  250. r, err := tab.net.findnode(n.ID, n.addr(), targetID)
  251. if err != nil {
  252. // Bump the failure counter to detect and evacuate non-bonded entries
  253. fails := tab.db.findFails(n.ID) + 1
  254. tab.db.updateFindFails(n.ID, fails)
  255. glog.V(logger.Detail).Infof("Bumping failures for %x: %d", n.ID[:8], fails)
  256. if fails >= maxFindnodeFailures {
  257. glog.V(logger.Detail).Infof("Evacuating node %x: %d findnode failures", n.ID[:8], fails)
  258. tab.delete(n)
  259. }
  260. }
  261. reply <- tab.bondall(r)
  262. }()
  263. }
  264. }
  265. if pendingQueries == 0 {
  266. // we have asked all closest nodes, stop the search
  267. break
  268. }
  269. // wait for the next reply
  270. for _, n := range <-reply {
  271. if n != nil && !seen[n.ID] {
  272. seen[n.ID] = true
  273. result.push(n, bucketSize)
  274. }
  275. }
  276. pendingQueries--
  277. }
  278. return result.entries
  279. }
  280. func (tab *Table) refresh() <-chan struct{} {
  281. done := make(chan struct{})
  282. select {
  283. case tab.refreshReq <- done:
  284. case <-tab.closed:
  285. close(done)
  286. }
  287. return done
  288. }
  289. // refreshLoop schedules doRefresh runs and coordinates shutdown.
  290. func (tab *Table) refreshLoop() {
  291. var (
  292. timer = time.NewTicker(autoRefreshInterval)
  293. waiting []chan struct{} // accumulates waiting callers while doRefresh runs
  294. done chan struct{} // where doRefresh reports completion
  295. )
  296. loop:
  297. for {
  298. select {
  299. case <-timer.C:
  300. if done == nil {
  301. done = make(chan struct{})
  302. go tab.doRefresh(done)
  303. }
  304. case req := <-tab.refreshReq:
  305. waiting = append(waiting, req)
  306. if done == nil {
  307. done = make(chan struct{})
  308. go tab.doRefresh(done)
  309. }
  310. case <-done:
  311. for _, ch := range waiting {
  312. close(ch)
  313. }
  314. waiting = nil
  315. done = nil
  316. case <-tab.closeReq:
  317. break loop
  318. }
  319. }
  320. if tab.net != nil {
  321. tab.net.close()
  322. }
  323. if done != nil {
  324. <-done
  325. }
  326. for _, ch := range waiting {
  327. close(ch)
  328. }
  329. tab.db.close()
  330. close(tab.closed)
  331. }
  332. // doRefresh performs a lookup for a random target to keep buckets
  333. // full. seed nodes are inserted if the table is empty (initial
  334. // bootstrap or discarded faulty peers).
  335. func (tab *Table) doRefresh(done chan struct{}) {
  336. defer close(done)
  337. // The Kademlia paper specifies that the bucket refresh should
  338. // perform a lookup in the least recently used bucket. We cannot
  339. // adhere to this because the findnode target is a 512bit value
  340. // (not hash-sized) and it is not easily possible to generate a
  341. // sha3 preimage that falls into a chosen bucket.
  342. // We perform a lookup with a random target instead.
  343. var target NodeID
  344. rand.Read(target[:])
  345. result := tab.lookup(target, false)
  346. if len(result) > 0 {
  347. return
  348. }
  349. // The table is empty. Load nodes from the database and insert
  350. // them. This should yield a few previously seen nodes that are
  351. // (hopefully) still alive.
  352. seeds := tab.db.querySeeds(seedCount, seedMaxAge)
  353. seeds = tab.bondall(append(seeds, tab.nursery...))
  354. if glog.V(logger.Debug) {
  355. if len(seeds) == 0 {
  356. glog.Infof("no seed nodes found")
  357. }
  358. for _, n := range seeds {
  359. age := time.Since(tab.db.lastPong(n.ID))
  360. glog.Infof("seed node (age %v): %v", age, n)
  361. }
  362. }
  363. tab.mutex.Lock()
  364. tab.stuff(seeds)
  365. tab.mutex.Unlock()
  366. // Finally, do a self lookup to fill up the buckets.
  367. tab.lookup(tab.self.ID, false)
  368. }
  369. // closest returns the n nodes in the table that are closest to the
  370. // given id. The caller must hold tab.mutex.
  371. func (tab *Table) closest(target common.Hash, nresults int) *nodesByDistance {
  372. // This is a very wasteful way to find the closest nodes but
  373. // obviously correct. I believe that tree-based buckets would make
  374. // this easier to implement efficiently.
  375. close := &nodesByDistance{target: target}
  376. for _, b := range tab.buckets {
  377. for _, n := range b.entries {
  378. close.push(n, nresults)
  379. }
  380. }
  381. return close
  382. }
  383. func (tab *Table) len() (n int) {
  384. for _, b := range tab.buckets {
  385. n += len(b.entries)
  386. }
  387. return n
  388. }
  389. // bondall bonds with all given nodes concurrently and returns
  390. // those nodes for which bonding has probably succeeded.
  391. func (tab *Table) bondall(nodes []*Node) (result []*Node) {
  392. rc := make(chan *Node, len(nodes))
  393. for i := range nodes {
  394. go func(n *Node) {
  395. nn, _ := tab.bond(false, n.ID, n.addr(), uint16(n.TCP))
  396. rc <- nn
  397. }(nodes[i])
  398. }
  399. for _ = range nodes {
  400. if n := <-rc; n != nil {
  401. result = append(result, n)
  402. }
  403. }
  404. return result
  405. }
  406. // bond ensures the local node has a bond with the given remote node.
  407. // It also attempts to insert the node into the table if bonding succeeds.
  408. // The caller must not hold tab.mutex.
  409. //
  410. // A bond is must be established before sending findnode requests.
  411. // Both sides must have completed a ping/pong exchange for a bond to
  412. // exist. The total number of active bonding processes is limited in
  413. // order to restrain network use.
  414. //
  415. // bond is meant to operate idempotently in that bonding with a remote
  416. // node which still remembers a previously established bond will work.
  417. // The remote node will simply not send a ping back, causing waitping
  418. // to time out.
  419. //
  420. // If pinged is true, the remote node has just pinged us and one half
  421. // of the process can be skipped.
  422. func (tab *Table) bond(pinged bool, id NodeID, addr *net.UDPAddr, tcpPort uint16) (*Node, error) {
  423. // Retrieve a previously known node and any recent findnode failures
  424. node, fails := tab.db.node(id), 0
  425. if node != nil {
  426. fails = tab.db.findFails(id)
  427. }
  428. // If the node is unknown (non-bonded) or failed (remotely unknown), bond from scratch
  429. var result error
  430. age := time.Since(tab.db.lastPong(id))
  431. if node == nil || fails > 0 || age > nodeDBNodeExpiration {
  432. glog.V(logger.Detail).Infof("Bonding %x: known=%t, fails=%d age=%v", id[:8], node != nil, fails, age)
  433. tab.bondmu.Lock()
  434. w := tab.bonding[id]
  435. if w != nil {
  436. // Wait for an existing bonding process to complete.
  437. tab.bondmu.Unlock()
  438. <-w.done
  439. } else {
  440. // Register a new bonding process.
  441. w = &bondproc{done: make(chan struct{})}
  442. tab.bonding[id] = w
  443. tab.bondmu.Unlock()
  444. // Do the ping/pong. The result goes into w.
  445. tab.pingpong(w, pinged, id, addr, tcpPort)
  446. // Unregister the process after it's done.
  447. tab.bondmu.Lock()
  448. delete(tab.bonding, id)
  449. tab.bondmu.Unlock()
  450. }
  451. // Retrieve the bonding results
  452. result = w.err
  453. if result == nil {
  454. node = w.n
  455. }
  456. }
  457. if node != nil {
  458. // Add the node to the table even if the bonding ping/pong
  459. // fails. It will be relaced quickly if it continues to be
  460. // unresponsive.
  461. tab.add(node)
  462. tab.db.updateFindFails(id, 0)
  463. }
  464. return node, result
  465. }
  466. func (tab *Table) pingpong(w *bondproc, pinged bool, id NodeID, addr *net.UDPAddr, tcpPort uint16) {
  467. // Request a bonding slot to limit network usage
  468. <-tab.bondslots
  469. defer func() { tab.bondslots <- struct{}{} }()
  470. // Ping the remote side and wait for a pong.
  471. if w.err = tab.ping(id, addr); w.err != nil {
  472. close(w.done)
  473. return
  474. }
  475. if !pinged {
  476. // Give the remote node a chance to ping us before we start
  477. // sending findnode requests. If they still remember us,
  478. // waitping will simply time out.
  479. tab.net.waitping(id)
  480. }
  481. // Bonding succeeded, update the node database.
  482. w.n = NewNode(id, addr.IP, uint16(addr.Port), tcpPort)
  483. tab.db.updateNode(w.n)
  484. close(w.done)
  485. }
  486. // ping a remote endpoint and wait for a reply, also updating the node
  487. // database accordingly.
  488. func (tab *Table) ping(id NodeID, addr *net.UDPAddr) error {
  489. tab.db.updateLastPing(id, time.Now())
  490. if err := tab.net.ping(id, addr); err != nil {
  491. return err
  492. }
  493. tab.db.updateLastPong(id, time.Now())
  494. // Start the background expiration goroutine after the first
  495. // successful communication. Subsequent calls have no effect if it
  496. // is already running. We do this here instead of somewhere else
  497. // so that the search for seed nodes also considers older nodes
  498. // that would otherwise be removed by the expiration.
  499. tab.db.ensureExpirer()
  500. return nil
  501. }
  502. // add attempts to add the given node its corresponding bucket. If the
  503. // bucket has space available, adding the node succeeds immediately.
  504. // Otherwise, the node is added if the least recently active node in
  505. // the bucket does not respond to a ping packet.
  506. //
  507. // The caller must not hold tab.mutex.
  508. func (tab *Table) add(new *Node) {
  509. b := tab.buckets[logdist(tab.self.sha, new.sha)]
  510. tab.mutex.Lock()
  511. defer tab.mutex.Unlock()
  512. if b.bump(new) {
  513. return
  514. }
  515. var oldest *Node
  516. if len(b.entries) == bucketSize {
  517. oldest = b.entries[bucketSize-1]
  518. if oldest.contested {
  519. // The node is already being replaced, don't attempt
  520. // to replace it.
  521. return
  522. }
  523. oldest.contested = true
  524. // Let go of the mutex so other goroutines can access
  525. // the table while we ping the least recently active node.
  526. tab.mutex.Unlock()
  527. err := tab.ping(oldest.ID, oldest.addr())
  528. tab.mutex.Lock()
  529. oldest.contested = false
  530. if err == nil {
  531. // The node responded, don't replace it.
  532. return
  533. }
  534. }
  535. added := b.replace(new, oldest)
  536. if added && tab.nodeAddedHook != nil {
  537. tab.nodeAddedHook(new)
  538. }
  539. }
  540. // stuff adds nodes the table to the end of their corresponding bucket
  541. // if the bucket is not full. The caller must hold tab.mutex.
  542. func (tab *Table) stuff(nodes []*Node) {
  543. outer:
  544. for _, n := range nodes {
  545. if n.ID == tab.self.ID {
  546. continue // don't add self
  547. }
  548. bucket := tab.buckets[logdist(tab.self.sha, n.sha)]
  549. for i := range bucket.entries {
  550. if bucket.entries[i].ID == n.ID {
  551. continue outer // already in bucket
  552. }
  553. }
  554. if len(bucket.entries) < bucketSize {
  555. bucket.entries = append(bucket.entries, n)
  556. if tab.nodeAddedHook != nil {
  557. tab.nodeAddedHook(n)
  558. }
  559. }
  560. }
  561. }
  562. // delete removes an entry from the node table (used to evacuate
  563. // failed/non-bonded discovery peers).
  564. func (tab *Table) delete(node *Node) {
  565. tab.mutex.Lock()
  566. defer tab.mutex.Unlock()
  567. bucket := tab.buckets[logdist(tab.self.sha, node.sha)]
  568. for i := range bucket.entries {
  569. if bucket.entries[i].ID == node.ID {
  570. bucket.entries = append(bucket.entries[:i], bucket.entries[i+1:]...)
  571. return
  572. }
  573. }
  574. }
  575. func (b *bucket) replace(n *Node, last *Node) bool {
  576. // Don't add if b already contains n.
  577. for i := range b.entries {
  578. if b.entries[i].ID == n.ID {
  579. return false
  580. }
  581. }
  582. // Replace last if it is still the last entry or just add n if b
  583. // isn't full. If is no longer the last entry, it has either been
  584. // replaced with someone else or became active.
  585. if len(b.entries) == bucketSize && (last == nil || b.entries[bucketSize-1].ID != last.ID) {
  586. return false
  587. }
  588. if len(b.entries) < bucketSize {
  589. b.entries = append(b.entries, nil)
  590. }
  591. copy(b.entries[1:], b.entries)
  592. b.entries[0] = n
  593. return true
  594. }
  595. func (b *bucket) bump(n *Node) bool {
  596. for i := range b.entries {
  597. if b.entries[i].ID == n.ID {
  598. // move it to the front
  599. copy(b.entries[1:], b.entries[:i])
  600. b.entries[0] = n
  601. return true
  602. }
  603. }
  604. return false
  605. }
  606. // nodesByDistance is a list of nodes, ordered by
  607. // distance to target.
  608. type nodesByDistance struct {
  609. entries []*Node
  610. target common.Hash
  611. }
  612. // push adds the given node to the list, keeping the total size below maxElems.
  613. func (h *nodesByDistance) push(n *Node, maxElems int) {
  614. ix := sort.Search(len(h.entries), func(i int) bool {
  615. return distcmp(h.target, h.entries[i].sha, n.sha) > 0
  616. })
  617. if len(h.entries) < maxElems {
  618. h.entries = append(h.entries, n)
  619. }
  620. if ix == len(h.entries) {
  621. // farther away than all nodes we already have.
  622. // if there was room for it, the node is now the last element.
  623. } else {
  624. // slide existing entries down to make room
  625. // this will overwrite the entry we just appended.
  626. copy(h.entries[ix+1:], h.entries[ix:])
  627. h.entries[ix] = n
  628. }
  629. }