Skip to content

Commit 28f0001

Browse files
authored
Merge pull request #618 from MatrixAI/feature-decentralized-signalling
Decentralized Signalling
2 parents af59e43 + 37ef800 commit 28f0001

66 files changed

Lines changed: 7297 additions & 7188 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

jest.config.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
const os = require('os');
21
const path = require('path');
3-
const fs = require('fs');
4-
const process = require('process');
52
const { pathsToModuleNameMapper } = require('ts-jest');
63
const { compilerOptions } = require('./tsconfig');
74

@@ -16,10 +13,6 @@ const globals = {
1613
projectDir: __dirname,
1714
// Absolute directory to the test root
1815
testDir: path.join(__dirname, 'tests'),
19-
// Default global data directory
20-
dataDir: fs.mkdtempSync(
21-
path.join(os.tmpdir(), 'polykey-test-global-'),
22-
),
2316
// Default asynchronous test timeout
2417
defaultTimeout: 20000,
2518
failedConnectionTimeout: 50000,
@@ -29,8 +22,8 @@ const globals = {
2922

3023
// The `globalSetup` and `globalTeardown` cannot access the `globals`
3124
// They run in their own process context
32-
// They can receive process environment
33-
process.env['GLOBAL_DATA_DIR'] = globals.dataDir;
25+
// They can however receive the process environment
26+
// Use `process.env` to set variables
3427

3528
module.exports = {
3629
testEnvironment: 'node',

src/PolykeyAgent.ts

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import type { DeepPartial, FileSystem, ObjectEmpty } from './types';
22
import type { PolykeyWorkerManagerInterface } from './workers/types';
33
import type { TLSConfig } from './network/types';
4-
import type { SeedNodes } from './nodes/types';
4+
import type { NodeAddress, NodeId, SeedNodes } from './nodes/types';
55
import type { Key, PasswordOpsLimit, PasswordMemLimit } from './keys/types';
66
import path from 'path';
77
import process from 'process';
88
import Logger from '@matrixai/logger';
99
import { DB } from '@matrixai/db';
10-
import { MDNS } from '@matrixai/mdns';
1110
import {
1211
CreateDestroyStartStop,
1312
ready,
@@ -76,7 +75,8 @@ type PolykeyAgentOptions = {
7675
rpcParserBufferSize: number;
7776
};
7877
nodes: {
79-
connectionIdleTimeoutTime: number;
78+
connectionIdleTimeoutTimeMin: number;
79+
connectionIdleTimeoutTimeScale: number;
8080
connectionFindConcurrencyLimit: number;
8181
connectionConnectTimeoutTime: number;
8282
connectionKeepAliveTimeoutTime: number;
@@ -160,8 +160,10 @@ class PolykeyAgent {
160160
rpcParserBufferSize: config.defaultsSystem.rpcParserBufferSize,
161161
},
162162
nodes: {
163-
connectionIdleTimeoutTime:
164-
config.defaultsSystem.nodesConnectionIdleTimeoutTime,
163+
connectionIdleTimeoutTimeMin:
164+
config.defaultsSystem.nodesConnectionIdleTimeoutTimeMin,
165+
connectionIdleTimeoutTimeScale:
166+
config.defaultsSystem.nodesConnectionIdleTimeoutTimeScale,
165167
connectionFindConcurrencyLimit:
166168
config.defaultsSystem.nodesConnectionFindConcurrencyLimit,
167169
connectionFindLocalTimeoutTime:
@@ -213,7 +215,6 @@ class PolykeyAgent {
213215
let gestaltGraph: GestaltGraph | undefined;
214216
let identitiesManager: IdentitiesManager | undefined;
215217
let nodeGraph: NodeGraph | undefined;
216-
let mdns: MDNS | undefined;
217218
let nodeConnectionManager: NodeConnectionManager | undefined;
218219
let nodeManager: NodeManager | undefined;
219220
let discovery: Discovery | undefined;
@@ -330,30 +331,20 @@ class PolykeyAgent {
330331
keyRing,
331332
logger: logger.getChild(NodeGraph.name),
332333
});
333-
mdns = new MDNS({
334-
logger: logger.getChild(MDNS.name),
335-
});
336-
await mdns.start({
337-
id: keyRing.getNodeId().toBuffer().readUint16BE(),
338-
hostname: nodesUtils.encodeNodeId(keyRing.getNodeId()),
339-
groups: optionsDefaulted.mdns.groups,
340-
port: optionsDefaulted.mdns.port,
341-
});
342334
// Remove your own node ID if provided as a seed node
343335
const nodeIdOwnEncoded = nodesUtils.encodeNodeId(keyRing.getNodeId());
344336
delete optionsDefaulted.seedNodes[nodeIdOwnEncoded];
345337
nodeConnectionManager = new NodeConnectionManager({
346338
keyRing,
347-
nodeGraph,
348339
tlsConfig,
349-
mdns,
350-
seedNodes: optionsDefaulted.seedNodes,
351340
connectionFindConcurrencyLimit:
352341
optionsDefaulted.nodes.connectionFindConcurrencyLimit,
353342
connectionFindLocalTimeoutTime:
354343
optionsDefaulted.nodes.connectionFindLocalTimeoutTime,
355-
connectionIdleTimeoutTime:
356-
optionsDefaulted.nodes.connectionIdleTimeoutTime,
344+
connectionIdleTimeoutTimeMin:
345+
optionsDefaulted.nodes.connectionIdleTimeoutTimeMin,
346+
connectionIdleTimeoutTimeScale:
347+
optionsDefaulted.nodes.connectionIdleTimeoutTimeScale,
357348
connectionConnectTimeoutTime:
358349
optionsDefaulted.nodes.connectionConnectTimeoutTime,
359350
connectionKeepAliveTimeoutTime:
@@ -374,22 +365,12 @@ class PolykeyAgent {
374365
nodeConnectionManager,
375366
taskManager,
376367
gestaltGraph,
368+
mdnsOptions: {
369+
groups: optionsDefaulted.mdns.groups,
370+
port: optionsDefaulted.mdns.port,
371+
},
377372
logger: logger.getChild(NodeManager.name),
378373
});
379-
await nodeManager.start();
380-
// Add seed nodes to the nodeGraph
381-
const setNodeProms = new Array<Promise<void>>();
382-
for (const nodeIdEncoded in optionsDefaulted.seedNodes) {
383-
const nodeId = nodesUtils.decodeNodeId(nodeIdEncoded);
384-
if (nodeId == null) utils.never();
385-
const setNodeProm = nodeManager.setNode(
386-
nodeId,
387-
optionsDefaulted.seedNodes[nodeIdEncoded],
388-
true,
389-
);
390-
setNodeProms.push(setNodeProm);
391-
}
392-
await Promise.all(setNodeProms);
393374
discovery = await Discovery.createDiscovery({
394375
db,
395376
keyRing,
@@ -403,7 +384,6 @@ class PolykeyAgent {
403384
await NotificationsManager.createNotificationsManager({
404385
acl,
405386
db,
406-
nodeConnectionManager,
407387
nodeManager,
408388
keyRing,
409389
logger: logger.getChild(NotificationsManager.name),
@@ -412,7 +392,7 @@ class PolykeyAgent {
412392
vaultManager = await VaultManager.createVaultManager({
413393
vaultsPath,
414394
keyRing,
415-
nodeConnectionManager,
395+
nodeManager,
416396
notificationsManager,
417397
gestaltGraph,
418398
acl,
@@ -458,7 +438,6 @@ class PolykeyAgent {
458438
await discovery?.stop();
459439
await identitiesManager?.stop();
460440
await gestaltGraph?.stop();
461-
await mdns?.stop();
462441
await acl?.stop();
463442
await sigchain?.stop();
464443
await certManager?.stop();
@@ -483,7 +462,6 @@ class PolykeyAgent {
483462
acl,
484463
gestaltGraph,
485464
nodeGraph,
486-
mdns,
487465
taskManager,
488466
nodeConnectionManager,
489467
nodeManager,
@@ -504,6 +482,7 @@ class PolykeyAgent {
504482
agentServicePort: optionsDefaulted.agentServicePort,
505483
workers: optionsDefaulted.workers,
506484
ipv6Only: optionsDefaulted.ipv6Only,
485+
seedNodes: optionsDefaulted.seedNodes,
507486
},
508487
fresh,
509488
});
@@ -523,7 +502,6 @@ class PolykeyAgent {
523502
public readonly acl: ACL;
524503
public readonly gestaltGraph: GestaltGraph;
525504
public readonly nodeGraph: NodeGraph;
526-
public readonly mdns: MDNS;
527505
public readonly taskManager: TaskManager;
528506
public readonly nodeConnectionManager: NodeConnectionManager;
529507
public readonly nodeManager: NodeManager;
@@ -570,7 +548,6 @@ class PolykeyAgent {
570548
acl,
571549
gestaltGraph,
572550
nodeGraph,
573-
mdns,
574551
taskManager,
575552
nodeConnectionManager,
576553
nodeManager,
@@ -594,7 +571,6 @@ class PolykeyAgent {
594571
acl: ACL;
595572
gestaltGraph: GestaltGraph;
596573
nodeGraph: NodeGraph;
597-
mdns: MDNS;
598574
taskManager: TaskManager;
599575
nodeConnectionManager: NodeConnectionManager;
600576
nodeManager: NodeManager;
@@ -620,7 +596,6 @@ class PolykeyAgent {
620596
this.gestaltGraph = gestaltGraph;
621597
this.discovery = discovery;
622598
this.nodeGraph = nodeGraph;
623-
this.mdns = mdns;
624599
this.taskManager = taskManager;
625600
this.nodeConnectionManager = nodeConnectionManager;
626601
this.nodeManager = nodeManager;
@@ -681,6 +656,7 @@ class PolykeyAgent {
681656
groups: Array<string>;
682657
port: number;
683658
};
659+
seedNodes: SeedNodes;
684660
}>;
685661
workers?: number;
686662
fresh?: boolean;
@@ -698,6 +674,7 @@ class PolykeyAgent {
698674
groups: config.defaultsSystem.mdnsGroups,
699675
port: config.defaultsSystem.mdnsPort,
700676
},
677+
seedNodes: config.defaultsUser.seedNodes,
701678
});
702679
// Register event handlers
703680
this.certManager.addEventListener(
@@ -768,18 +745,11 @@ class PolykeyAgent {
768745
host: optionsDefaulted.clientServiceHost,
769746
port: optionsDefaulted.clientServicePort,
770747
});
771-
await this.mdns.start({
772-
id: this.keyRing.getNodeId().toBuffer().readUint16BE(),
773-
hostname: nodesUtils.encodeNodeId(this.keyRing.getNodeId()),
774-
groups: optionsDefaulted.mdns.groups,
775-
port: optionsDefaulted.mdns.port,
776-
});
777-
await this.nodeManager.start();
778748
await this.nodeConnectionManager.start({
779749
host: optionsDefaulted.agentServiceHost,
780750
port: optionsDefaulted.agentServicePort,
781751
ipv6Only: optionsDefaulted.ipv6Only,
782-
manifest: agentServerManifest({
752+
agentService: agentServerManifest({
783753
acl: this.acl,
784754
db: this.db,
785755
keyRing: this.keyRing,
@@ -792,8 +762,39 @@ class PolykeyAgent {
792762
vaultManager: this.vaultManager,
793763
}),
794764
});
765+
await this.nodeManager.start();
766+
// Add seed nodes to the nodeGraph
767+
const setNodeProms = new Array<Promise<void>>();
768+
for (const nodeIdEncoded in optionsDefaulted.seedNodes) {
769+
const nodeId = nodesUtils.decodeNodeId(nodeIdEncoded);
770+
if (nodeId == null) utils.never();
771+
const setNodeProm = this.nodeManager.setNode(
772+
nodeId,
773+
optionsDefaulted.seedNodes[nodeIdEncoded],
774+
{
775+
mode: 'direct',
776+
connectedTime: 0,
777+
scopes: ['global'],
778+
},
779+
true,
780+
);
781+
setNodeProms.push(setNodeProm);
782+
}
783+
await Promise.all(setNodeProms);
795784
await this.nodeGraph.start({ fresh });
796-
await this.nodeManager.syncNodeGraph(false);
785+
const seedNodeEntries = Object.entries(
786+
optionsDefaulted.seedNodes as SeedNodes,
787+
);
788+
if (seedNodeEntries.length > 0) {
789+
const initialNodes = seedNodeEntries.map(
790+
([nodeIdEncoded, nodeAddress]) => {
791+
const nodeId = nodesUtils.decodeNodeId(nodeIdEncoded);
792+
if (nodeId == null) utils.never('nodeId should be defined');
793+
return [nodeId, nodeAddress] as [NodeId, NodeAddress];
794+
},
795+
);
796+
await this.nodeManager.syncNodeGraph(initialNodes, undefined, false);
797+
}
797798
await this.discovery.start({ fresh });
798799
await this.vaultManager.start({ fresh });
799800
await this.notificationsManager.start({ fresh });
@@ -838,7 +839,6 @@ class PolykeyAgent {
838839
await this.vaultManager?.stop();
839840
await this.discovery?.stop();
840841
await this.nodeGraph?.stop();
841-
await this.mdns?.stop();
842842
await this.nodeConnectionManager?.stop();
843843
await this.nodeManager?.stop();
844844
await this.clientService.stop({ force: true });
@@ -882,7 +882,6 @@ class PolykeyAgent {
882882
await this.clientService.stop({ force: true });
883883
await this.identitiesManager.stop();
884884
await this.gestaltGraph.stop();
885-
await this.mdns.stop();
886885
await this.acl.stop();
887886
await this.sigchain.stop();
888887
await this.certManager.stop();

src/bootstrap/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ async function bootstrapState({
195195
await NotificationsManager.createNotificationsManager({
196196
acl,
197197
db,
198-
nodeConnectionManager: {} as any, // No connections are attempted
199198
nodeManager,
200199
keyRing,
201200
logger: logger.getChild(NotificationsManager.name),
@@ -206,7 +205,7 @@ async function bootstrapState({
206205
db,
207206
gestaltGraph,
208207
keyRing,
209-
nodeConnectionManager: {} as any, // No connections are attempted
208+
nodeManager: {} as any, // No connections are attempted
210209
vaultsPath,
211210
notificationsManager,
212211
logger: logger.getChild(VaultManager.name),

src/client/handlers/NodesAdd.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
NodesAddMessage,
66
} from '../types';
77
import type { NodeId } from '../../ids';
8-
import type { Host, Hostname, Port } from '../../network/types';
8+
import type { Host, Port } from '../../network/types';
99
import type NodeManager from '../../nodes/NodeManager';
1010
import { UnaryHandler } from '@matrixai/rpc';
1111
import * as ids from '../../ids';
@@ -32,13 +32,13 @@ class NodesAdd extends UnaryHandler<
3232
port,
3333
}: {
3434
nodeId: NodeId;
35-
host: Host | Hostname;
35+
host: Host;
3636
port: Port;
3737
} = validateSync(
3838
(keyPath, value) => {
3939
return matchSync(keyPath)(
4040
[['nodeId'], () => ids.parseNodeId(value)],
41-
[['host'], () => networkUtils.parseHostOrHostname(value)],
41+
[['host'], () => networkUtils.parseHost(value)],
4242
[['port'], () => networkUtils.parsePort(value)],
4343
() => value,
4444
);
@@ -52,9 +52,7 @@ class NodesAdd extends UnaryHandler<
5252
// Pinging to authenticate the node
5353
if (
5454
(input.ping ?? false) &&
55-
!(await nodeManager.pingNode(nodeId, [
56-
{ host, port, scopes: ['global'] },
57-
]))
55+
!(await nodeManager.pingNodeAddress(nodeId, host, port))
5856
) {
5957
throw new nodeErrors.ErrorNodePingFailed(
6058
'Failed to authenticate target node',
@@ -64,9 +62,10 @@ class NodesAdd extends UnaryHandler<
6462
await db.withTransactionF((tran) =>
6563
nodeManager.setNode(
6664
nodeId,
65+
[host, port],
6766
{
68-
host,
69-
port,
67+
mode: 'direct',
68+
connectedTime: Date.now(),
7069
scopes: ['global'],
7170
},
7271
true,

0 commit comments

Comments
 (0)