diff --git a/package.json b/package.json index 1f6a041..b8ec600 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "compact-encoding": "^2.11.0", "hypercore-crypto": "^3.3.0", "jsnetworkx": "^0.3.4", + "loglevel": "^1.8.1", "lru": "^3.1.0", "ordered-json": "^0.1.1", "protocol-buffers-encodings": "^1.2.0", diff --git a/src/index.ts b/src/index.ts index 6c290e9..0d790c8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { Message, State, Type } from "./messages.js"; import sodium from "sodium-universal"; import type { PartialMessage } from "@protobuf-ts/runtime"; import DHTFlood from "@lumeweb/dht-flood"; +import log, { getLogger } from "loglevel"; type Bootstrap = { [key: string]: State; @@ -32,6 +33,7 @@ export default class DHTCache extends EventEmitter { private heartBeatInterval: number; protected flood: DHTFlood; + private log: log.Logger; constructor( swarm: any, @@ -53,6 +55,7 @@ export default class DHTCache extends EventEmitter { this._online = new Set([this._maybeHexify(this.id)]); this.swarm = swarm; this.flood = new DHTFlood({ id, swarm, ...opts }); + this.log = getLogger("dht-cache"); this.flood.on("peer-open", (peer) => this.addPeerHandler(peer)); this.flood.on("peer-remove", (peer) => this.removePeerHandler(peer)); @@ -193,10 +196,14 @@ export default class DHTCache extends EventEmitter { this._emitHeartbeat(peer); + this.log.debug(`Relay peer connected: ${stringId}`); + if (this.bootstrapped) { return; } + this.log.debug(`Broadcasting bootstrap request`); + // If this is the first person we've met, get their graph this._broadcastMessage({ type: Type.BOOTSTRAP_REQUEST }, 0); } @@ -210,6 +217,8 @@ export default class DHTCache extends EventEmitter { } this.onRemovePeer(peer); }, DISCONNECT_SMOOTH); + + this.log.debug(`Relay peer might have disconnected: ${id.toString("hex")}`); } protected onRemovePeer(peer: any) { @@ -229,6 +238,8 @@ export default class DHTCache extends EventEmitter { }, 0 ); + + this.log.debug(`Relay peer confirmed disconnected: ${id.toString("hex")}`); } protected onGetBroadcast(message: Buffer, id: Buffer) { @@ -252,25 +263,42 @@ export default class DHTCache extends EventEmitter { this._ensureItem(bufData); this._addEntityConnection(id, bufData); this.emit("item-added", id, bufData); + this.log.debug( + `New item added: ${bufData.toString("hex")} from ${id.toString( + "hex" + )}` + ); } if (Type.REMOVE_ITEM === type) { this.removeItem(bufData); this._pruneItems(); this.emit("item-removed", id, bufData); + this.log.debug( + `Item removed: ${bufData.toString("hex")} from ${id.toString( + "hex" + )}` + ); } } } else if (type === Type.CONNECTED) { const { id: toId } = decoded; - this._addEntityConnection(id, b4a.from(toId as Uint8Array) as Buffer); - this.emit("peer-add-seen", id, toId); + let bufId = b4a.from(toId as Uint8Array) as Buffer; + + this._addEntityConnection(id, bufId); + this.emit("peer-add-seen", id, bufId); this._recalculate(); + this.log.debug(`Network peer connected: ${bufId.toString("hex")}`); } else if (type === Type.DISCONNECTED) { const { id: toId } = decoded; + let bufId = b4a.from(toId as Uint8Array) as Buffer; + this._removeEntityConnection(id, b4a.from(toId as Uint8Array) as Buffer); this.emit("peer-remove-seen", id, toId); this._recalculate(); this._pruneItems(); + + this.log.debug(`Network peer disconnected: ${bufId.toString("hex")}`); } else if (type === Type.BOOTSTRAP_REQUEST) { const bootstrap = this._getBootstrapInfo(); this.broadcast( @@ -282,18 +310,23 @@ export default class DHTCache extends EventEmitter { ), 0 ); + this.log.debug(`Bootstrap request received`); } else if (type === Type.BOOTSTRAP_RESPONSE) { const { bootstrap } = decoded; this._bootstrapFrom(bootstrap); } else if (type === Type.HEARTBEAT) { - let { id: toId, signature, data: bufData } = decoded; + const { id: toId, signature, data: bufData } = decoded; - toId = b4a.from(toId as Uint8Array); + let bufId = b4a.from(toId as Uint8Array) as Buffer; if (signature && crypto.verify(bufData, signature, id)) { - this._addEntityConnection(id, toId as Buffer); - this._setEntity(toId as Buffer, { heartbeat: Date.now() }); + this._addEntityConnection(id, bufId as Buffer); + this._setEntity(bufId as Buffer, { heartbeat: Date.now() }); } + + this.log.debug( + `Bootstrap response received from ${bufId.toString("hex")}` + ); } } @@ -439,6 +472,10 @@ export default class DHTCache extends EventEmitter { this._online = online; this.emit("online", online); + + this.log.debug( + `Online list updated: ${online.size} network peers online, ${offline.size} network peers offline and removed from DAG` + ); } private _maybeHexify(data: Buffer | string): string {