From d15ab0a7ac683cf1f8798ab7631342f7b7a3f092 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Fri, 19 Apr 2024 11:36:27 +0200 Subject: [PATCH] Giraffe finds loops :) --- .../fixtures/batched-giraffe-hourglass.json | 6 ++- .../fixtures/batched-giraffe-triangle.json | 9 +++- src/engine/loopsengine.ts | 15 ++++++ src/giraffe.ts | 47 ++++++++++++------- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/__tests__/fixtures/batched-giraffe-hourglass.json b/__tests__/fixtures/batched-giraffe-hourglass.json index f7dd74d..615fd7b 100644 --- a/__tests__/fixtures/batched-giraffe-hourglass.json +++ b/__tests__/fixtures/batched-giraffe-hourglass.json @@ -117,7 +117,11 @@ "[TraceEngine] handling trace message from Dave: trace genRanHex0 genRanHex3 genRanHex5", "loop-found genRanHex0 genRanHex3" ], - "loopsFound": [] + "loopsFound": [ + "genRanHex0 genRanHex1", + "genRanHex0 genRanHex3", + "genRanHex0 genRanHex3" + ] }, "bob": { "debugLog": [ diff --git a/__tests__/fixtures/batched-giraffe-triangle.json b/__tests__/fixtures/batched-giraffe-triangle.json index fdcc61e..2c88d9d 100644 --- a/__tests__/fixtures/batched-giraffe-triangle.json +++ b/__tests__/fixtures/batched-giraffe-triangle.json @@ -128,7 +128,10 @@ "[TracesEngine] sending message to Charlie: trace genRanHex2 genRanHex8 genRanHex10", "[Node#sendTraceMessage] Alice sends trace message to Charlie: trace genRanHex2 genRanHex8 genRanHex10" ], - "loopsFound": [] + "loopsFound": [ + "genRanHex0 genRanHex3", + "genRanHex1 genRanHex5" + ] }, "bob": { "debugLog": [ @@ -197,7 +200,9 @@ "[TraceEngine] handling trace message from Charlie: trace genRanHex2 genRanHex8 genRanHex10", "loop-found genRanHex2 genRanHex8" ], - "loopsFound": [] + "loopsFound": [ + "genRanHex2 genRanHex8" + ] }, "charlie": { "debugLog": [ diff --git a/src/engine/loopsengine.ts b/src/engine/loopsengine.ts index e69de29..9b6e098 100644 --- a/src/engine/loopsengine.ts +++ b/src/engine/loopsengine.ts @@ -0,0 +1,15 @@ +import EventEmitter from "events"; + +export class LoopsEngine extends EventEmitter { + loops: string[]; + constructor() { + super(); + this.loops = []; + } + handleLoopFound(probeId: string, traceId: string): void { + this.loops.push(`${probeId} ${traceId}`); + } + getLoops(): string[] { + return this.loops; + } +} \ No newline at end of file diff --git a/src/giraffe.ts b/src/giraffe.ts index e552aba..cadf1db 100644 --- a/src/giraffe.ts +++ b/src/giraffe.ts @@ -4,20 +4,23 @@ import { getMessageType } from "./messages.js"; import { ProbesEngine } from "./engine/probesengine.js"; import { FriendsEngine } from "./engine/friendsengine.js"; import { TracesEngine } from "./engine/tracesengine.js"; +import { LoopsEngine } from "./engine/loopsengine.js"; export class Giraffe extends EventEmitter implements NetworkNode { - protected friendsengine: FriendsEngine; - protected probesengine: ProbesEngine; - protected tracesengine: TracesEngine; + protected friendsEngine: FriendsEngine; + protected probesEngine: ProbesEngine; + protected tracesEngine: TracesEngine; + protected loopsEngine: LoopsEngine; protected debugLog: string[] = []; protected name: string; constructor(name: string) { super(); this.name = name; - this.friendsengine = new FriendsEngine(name); - this.probesengine = this.connectProbesEngine(); - this.tracesengine = this.connectTracesEngine(this.probesengine); + this.friendsEngine = new FriendsEngine(name); + this.probesEngine = this.connectProbesEngine(); + this.tracesEngine = this.connectTracesEngine(this.probesEngine); + this.loopsEngine = this.connectLoopsEngine(this.tracesEngine); } protected connectProbesEngine(): ProbesEngine { const probesengine = new ProbesEngine(this.name); @@ -48,33 +51,43 @@ export class Giraffe extends EventEmitter implements NetworkNode { }); return tracesengine; } + protected connectLoopsEngine(traceEngine: TracesEngine): LoopsEngine { + const loopsEngine = new LoopsEngine(); + traceEngine.on('loop-found', (probeId: string, traceId: string) => { + loopsEngine.handleLoopFound(probeId, traceId); + }); + loopsEngine.on('debug', (message: string) => { + this.debugLog.push(message); + }); + return loopsEngine; + } process(sender: string, message: string): void { this.debugLog.push(`[Node#receiveMessage] ${this.name} receives message from ${sender}`); // console.log(`${this.name} receives message from ${sender}`, message); switch(getMessageType(message)) { case `meet`: return this.handleMeetMessage(sender); - case `probe`: return this.probesengine.handleProbeMessage(sender, message); - case `trace`: return this.tracesengine.handleTraceMessage(sender, message); + case `probe`: return this.probesEngine.handleProbeMessage(sender, message); + case `trace`: return this.tracesEngine.handleTraceMessage(sender, message); // case `loop`: return this.probesengine.handleTraceMessage(sender, message); - case `have-probes`: return this.probesengine.handleHaveProbesMessage(sender); - case `okay-to-send-probes`: return this.probesengine.handleOkayToSendProbesMessage(sender); + case `have-probes`: return this.probesEngine.handleHaveProbesMessage(sender); + case `okay-to-send-probes`: return this.probesEngine.handleOkayToSendProbesMessage(sender); } } meet(other: string, createProbe: boolean = true): void { - this.friendsengine.addFriend(other); + this.friendsEngine.addFriend(other); this.debugLog.push(`I meet ${other} [1/4]`); // this is safe to because it will just queue them for the next message round this.emit('message', other, 'meet'); this.debugLog.push(`I queue ${other} all my flood probes [2/4]`); - this.probesengine.addFriend(other, true, createProbe); + this.probesEngine.addFriend(other, true, createProbe); this.debugLog.push(`Done onMeet ${other} [4/4]`); } // when this node has received a `meet` message handleMeetMessage(sender: string): void { - this.friendsengine.addFriend(sender); + this.friendsEngine.addFriend(sender); this.debugLog.push(`MEET MESSAGE FROM ${sender}, queueing all flood probes`); - this.probesengine.addFriend(sender, false, false); + this.probesEngine.addFriend(sender, false, false); } getProbes(): { [id: string]: { @@ -88,7 +101,7 @@ export class Giraffe extends EventEmitter implements NetworkNode { }[] } } { - return this.probesengine.getProbes(); + return this.probesEngine.getProbes(); } getName(): string { return this.name; @@ -97,9 +110,9 @@ export class Giraffe extends EventEmitter implements NetworkNode { return this.debugLog; } getFriends(): string[] { - return Object.keys(this.friendsengine.getFriends()); + return Object.keys(this.friendsEngine.getFriends()); } getLoops(): string[] { - return []; + return this.loopsEngine.getLoops(); } }