diff --git a/packages/kad-dht/src/index.ts b/packages/kad-dht/src/index.ts index c77f6d13e2..596ce07e9b 100644 --- a/packages/kad-dht/src/index.ts +++ b/packages/kad-dht/src/index.ts @@ -428,9 +428,23 @@ export interface KadDHTInit { * can be stored. * * Storing more peers means fewer lookups (and network operations) are needed - * to locate a certain peer, but also that more memory is consumed. + * to locate a certain peer, but also that more memory is consumed and more + * CPU while responding to queries (e.g. with more peers in the table sorting + * the closest peers becomes more expensive) and CPU/network during table + * maintenance (e.g. checking peers are still online). * - * @default 32 + * The larger this value, the more prefix bits must be the same for a peer to + * be stored in a KAD bucket, so the fewer nodes that bucket is likely to + * contain. + * + * The total number of peers in the table is a factor of `prefixLength` and + * `kBucketSize`: + * + * ``` + * (2 ^ prefixLength) * kBucketSize + * ``` + * + * @default 6 */ prefixLength?: number @@ -438,6 +452,13 @@ export interface KadDHTInit { * If true, only ever be a DHT client. If false, be a DHT client until told * to be a DHT server via `setMode`. * + * In general this should be left as the default because server mode will be + * selected automatically when libp2p establishes that the current node has + * a publicly dialable address. + * + * The exception to this is LAN-only DHT (e.g. for testing purposes) where it + * is safe to assume that the current node is dialable. + * * @default false */ clientMode?: boolean diff --git a/packages/kad-dht/src/routing-table/index.ts b/packages/kad-dht/src/routing-table/index.ts index 25d1a649e9..4c95a368b9 100644 --- a/packages/kad-dht/src/routing-table/index.ts +++ b/packages/kad-dht/src/routing-table/index.ts @@ -14,7 +14,7 @@ import type { AbortOptions, ComponentLogger, CounterGroup, Logger, Metric, Metri import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout' export const KBUCKET_SIZE = 20 -export const PREFIX_LENGTH = 8 +export const PREFIX_LENGTH = 6 export const PING_NEW_CONTACT_TIMEOUT = 2000 export const PING_NEW_CONTACT_CONCURRENCY = 20 export const PING_NEW_CONTACT_MAX_QUEUE_SIZE = 100 diff --git a/packages/kad-dht/test/routing-table.spec.ts b/packages/kad-dht/test/routing-table.spec.ts index 2657f3dda0..3311c2e0bf 100644 --- a/packages/kad-dht/test/routing-table.spec.ts +++ b/packages/kad-dht/test/routing-table.spec.ts @@ -484,4 +484,40 @@ describe('Routing Table', () => { await expect(table.find(peer.id)).to.eventually.be.ok() }) + + describe('max size', () => { + it('should constrain size to 10', async () => { + const prefixLength = 8 + const kBucketSize = 20 + const maxSize = Math.pow(2, prefixLength) * kBucketSize + + table = new RoutingTable(components, { + logPrefix: '', + metricsPrefix: '', + protocol: PROTOCOL, + network, + prefixLength, + kBucketSize + }) + await start(table) + + // reset network stub so we can have specific behavior + table.network = network = stubInterface() + + // all old peers answer pings, no peers should be evicted + network.sendRequest.callsFake(async function * (from: PeerId) { + yield peerResponseEvent({ + from, + messageType: MessageType.PING + }) + }) + + for (let i = 0; i < 2 * maxSize; i++) { + const remotePeer = await createPeerId() + await table.add(remotePeer) + } + + expect(table.size).to.be.lessThanOrEqual(maxSize) + }) + }) })