Skip to content

Commit 48cd9b6

Browse files
authored
fix: decrease default routing table size (#3023)
Reduces the default routing table size to 1280. This improves CPU/memory/network usage as we don't need to sort as many peers when finding the closest ones to a given key, nor do we need to contact as many to ensure only live peers are still in the table.
1 parent c4b6a37 commit 48cd9b6

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

packages/kad-dht/src/index.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -428,16 +428,37 @@ export interface KadDHTInit {
428428
* can be stored.
429429
*
430430
* Storing more peers means fewer lookups (and network operations) are needed
431-
* to locate a certain peer, but also that more memory is consumed.
431+
* to locate a certain peer, but also that more memory is consumed and more
432+
* CPU while responding to queries (e.g. with more peers in the table sorting
433+
* the closest peers becomes more expensive) and CPU/network during table
434+
* maintenance (e.g. checking peers are still online).
432435
*
433-
* @default 32
436+
* The larger this value, the more prefix bits must be the same for a peer to
437+
* be stored in a KAD bucket, so the fewer nodes that bucket is likely to
438+
* contain.
439+
*
440+
* The total number of peers in the table is a factor of `prefixLength` and
441+
* `kBucketSize`:
442+
*
443+
* ```
444+
* (2 ^ prefixLength) * kBucketSize
445+
* ```
446+
*
447+
* @default 6
434448
*/
435449
prefixLength?: number
436450

437451
/**
438452
* If true, only ever be a DHT client. If false, be a DHT client until told
439453
* to be a DHT server via `setMode`.
440454
*
455+
* In general this should be left as the default because server mode will be
456+
* selected automatically when libp2p establishes that the current node has
457+
* a publicly dialable address.
458+
*
459+
* The exception to this is LAN-only DHT (e.g. for testing purposes) where it
460+
* is safe to assume that the current node is dialable.
461+
*
441462
* @default false
442463
*/
443464
clientMode?: boolean

packages/kad-dht/src/routing-table/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { AbortOptions, ComponentLogger, CounterGroup, Logger, Metric, Metri
1414
import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
1515

1616
export const KBUCKET_SIZE = 20
17-
export const PREFIX_LENGTH = 8
17+
export const PREFIX_LENGTH = 6
1818
export const PING_NEW_CONTACT_TIMEOUT = 2000
1919
export const PING_NEW_CONTACT_CONCURRENCY = 20
2020
export const PING_NEW_CONTACT_MAX_QUEUE_SIZE = 100

packages/kad-dht/test/routing-table.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,40 @@ describe('Routing Table', () => {
484484

485485
await expect(table.find(peer.id)).to.eventually.be.ok()
486486
})
487+
488+
describe('max size', () => {
489+
it('should constrain size to 10', async () => {
490+
const prefixLength = 8
491+
const kBucketSize = 20
492+
const maxSize = Math.pow(2, prefixLength) * kBucketSize
493+
494+
table = new RoutingTable(components, {
495+
logPrefix: '',
496+
metricsPrefix: '',
497+
protocol: PROTOCOL,
498+
network,
499+
prefixLength,
500+
kBucketSize
501+
})
502+
await start(table)
503+
504+
// reset network stub so we can have specific behavior
505+
table.network = network = stubInterface()
506+
507+
// all old peers answer pings, no peers should be evicted
508+
network.sendRequest.callsFake(async function * (from: PeerId) {
509+
yield peerResponseEvent({
510+
from,
511+
messageType: MessageType.PING
512+
})
513+
})
514+
515+
for (let i = 0; i < 2 * maxSize; i++) {
516+
const remotePeer = await createPeerId()
517+
await table.add(remotePeer)
518+
}
519+
520+
expect(table.size).to.be.lessThanOrEqual(maxSize)
521+
})
522+
})
487523
})

0 commit comments

Comments
 (0)