Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
fix: use the content routing api for get/put operations (#34)
Browse files Browse the repository at this point in the history
The content routing API is more stable than the DHT API and if the
node has a DHT implementation it will be set up to work via the
content routing methods.
  • Loading branch information
achingbrain authored May 5, 2023
1 parent e04eca9 commit 55208cc
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 48 deletions.
1 change: 1 addition & 0 deletions packages/ipns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
"release": "aegir release"
},
"dependencies": {
"@libp2p/interface-content-routing": "^2.1.0",
"@libp2p/interface-dht": "^2.0.1",
"@libp2p/interface-peer-id": "^2.0.1",
"@libp2p/interface-pubsub": "^3.0.6",
Expand Down
54 changes: 6 additions & 48 deletions packages/ipns/src/routing/dht.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,35 @@
import { logger } from '@libp2p/logger'
import type { IPNSRouting } from '../index.js'
import type { DHT, QueryEvent } from '@libp2p/interface-dht'
import type { GetOptions, PutOptions } from './index.js'
import { CustomProgressEvent, ProgressEvent } from 'progress-events'

const log = logger('helia:ipns:routing:dht')
import type { ContentRouting } from '@libp2p/interface-content-routing'

export interface DHTRoutingComponents {
libp2p: {
dht: DHT
contentRouting: ContentRouting
}
}

export type DHTProgressEvents =
ProgressEvent<'ipns:routing:dht:query', QueryEvent> |
ProgressEvent<'ipns:routing:dht:error', Error>

export class DHTRouting implements IPNSRouting {
private readonly dht: DHT
private readonly contentRouting: ContentRouting

constructor (components: DHTRoutingComponents) {
this.dht = components.libp2p.dht
this.contentRouting = components.libp2p.contentRouting
}

async put (routingKey: Uint8Array, marshaledRecord: Uint8Array, options: PutOptions = {}): Promise<void> {
let putValue = false

try {
for await (const event of this.dht.put(routingKey, marshaledRecord, options)) {
logEvent('DHT put event', event)

options.onProgress?.(new CustomProgressEvent<QueryEvent>('ipns:routing:dht:query', event))

if (event.name === 'PEER_RESPONSE' && event.messageName === 'PUT_VALUE') {
putValue = true
}
}
await this.contentRouting.put(routingKey, marshaledRecord, options)
} catch (err: any) {
options.onProgress?.(new CustomProgressEvent<Error>('ipns:routing:dht:error', err))
}

if (!putValue) {
throw new Error('Could not put value to DHT')
}
}

async get (routingKey: Uint8Array, options: GetOptions = {}): Promise<Uint8Array> {
try {
for await (const event of this.dht.get(routingKey, options)) {
logEvent('DHT get event', event)

options.onProgress?.(new CustomProgressEvent<QueryEvent>('ipns:routing:dht:query', event))

if (event.name === 'VALUE') {
return event.value
}
}
return await this.contentRouting.get(routingKey, options)
} catch (err: any) {
options.onProgress?.(new CustomProgressEvent<Error>('ipns:routing:dht:error', err))
}
Expand All @@ -64,22 +38,6 @@ export class DHTRouting implements IPNSRouting {
}
}

function logEvent (prefix: string, event: QueryEvent): void {
if (event.name === 'SENDING_QUERY') {
log(prefix, event.name, event.messageName, '->', event.to.toString())
} else if (event.name === 'PEER_RESPONSE') {
log(prefix, event.name, event.messageName, '<-', event.from.toString())
} else if (event.name === 'FINAL_PEER') {
log(prefix, event.name, event.peer.id.toString())
} else if (event.name === 'QUERY_ERROR') {
log(prefix, event.name, event.error.message)
} else if (event.name === 'PROVIDER') {
log(prefix, event.name, event.providers.map(p => p.id.toString()).join(', '))
} else {
log(prefix, event.name)
}
}

export function dht (components: DHTRoutingComponents): IPNSRouting {
return new DHTRouting(components)
}

0 comments on commit 55208cc

Please sign in to comment.