Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scout #16

Merged
merged 45 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6883ca9
Make room for probeId in probe messages
michielbdejong Oct 1, 2024
bb5e7bf
Fix tests
michielbdejong Oct 1, 2024
4995e3d
Run tests to .out files
michielbdejong Oct 2, 2024
b718ab8
jerboa out
michielbdejong Oct 2, 2024
631756e
Some checks on probes and loop detection
michielbdejong Oct 2, 2024
5ba3130
npm start
michielbdejong Oct 2, 2024
9046547
split out considerProbe from receiveProbe
michielbdejong Oct 2, 2024
9059e50
dont resend probe to same out node
michielbdejong Oct 2, 2024
327d557
different results due to not repeating loop starts
michielbdejong Oct 2, 2024
9e793a6
Send loops for clearing
michielbdejong Oct 2, 2024
c7dfd25
Message objects
michielbdejong Oct 2, 2024
1f33904
Partially fix Jerboa tests
michielbdejong Oct 2, 2024
7c0102a
Fix Graph tests
michielbdejong Oct 2, 2024
34490cd
Fix missing command in scout message
michielbdejong Oct 2, 2024
a3f47d0
Jerboa tests passing
michielbdejong Oct 2, 2024
d333d98
It keeps retrying the same loops
michielbdejong Oct 2, 2024
4ddd1f6
Check Friend Cache after Adjust Sent / Received
michielbdejong Oct 3, 2024
27a3fd1
Check Friend Cache after Adjust Sent / Received
michielbdejong Oct 3, 2024
d9615ed
remove console.log statements
michielbdejong Oct 3, 2024
82455e4
Comment out transfer message in flight logging
michielbdejong Oct 3, 2024
3f7ffbc
log probeId in PROBING_REPORT messages
michielbdejong Oct 3, 2024
d247a27
Use node directly instead of through volta
michielbdejong Oct 3, 2024
5d43473
Use node directly instead of through volta
michielbdejong Oct 3, 2024
fdd8de7
Fix multiple in message reporting
michielbdejong Oct 3, 2024
b0b1748
Fix situation for node 19 in fixture-3k, ref #15
michielbdejong Oct 3, 2024
ef2461b
reduce logging level
michielbdejong Oct 3, 2024
70616f6
Add incarnation to probe and nack messages, ref #15
michielbdejong Oct 3, 2024
54d50ca
report incarnation on PROBING_REPORT
michielbdejong Oct 3, 2024
f5dffc2
increment incarnation
michielbdejong Oct 3, 2024
5007efc
Record incarnations of probe traffic
michielbdejong Oct 3, 2024
6678b6e
Add incarnation in scout message
michielbdejong Oct 3, 2024
d470a26
pick best probeSender to forward scout message to
michielbdejong Oct 3, 2024
9c0b35d
Include incarnation in propose message
michielbdejong Oct 3, 2024
36fc883
this.pickIncarnation
michielbdejong Oct 3, 2024
572c6b2
Fix #15
michielbdejong Oct 3, 2024
ab5eada
less logging
michielbdejong Oct 3, 2024
419d810
Detect when scout message leaves the loop
michielbdejong Oct 3, 2024
6d1733a
less verbose
michielbdejong Oct 3, 2024
c1fd129
Failed attempt to directly find out of an incoming probe is a looper …
michielbdejong Oct 3, 2024
75f3645
Change in to looper when loop is found
michielbdejong Oct 3, 2024
585324a
Reduce logging, fix #17
michielbdejong Oct 3, 2024
6e13b57
Merge pull request #18 from ledgerloops/track-looper-moves-separately
michielbdejong Oct 3, 2024
7a5f614
Fix #19
michielbdejong Oct 3, 2024
c7ff49f
Remove incorrect stats that are no longer being updated
michielbdejong Oct 3, 2024
c9b1a47
remove incorrect expectation
michielbdejong Oct 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- uses: volta-cli/action@v1
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- run: npm ci --no-audit
- run: npm run lint --if-present
- run: npm test
Expand Down
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,25 @@ now it takes 220 seconds:
npm install
npm test
npm run build
time node build/src/birdsEyeAnalysis.js __tests__/fixture-300.csv > birdseye-30.log
time node build/src/birdsEyeAnalysis.js __tests__/fixture-300.csv > birdseye-300.log
time node build/src/birdsEyeAnalysis.js __tests__/fixture-3000.csv > birdseye-3k.log
time node build/src/birdsEyeAnalysis.js __tests__/fixture-30000.csv > birdseye-30k.log
time node build/src/birdsEyeAnalysis.js __tests__/fixture-300000.csv > birdseye-300k.log

PROBING_REPORT=1 time node build/src/analysis.js __tests__/fixture-30.csv > jerboa-30.log
PROBING_REPORT=1 time node build/src/analysis.js __tests__/fixture-300.csv > jerboa-300.log
PROBING_REPORT=1 time node build/src/analysis.js __tests__/fixture-3000.csv > jerboa-3k.log
PROBING_REPORT=1 time node build/src/analysis.js __tests__/fixture-30000.csv > jerboa-30k.log
PROBING_REPORT=1 time node build/src/analysis.js __tests__/fixture-300000.csv > jerboa-300k.log

diff ./jerboa-30.log ./birdseye-30.log
diff ./jerboa-300.log ./birdseye-300.log
diff ./jerboa-3k.log ./birdseye-3k.log
diff ./jerboa-30k.log ./birdseye-30k.log
diff ./jerboa-300k.log ./birdseye-300k.log
npm start

time node build/src/birdsEyeAnalysis.js __tests__/fixture-30.csv > birdseye-30.out
time node build/src/birdsEyeAnalysis.js __tests__/fixture-300.csv > birdseye-300.out
time node build/src/birdsEyeAnalysis.js __tests__/fixture-3k.csv > birdseye-3k.out
time node build/src/birdsEyeAnalysis.js __tests__/fixture-30k.csv > birdseye-30k.out
time node build/src/birdsEyeAnalysis.js __tests__/fixture-300k.csv > birdseye-300k.out

PROBING_REPORT=1 time node build/src/main.js __tests__/fixture-30.csv > jerboa-30.out
PROBING_REPORT=1 time node build/src/main.js __tests__/fixture-300.csv > jerboa-300.out
PROBING_REPORT=1 time node build/src/main.js __tests__/fixture-3k.csv > jerboa-3k.out
PROBING_REPORT=1 time node build/src/main.js __tests__/fixture-30k.csv > jerboa-30k.out
PROBING_REPORT=1 time node build/src/main.js __tests__/fixture-300k.csv > jerboa-300k.out

diff ./jerboa-30.out ./birdseye-30.out
diff ./jerboa-300.out ./birdseye-300.out
diff ./jerboa-3k.out ./birdseye-3k.out
diff ./jerboa-30k.out ./birdseye-30k.out
diff ./jerboa-300k.out ./birdseye-300k.out
```

The diff output is expected to show that BirdsEyeAnalysis does more netting, because it nets after every transfer, and Jerboa only nets the balances after all transfers are finished.
The diff output is expected to show that BirdsEyeAnalysis does more netting, because it nets after every transfer, and Jerboa only nets the balances after all transfers are finished.
20 changes: 7 additions & 13 deletions __tests__/DLD.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ async function readCsv(callback: (from: string, to: string, amount: number) => v
describe('DLD', () => {
it('finds loops', async () => {
const dld = new DLD();
await readCsv(dld.graph.addWeight.bind(dld.graph));
await readCsv((source: string, target: string, weight: number) => {
dld.graph.addWeight(source,target, weight);
dld.graph.messaging.runTasks();
});
dld.runWorm();
let totalNum = 0;
let totalAmount = 0;
Expand All @@ -51,18 +54,9 @@ describe('DLD', () => {
}
});
expect([totalNum, totalAmount, dld.graph.stats]).toEqual([
1,
30,
{
"2": {
"numFound": 1,
"totalAmount": 0.5,
},
"3": {
"numFound": 1,
"totalAmount": 10,
},
},
0,
0,
{},
]);
});
});
3 changes: 3 additions & 0 deletions __tests__/Graph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('addWeight', () => {
it('nets a higher amount', () => {
const graph = new Graph();
graph.addWeight('a', 'b', 3);
graph.messaging.runTasks();
graph.addWeight('b', 'a', 7);
graph.messaging.runTasks();
expect(graph.getBalances()).toEqual({
Expand All @@ -73,6 +74,7 @@ describe('addWeight', () => {
it('nets a lower amount', () => {
const graph = new Graph();
graph.addWeight('a', 'b', 3);
graph.messaging.runTasks();
graph.addWeight('b', 'a', 2);
graph.messaging.runTasks();
expect(graph.getBalances()).toEqual({
Expand All @@ -87,6 +89,7 @@ describe('addWeight', () => {
it('nets an equal amount', () => {
const graph = new Graph();
graph.addWeight('a', 'b', 3);
graph.messaging.runTasks();
graph.addWeight('b', 'a', 3);
graph.messaging.runTasks();
expect(graph.getBalances()).toEqual({
Expand Down
46 changes: 31 additions & 15 deletions __tests__/Jerboa.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Jerboa } from '../src/Jerboa.js';
import { Jerboa, ProbeMessage } from '../src/Jerboa.js';
import { Graph } from '../src/Graph.js';
import { Messaging } from '../src/Messaging.js';
// jest.mock('../src/Graph.js');
Expand All @@ -10,7 +10,7 @@ describe('Jerboa', () => {
it ('returns false if it cannot initiate a probe', () => {
const graph = new Graph();
const a = new Jerboa('a', graph);
const result = a.startProbe();
const result = a.startProbe('probe-id');
expect(result).toEqual(false);
});
it ('initiates a probe if it can', () => {
Expand All @@ -19,37 +19,53 @@ describe('Jerboa', () => {
graph.messaging.sendMessage = jest.fn();
const a = new Jerboa('a', graph);
a.addWeight('b', 9);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['transfer', '9']);
const result = a.startProbe();
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', {"amount": 9, "command": "transfer"});
const result = a.startProbe('probe-id');
expect(result).toEqual(true);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['probe', '[]', '[]']);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', { command: 'probe', probeId: 'probe-id', incarnation: 0, debugInfo: {"path":[],"backtracked":[]} });
});
it('forwards a probe if it can', () => {
const graph = new Graph();
graph.messaging = new Messaging(graph);
graph.messaging.sendMessage = jest.fn();
const a = new Jerboa('a', graph);
a.addWeight('b', 9);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['transfer', '9']);
a.receiveMessage('x', ['probe', JSON.stringify(['b', 'c']), '[]']);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['probe', JSON.stringify(['b', 'c', 'x']), '[]']);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', {"amount": 9, "command": "transfer"});
a.receiveMessage('x', { command: 'probe', probeId: '1', incarnation: 123, debugInfo: { path: ['b', 'c'], backtracked: [] } } as ProbeMessage);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', { command: 'probe', probeId: '1', incarnation: 123, debugInfo: { path: ['b', 'c', 'x'], backtracked: []} });
});
it('splices off a loop if it can', () => {
const graph = new Graph();
graph.messaging = new Messaging(graph);
graph.messaging.sendMessage = jest.fn();
const a = new Jerboa('a', graph);
a.addWeight('b', 9);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['transfer', '9']);
a.receiveMessage('x', ['probe', JSON.stringify(['b', 'c', 'a', 'd']), '[]']); // so the loop is a-d-x-a and b-c-a is the old prefix
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'b', ['probe', JSON.stringify(['b', 'c']), '[]']);
// rather than calling `new Jerboa('d'), getting the Jerboas from the graph
// will allow them to query each other for debugging
// do note though that since we mocked graph.messaging, messages sent by these
// nodes will still not arrive:
const d = graph.getNode('d');
const e = graph.getNode('e');
const f = graph.getNode('f');
d.addWeight('e', 9);
e.receiveMessage('d', { command: 'transfer', amount: 9 });
e.addWeight('f', 9);
f.receiveMessage('e', { command: 'transfer', amount: 9 });
f.addWeight('d', 9);
d.receiveMessage('f', { command: 'transfer', amount: 9 });
expect(d.getBalances()).toEqual({ e: 9, f: -9 });
expect(e.getBalances()).toEqual({ f: 9, d: -9 });
expect(f.getBalances()).toEqual({ d: 9, e: -9 });
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('d', 'e', {"amount": 9, "command": "transfer"});
d.receiveMessage('c', { command: 'probe', probeId: 'probe-id', incarnation: 0, debugInfo: { path: ['a', 'b'], backtracked: [] } });
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('d', 'e', { command: 'probe', probeId: 'probe-id', incarnation: 0, debugInfo: { path: ['a', 'b', 'c'], backtracked: [] } });
d.receiveMessage('f', { command: 'probe', probeId: 'probe-id', incarnation: 0, debugInfo: { path: ['a', 'b', 'c', 'd', 'e'], backtracked: [] } }); // so the probe has P-looped as: a-b-c-[d-e-f-d]
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('d', 'f', { command: 'scout', probeId: 'probe-id', maxIncarnation: 0, amount: 9, debugInfo: { loop: ['d', 'e', 'f', 'd']} });
});
it ('replies with nack if it is a leaf', () => {
const graph = new Graph();
graph.messaging = new Messaging(graph);
graph.messaging.sendMessage = jest.fn();
const a = new Jerboa('a', graph);
a.receiveMessage('x', ['probe', '[]', '[]']);
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'x', ['nack', JSON.stringify([]), '[]']);
a.receiveMessage('x', { command: 'probe', probeId: 'probe-id', incarnation: 0, debugInfo: { path: [], backtracked: [] } });
expect(graph.messaging.sendMessage).toHaveBeenCalledWith('a', 'x', { command: 'nack', probeId: 'probe-id', incarnation: 0, debugInfo: { path: [], backtracked: []} });
});
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions birdseye-30.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Opening __tests__/fixture-30.csv
backtracked [ '5', '6' ] [ '8' ]
found loop [] [ '5', '6', '9', '5' ]
backtracked [ '5' ] [ '6' ]
finished [] [ '5', '8' ]
backtracked [ '9' ] [ '5' ]
finished [] [ '9', '8' ]
backtracked [ '10' ] [ '5' ]
finished [] [ '10', '11' ]
finished [] [ '12', '13' ]
finished [] [ '14', '5' ]
finished [] [ '15', '16' ]
finished [] [ '17', '11' ]
finished [] [ '18', '16' ]
Done after 23 steps
{
'2': { numFound: 7, totalAmount: 52.5 },
'3': { numFound: 1, totalAmount: 10 }
}
Graph has 0 nodes and 0 links left
After 22 transactions with a total amount of 0 million
0 million (8%) was immediately netted bilaterally
And a further 0 million (5%) was netted in 1 loops
Leaving 0 million (87%) to be settled out of band
Loading
Loading