Compare commits

..

2 Commits

Author SHA1 Message Date
Derrick Hammer 52a0e41ca2
*Update dist 2022-12-05 06:59:58 -05:00
Derrick Hammer 8ecd021a1d
*Add heartbeat support to protocol 2022-12-05 06:59:46 -05:00
9 changed files with 130 additions and 11 deletions

4
dist/index.d.ts vendored
View File

@ -24,7 +24,7 @@ export default class DHTCache extends EventEmitter {
private _online;
get online(): Set<string>;
broadcast(message: any, ttl?: number): void;
send(message: any): void;
send(peer: any, message: any): void;
protected addPeerHandler(peer: any): void;
removePeerHandler(peer: any): void;
protected onRemovePeer(peer: any): void;
@ -43,5 +43,7 @@ export default class DHTCache extends EventEmitter {
private _recalculate;
private _maybeHexify;
private _pruneItems;
private _heartbeatCheck;
private _emitHeartbeat;
}
//# sourceMappingURL=index.d.ts.map

2
dist/index.d.ts.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAYlC,OAAO,QAAQ,MAAM,oBAAoB,CAAC;AAa1C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,YAAY;IAChD,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC;IACrB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAW;IAE9B,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAGxB,KAAK,EAAE,GAAG,EACV,EACE,EAA4B,EAC5B,GAAG,IAAI,EACR,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAO;IAkC7C,OAAO,CAAC,MAAM,CAAc;IAE5B,IAAW,KAAK,IAAI,MAAM,EAAE,CAE3B;IAED,IAAW,QAAQ,IAAI,MAAM,EAAE,CAU9B;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAOlE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAsBpC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIlB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IA2BjD,OAAO,CAAC,OAAO,CAAc;IAE7B,IAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAE/B;IAEM,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM;IAIpC,IAAI,CAAC,OAAO,EAAE,GAAG;IAIxB,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG;IA2BlC,iBAAiB,CAAC,IAAI,EAAE,GAAG;IAW3B,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG;IAmBhC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAyDpD,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,YAAY;IA+BpB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,WAAW;CAyBpB"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAYlC,OAAO,QAAQ,MAAM,oBAAoB,CAAC;AAa1C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,YAAY;IAChD,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC;IACrB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAW;IAE9B,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAGxB,KAAK,EAAE,GAAG,EACV,EACE,EAA4B,EAC5B,GAAG,IAAI,EACR,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAO;IAoC7C,OAAO,CAAC,MAAM,CAAc;IAE5B,IAAW,KAAK,IAAI,MAAM,EAAE,CAE3B;IAED,IAAW,QAAQ,IAAI,MAAM,EAAE,CAU9B;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAOlE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAsBpC,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIlB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IA2BjD,OAAO,CAAC,OAAO,CAAc;IAE7B,IAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAE/B;IAEM,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM;IAIpC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;IAInC,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG;IA6BlC,iBAAiB,CAAC,IAAI,EAAE,GAAG;IAW3B,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG;IAmBhC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAkEpD,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,YAAY;IA+BpB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;CA2BvB"}

52
dist/index.js vendored
View File

@ -38,7 +38,7 @@ class DHTCache extends events_1.default {
this.flood.on("peer-open", (peer) => this.addPeerHandler(peer));
this.flood.on("peer-remove", (peer) => this.removePeerHandler(peer));
this.flood.on("message", (message, id) => this.onGetBroadcast(message, id));
this.swarm.on("connection", (peer) => this.flood.send(peer, b4a_1.default.from("hello"), 0));
this.swarm.on("connection", (peer) => this.send(peer, b4a_1.default.from("hello")));
[...this.swarm.peers.values()]
.map((item) => {
remotePublicKey: item.publicKey;
@ -48,6 +48,8 @@ class DHTCache extends events_1.default {
this.addPeerHandler(item);
});
this._ensurePeer(this.id);
setInterval(() => this._heartbeatCheck(), 5 * 1000);
setInterval(() => this._emitHeartbeat(), 60 * 1000);
}
_cache;
get cache() {
@ -123,8 +125,8 @@ class DHTCache extends events_1.default {
broadcast(message, ttl) {
this.flood.broadcast(message, ttl);
}
send(message) {
this.flood.send(message, 0);
send(peer, message) {
this.flood.send(peer, message, 0);
}
addPeerHandler(peer) {
const id = peer.remotePublicKey;
@ -141,6 +143,7 @@ class DHTCache extends events_1.default {
type: messages_js_1.Type.CONNECTED,
id,
});
this._emitHeartbeat(peer);
if (this.bootstrapped) {
return;
}
@ -220,6 +223,14 @@ class DHTCache extends events_1.default {
const { bootstrap } = decoded;
this._bootstrapFrom(bootstrap);
}
else if (type === messages_js_1.Type.HEARTBEAT) {
let { id: toId, signature, data: bufData } = decoded;
toId = b4a_1.default.from(toId);
if (signature && hypercore_crypto_1.default.verify(bufData, signature, id)) {
this._addEntityConnection(id, toId);
this._setEntity(toId, { heartbeat: Date.now() });
}
}
}
_signItem(item) {
item = this._maybeHexify(item);
@ -352,5 +363,40 @@ class DHTCache extends events_1.default {
}
})();
}
_heartbeatCheck() {
for (const peer of this.connectedTo) {
const pubkey = b4a_1.default.from(peer, "hex");
const heartbeat = this.graph.node.get(peer)?.heartbeat;
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
this.onRemovePeer({ remotePublicKey: pubkey });
continue;
}
if (heartbeat > 0 && Date.now() - heartbeat > 60 * 1000) {
conn.end();
}
}
}
_emitHeartbeat(peer) {
let peers = [...this.connectedTo];
if (peer) {
// @ts-ignore
peers = [b4a_1.default.from(peer.remotePublicKey).toString("hex")];
}
for (const peer of peers) {
const pubkey = b4a_1.default.from(peer, "hex");
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
continue;
}
const data = b4a_1.default.from(Uint8Array.from([1]));
this.send(conn, this._compileMessage({
type: messages_js_1.Type.HEARTBEAT,
id: this.id,
data,
signature: hypercore_crypto_1.default.sign(data, this.swarm.keyPair.secretKey),
}));
}
}
}
exports.default = DHTCache;

6
dist/messages.d.ts vendored
View File

@ -71,7 +71,11 @@ export declare enum Type {
/**
* @generated from protobuf enum value: REMOVE_ITEM = 6;
*/
REMOVE_ITEM = 6
REMOVE_ITEM = 6,
/**
* @generated from protobuf enum value: HEARTBEAT = 7;
*/
HEARTBEAT = 7
}
declare class Message$Type extends MessageType<Message> {
constructor();

View File

@ -1 +1 @@
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,SAAS,EAAE;QACP,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;KACxB,CAAC;IACF;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,EAAE,CAAC,EAAE,UAAU,CAAC;CACnB;AACD;;GAEG;AACH,MAAM,WAAW,KAAK;IAClB;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B;AACD;;GAEG;AACH,oBAAY,IAAI;IACZ;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,iBAAiB,IAAI;IACrB;;OAEG;IACH,kBAAkB,IAAI;IACtB;;OAEG;IACH,SAAS,IAAI;IACb;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,QAAQ,IAAI;IACZ;;OAEG;IACH,WAAW,IAAI;CAClB;AAED,cAAM,YAAa,SAAQ,WAAW,CAAC,OAAO,CAAC;;IAU3C,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO;IAOhD,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO;IA+BhH,OAAO,CAAC,cAAc;IAgBtB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa;CAyB3G;AACD;;GAEG;AACH,eAAO,MAAM,OAAO,cAAqB,CAAC;AAE1C,cAAM,UAAW,SAAQ,WAAW,CAAC,KAAK,CAAC;;IAMvC,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,KAAK;IAO5C,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK;IAmB5G,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa;CASzG;AACD;;GAEG;AACH,eAAO,MAAM,KAAK,YAAmB,CAAC"}
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,SAAS,EAAE;QACP,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;KACxB,CAAC;IACF;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,EAAE,CAAC,EAAE,UAAU,CAAC;CACnB;AACD;;GAEG;AACH,MAAM,WAAW,KAAK;IAClB;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B;AACD;;GAEG;AACH,oBAAY,IAAI;IACZ;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,iBAAiB,IAAI;IACrB;;OAEG;IACH,kBAAkB,IAAI;IACtB;;OAEG;IACH,SAAS,IAAI;IACb;;OAEG;IACH,YAAY,IAAI;IAChB;;OAEG;IACH,QAAQ,IAAI;IACZ;;OAEG;IACH,WAAW,IAAI;IACf;;OAEG;IACH,SAAS,IAAI;CAChB;AAED,cAAM,YAAa,SAAQ,WAAW,CAAC,OAAO,CAAC;;IAU3C,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO;IAOhD,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO;IA+BhH,OAAO,CAAC,cAAc;IAgBtB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa;CAyB3G;AACD;;GAEG;AACH,eAAO,MAAM,OAAO,cAAqB,CAAC;AAE1C,cAAM,UAAW,SAAQ,WAAW,CAAC,KAAK,CAAC;;IAMvC,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,KAAK;IAO5C,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK;IAmB5G,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa;CASzG;AACD;;GAEG;AACH,eAAO,MAAM,KAAK,YAAmB,CAAC"}

4
dist/messages.js vendored
View File

@ -39,6 +39,10 @@ var Type;
* @generated from protobuf enum value: REMOVE_ITEM = 6;
*/
Type[Type["REMOVE_ITEM"] = 6] = "REMOVE_ITEM";
/**
* @generated from protobuf enum value: HEARTBEAT = 7;
*/
Type[Type["HEARTBEAT"] = 7] = "HEARTBEAT";
})(Type = exports.Type || (exports.Type = {}));
// @generated message type with reflection information, may provide speed optimized methods
class Message$Type extends runtime_5.MessageType {

View File

@ -7,6 +7,7 @@ enum Type {
DISCONNECTED = 4;
ADD_ITEM = 5;
REMOVE_ITEM = 6;
HEARTBEAT = 7;
}
message Message {

View File

@ -56,7 +56,7 @@ export default class DHTCache extends EventEmitter {
this.flood.on("message", (message, id) => this.onGetBroadcast(message, id));
this.swarm.on("connection", (peer: any) =>
this.flood.send(peer, b4a.from("hello"), 0)
this.send(peer, b4a.from("hello"))
);
[...this.swarm.peers.values()]
@ -69,6 +69,8 @@ export default class DHTCache extends EventEmitter {
});
this._ensurePeer(this.id);
setInterval(() => this._heartbeatCheck(), 5 * 1000);
setInterval(() => this._emitHeartbeat(), 60 * 1000);
}
private _cache: Set<string>;
@ -163,8 +165,8 @@ export default class DHTCache extends EventEmitter {
this.flood.broadcast(message, ttl);
}
public send(message: any) {
this.flood.send(message, 0);
public send(peer: any, message: any) {
this.flood.send(peer, message, 0);
}
protected addPeerHandler(peer: any) {
@ -186,6 +188,8 @@ export default class DHTCache extends EventEmitter {
id,
});
this._emitHeartbeat(peer);
if (this.bootstrapped) {
return;
}
@ -278,6 +282,15 @@ export default class DHTCache extends EventEmitter {
} else if (type === Type.BOOTSTRAP_RESPONSE) {
const { bootstrap } = decoded;
this._bootstrapFrom(bootstrap);
} else if (type === Type.HEARTBEAT) {
let { id: toId, signature, data: bufData } = decoded;
toId = b4a.from(toId as Uint8Array);
if (signature && crypto.verify(bufData, signature, id)) {
this._addEntityConnection(id, toId as Buffer);
this._setEntity(toId as Buffer, { heartbeat: Date.now() });
}
}
}
@ -447,4 +460,49 @@ export default class DHTCache extends EventEmitter {
}
})();
}
private _heartbeatCheck() {
for (const peer of this.connectedTo) {
const pubkey = b4a.from(peer, "hex");
const heartbeat = this.graph.node.get(peer)?.heartbeat;
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
this.onRemovePeer({ remotePublicKey: pubkey });
continue;
}
if (heartbeat > 0 && Date.now() - heartbeat > 60 * 1000) {
conn.end();
}
}
}
private _emitHeartbeat(peer?: any) {
let peers = [...this.connectedTo];
if (peer) {
// @ts-ignore
peers = [b4a.from(peer.remotePublicKey).toString("hex")];
}
for (const peer of peers) {
const pubkey = b4a.from(peer, "hex");
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
continue;
}
const data = b4a.from(Uint8Array.from([1]));
this.send(
conn,
this._compileMessage({
type: Type.HEARTBEAT,
id: this.id,
data,
signature: crypto.sign(data, this.swarm.keyPair.secretKey),
})
);
}
}
}

View File

@ -78,7 +78,11 @@ export enum Type {
/**
* @generated from protobuf enum value: REMOVE_ITEM = 6;
*/
REMOVE_ITEM = 6
REMOVE_ITEM = 6,
/**
* @generated from protobuf enum value: HEARTBEAT = 7;
*/
HEARTBEAT = 7
}
// @generated message type with reflection information, may provide speed optimized methods
class Message$Type extends MessageType<Message> {