Compare commits

...

9 Commits

Author SHA1 Message Date
semantic-release-bot 7dc4325056 chore(release): 0.1.0-develop.4 [skip ci]
# [0.1.0-develop.4](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.3...v0.1.0-develop.4) (2023-08-31)

### Bug Fixes

* add getter for networkId and hashQueryRoutingTable ([6ebc477](6ebc477449))
* ed25519.sign arguments are wrong order ([5585907](5585907591))
* fix object references ([e342982](e342982163))
* missing p2p object on S5Config ([b5e491b](b5e491b01a))
* need to store peer, set the id the pass it to onNewPeer ([7afc759](7afc759ece))
* need to use unpacked data from signed message ([35ebf74](35ebf74f4c))
* update registered messages ([87d1e6b](87d1e6b0b4))
2023-08-31 10:56:28 +00:00
Derrick Hammer 187367139d
Merge remote-tracking branch 'origin/develop' into develop 2023-08-31 06:55:30 -04:00
Derrick Hammer 87d1e6b0b4
fix: update registered messages 2023-08-31 06:54:16 -04:00
Derrick Hammer 35ebf74f4c
fix: need to use unpacked data from signed message 2023-08-31 06:53:52 -04:00
Derrick Hammer e342982163
fix: fix object references 2023-08-31 06:53:25 -04:00
Derrick Hammer 7afc759ece
fix: need to store peer, set the id the pass it to onNewPeer 2023-08-31 06:50:24 -04:00
Derrick Hammer 5585907591
fix: ed25519.sign arguments are wrong order 2023-08-31 06:49:59 -04:00
Derrick Hammer 6ebc477449
fix: add getter for networkId and hashQueryRoutingTable 2023-08-31 06:49:33 -04:00
Derrick Hammer b5e491b01a
fix: missing p2p object on S5Config 2023-08-31 06:18:59 -04:00
12 changed files with 82 additions and 36 deletions

View File

@ -1,3 +1,16 @@
# [0.1.0-develop.4](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.3...v0.1.0-develop.4) (2023-08-31)
### Bug Fixes
* add getter for networkId and hashQueryRoutingTable ([6ebc477](https://git.lumeweb.com/LumeWeb/libs5/commit/6ebc477449ca8893a2e5e37310575e0c5e7dc444))
* ed25519.sign arguments are wrong order ([5585907](https://git.lumeweb.com/LumeWeb/libs5/commit/5585907591c0275de5a229db99584c6ea3eb12d2))
* fix object references ([e342982](https://git.lumeweb.com/LumeWeb/libs5/commit/e342982163fe957be516f9fc07afdedd440a76f9))
* missing p2p object on S5Config ([b5e491b](https://git.lumeweb.com/LumeWeb/libs5/commit/b5e491b01a7a91fa2dd518e0ea260ac0b50c3a60))
* need to store peer, set the id the pass it to onNewPeer ([7afc759](https://git.lumeweb.com/LumeWeb/libs5/commit/7afc759ece228b148f56d0e3203f0406f4820ffa))
* need to use unpacked data from signed message ([35ebf74](https://git.lumeweb.com/LumeWeb/libs5/commit/35ebf74f4ca55281c1a402d058aad79b7ca86199))
* update registered messages ([87d1e6b](https://git.lumeweb.com/LumeWeb/libs5/commit/87d1e6b0b4f4b7ec7ae9af85b9afae5c4eaa8630))
# [0.1.0-develop.3](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.2...v0.1.0-develop.3) (2023-08-31) # [0.1.0-develop.3](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.2...v0.1.0-develop.3) (2023-08-31)
# [0.1.0-develop.2](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.1...v0.1.0-develop.2) (2023-08-31) # [0.1.0-develop.2](https://git.lumeweb.com/LumeWeb/libs5/compare/v0.1.0-develop.1...v0.1.0-develop.2) (2023-08-31)

4
npm-shrinkwrap.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@lumeweb/libs5", "name": "@lumeweb/libs5",
"version": "0.1.0-develop.3", "version": "0.1.0-develop.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@lumeweb/libs5", "name": "@lumeweb/libs5",
"version": "0.1.0-develop.3", "version": "0.1.0-develop.4",
"dependencies": { "dependencies": {
"@noble/curves": "^1.1.0", "@noble/curves": "^1.1.0",
"@noble/hashes": "^1.3.1", "@noble/hashes": "^1.3.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@lumeweb/libs5", "name": "@lumeweb/libs5",
"version": "0.1.0-develop.3", "version": "0.1.0-develop.4",
"type": "module", "type": "module",
"main": "lib/index.js", "main": "lib/index.js",
"repository": { "repository": {

View File

@ -10,6 +10,7 @@ export default async function (
data: Unpacker, data: Unpacker,
rawData: Uint8Array, rawData: Uint8Array,
) { ) {
const p2p = node.services.p2p;
const p = new Packer(); const p = new Packer();
p.packInt(protocolMethodHandshakeDone); p.packInt(protocolMethodHandshakeDone);
p.packBinary(data.unpackBinary()); p.packBinary(data.unpackBinary());
@ -18,16 +19,16 @@ export default async function (
peerNetworkId = data.unpackString(); peerNetworkId = data.unpackString();
} catch {} } catch {}
if (this.networkId && peerNetworkId !== this.networkId) { if (node.services.p2p.networkId && peerNetworkId !== p2p.networkId) {
throw `Peer is in different network: ${peerNetworkId}`; throw `Peer is in different network: ${peerNetworkId}`;
} }
p.packInt(supportedFeatures); p.packInt(supportedFeatures);
p.packInt(node.services.p2p.selfConnectionUris.length); p.packInt(p2p.selfConnectionUris.length);
for (const uri of this.selfConnectionUris) { for (const uri of p2p.selfConnectionUris) {
p.packString(uri.toString()); p.packString(uri.toString());
} }
// TODO Protocol version // TODO Protocol version
// p.packInt(protocolVersion); // p.packInt(protocolVersion);
peer.sendMessage(await this.signMessageSimple(p.takeBytes())); peer.sendMessage(await p2p.signMessageSimple(p.takeBytes()));
} }

View File

@ -1,9 +1,24 @@
import { P2PMessageHandler } from "#types.js"; import { P2PMessageHandler } from "#types.js";
import handshakeOpen from "#messages/handshakeOpen.js"; import handshakeOpen from "#messages/handshakeOpen.js";
import {
protocolMethodHandshakeOpen,
protocolMethodRegistryQuery,
protocolMethodSignedMessage,
recordTypeRegistryEntry,
recordTypeStorageLocation,
} from "#constants.js";
import registryQuery from "#messages/registryQuery.js";
import registryEntry from "#messages/registryEntry.js";
import storageLocation from "#messages/storageLocation.js";
import signedMessage from "#messages/signedMessage.js";
const messages = new Map<number, P2PMessageHandler>( const messages = new Map<number, P2PMessageHandler>(
Object.entries({ Object.entries({
protocolMethodHandshakeOpen: handshakeOpen, [protocolMethodHandshakeOpen]: handshakeOpen,
[protocolMethodRegistryQuery]: registryQuery,
[recordTypeRegistryEntry]: registryEntry,
[recordTypeStorageLocation]: storageLocation,
[protocolMethodSignedMessage]: signedMessage,
}).map(([key, value]) => [Number(key), value]), }).map(([key, value]) => [Number(key), value]),
); );

View File

@ -12,7 +12,7 @@ export default async function (
) { ) {
const sm = await node.services.p2p.unpackAndVerifySignature(data); const sm = await node.services.p2p.unpackAndVerifySignature(data);
const u = Unpacker.fromPacked(sm.message); const u = Unpacker.fromPacked(sm.message);
const method = data.unpackInt(); const method = u.unpackInt();
if (method !== null && messages.has(method)) { if (method !== null && messages.has(method)) {
await messages.get(method)?.(node, peer, u, sm, verifyId); await messages.get(method)?.(node, peer, u, sm, verifyId);

View File

@ -14,6 +14,7 @@ export default async function (
) { ) {
const length = data.unpackInt() as number; const length = data.unpackInt() as number;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
const p2p = node.services.p2p;
const peerIdBinary = data.unpackBinary(); const peerIdBinary = data.unpackBinary();
const id = new NodeId(peerIdBinary); const id = new NodeId(peerIdBinary);
@ -31,8 +32,8 @@ export default async function (
// TODO Fully support multiple connection uris // TODO Fully support multiple connection uris
const uri = new URL(connectionUris[0].toString()); const uri = new URL(connectionUris[0].toString());
uri.username = id.toBase58(); uri.username = id.toBase58();
if (!this.reconnectDelay.has(NodeId.decode(uri.username).toString())) { if (!p2p.reconnectDelay.has(NodeId.decode(uri.username).toString())) {
node.services.p2p.connectToNode([uri]); p2p.connectToNode([uri]);
} }
} }
} }

View File

@ -11,6 +11,7 @@ export default async function (
message: SignedMessage, message: SignedMessage,
verifyId: boolean, verifyId: boolean,
) { ) {
const p2p = node.services.p2p;
const challenge = data.unpackBinary(); const challenge = data.unpackBinary();
if (!equalBytes(peer.challenge, challenge)) { if (!equalBytes(peer.challenge, challenge)) {
@ -35,8 +36,8 @@ export default async function (
throw "Remote node does not support required features"; throw "Remote node does not support required features";
} }
node.services.p2p.peers.set(peer.id.toString(), peer); p2p.peers.set(peer.id.toString(), peer);
node.services.p2p.reconnectDelay.set(peer.id.toString(), 1); p2p.reconnectDelay.set(peer.id.toString(), 1);
const connectionUrisCount = data.unpackInt() as number; const connectionUrisCount = data.unpackInt() as number;
@ -45,21 +46,18 @@ export default async function (
peer.connectionUris.push(new URL(data.unpackString() as string)); peer.connectionUris.push(new URL(data.unpackString() as string));
} }
this.logger.info( node.logger.info(
`[+] ${peer.id.toString()} (${peer.renderLocationUri().toString()})`, `[+] ${peer.id.toString()} (${peer.renderLocationUri().toString()})`,
); );
node.services.p2p.sendPublicPeersToPeer( p2p.sendPublicPeersToPeer(peer, Array.from(p2p.peers.values()));
peer, for (const p of p2p.peers.values()) {
Array.from(node.services.p2p.peers.values()),
);
for (const p of this._peers.values()) {
if (p.id.equals(peer.id)) { if (p.id.equals(peer.id)) {
continue; continue;
} }
if (p.isConnected) { if (p.isConnected) {
this.sendPublicPeersToPeer(p, [peer]); p2p.sendPublicPeersToPeer(p, [peer]);
} }
} }
} }

View File

@ -1,9 +1,15 @@
import { P2PSignedMessageHandler } from "#types.js"; import { P2PSignedMessageHandler } from "#types.js";
import handshakeDone from "#messages/signedMessages/handshakeDone.js"; import handshakeDone from "#messages/signedMessages/handshakeDone.js";
import {
protocolMethodAnnouncePeers,
protocolMethodHandshakeDone,
} from "#constants.js";
import announcePeers from "#messages/signedMessages/announcePeers.js";
const messages = new Map<number, P2PSignedMessageHandler>( const messages = new Map<number, P2PSignedMessageHandler>(
Object.entries({ Object.entries({
protocolMethodHandshakeOpen: handshakeDone, [protocolMethodHandshakeDone]: handshakeDone,
[protocolMethodAnnouncePeers]: announcePeers,
}).map(([key, value]) => [Number(key), value]), }).map(([key, value]) => [Number(key), value]),
); );

View File

@ -14,6 +14,7 @@ export default async function (
data: Unpacker, data: Unpacker,
rawData: Uint8Array, rawData: Uint8Array,
) { ) {
const p2p = node.services.p2p;
const hash = new Multihash(rawData.subarray(1, 34)); const hash = new Multihash(rawData.subarray(1, 34));
const type = rawData[34]; const type = rawData[34];
const expiry = decodeEndian(rawData.subarray(35, 39)); const expiry = decodeEndian(rawData.subarray(35, 39));
@ -53,10 +54,10 @@ export default async function (
nodeId, nodeId,
location: new StorageLocation(type, parts, expiry), location: new StorageLocation(type, parts, expiry),
message: rawData, message: rawData,
config: this.node.config, config: node.config,
}); });
const list = this.hashQueryRoutingTable.get(hash) || new Set<NodeId>(); const list = p2p.hashQueryRoutingTable.get(hash) || new Set<NodeId>();
for (const peerId of list) { for (const peerId of list) {
if (peerId.equals(nodeId)) { if (peerId.equals(nodeId)) {
continue; continue;
@ -65,11 +66,11 @@ export default async function (
continue; continue;
} }
if (this._peers.has(peerId.toString())) { if (p2p.peers.has(peerId.toString())) {
try { try {
this._peers.get(peerId.toString())?.sendMessage(event); p2p.peers.get(peerId.toString())?.sendMessage(rawData);
} catch (e) { } catch (e) {
this.logger.catched(e); node.logger.catched(e);
} }
} }
} }

View File

@ -70,6 +70,7 @@ export class S5Node {
logger: this._nodeConfig.logger ?? DEFAULT_LOGGER, logger: this._nodeConfig.logger ?? DEFAULT_LOGGER,
cacheDb: this._nodeConfig.db.sublevel("s5-object-cache", {}), cacheDb: this._nodeConfig.db.sublevel("s5-object-cache", {}),
services: {} as any, services: {} as any,
p2p: this._nodeConfig.p2p,
}; };
const p2p = new P2PService(this); const p2p = new P2PService(this);

View File

@ -31,24 +31,34 @@ export class P2PService {
private logger: Logger; private logger: Logger;
private nodeKeyPair: KeyPairEd25519; private nodeKeyPair: KeyPairEd25519;
private localNodeId?: NodeId; private localNodeId?: NodeId;
private networkId?: string;
private nodesDb?: AbstractSublevel< private nodesDb?: AbstractSublevel<
AbstractLevel<Uint8Array, string, Uint8Array>, AbstractLevel<Uint8Array, string, Uint8Array>,
Uint8Array, Uint8Array,
string, string,
Uint8Array Uint8Array
>; >;
private hashQueryRoutingTable: Map<Multihash, Set<NodeId>> = new Map();
constructor(node: S5Node) { constructor(node: S5Node) {
this._node = node; this._node = node;
this.networkId = node.config.p2p?.network; this._networkId = node.config.p2p?.network;
this.nodeKeyPair = node.config.keyPair; this.nodeKeyPair = node.config.keyPair;
this.logger = node.logger; this.logger = node.logger;
node.config.services.p2p = this; node.config.services.p2p = this;
} }
private _hashQueryRoutingTable: Map<Multihash, Set<NodeId>> = new Map();
get hashQueryRoutingTable(): Map<Multihash, Set<NodeId>> {
return this._hashQueryRoutingTable;
}
private _networkId?: string;
get networkId(): string {
return this._networkId as string;
}
private _node: S5Node; private _node: S5Node;
get node(): S5Node { get node(): S5Node {
@ -92,8 +102,8 @@ export class P2PService {
const initialAuthPayloadPacker = new Packer(); const initialAuthPayloadPacker = new Packer();
initialAuthPayloadPacker.packInt(protocolMethodHandshakeOpen); initialAuthPayloadPacker.packInt(protocolMethodHandshakeOpen);
initialAuthPayloadPacker.packBinary(Buffer.from(peer.challenge)); initialAuthPayloadPacker.packBinary(Buffer.from(peer.challenge));
if (this.networkId) { if (this._networkId) {
initialAuthPayloadPacker.packString(this.networkId); initialAuthPayloadPacker.packString(this._networkId);
} }
const completer = defer<void>(); const completer = defer<void>();
@ -224,7 +234,7 @@ export class P2PService {
async signMessageSimple(message: Uint8Array): Promise<Uint8Array> { async signMessageSimple(message: Uint8Array): Promise<Uint8Array> {
const packer = new Packer(); const packer = new Packer();
const signature = ed25519.sign(this.nodeKeyPair.extractBytes(), message); const signature = ed25519.sign(message, this.nodeKeyPair.extractBytes());
packer.packInt(protocolMethodSignedMessage); packer.packInt(protocolMethodSignedMessage);
packer.packBinary(Buffer.from(this.localNodeId!.bytes)); packer.packBinary(Buffer.from(this.localNodeId!.bytes));
@ -309,10 +319,10 @@ export class P2PService {
this.logger.verbose(`[connect] ${connectionUri}`); this.logger.verbose(`[connect] ${connectionUri}`);
const socket = await createTransportSocket(protocol, connectionUri); const socket = await createTransportSocket(protocol, connectionUri);
await this.onNewPeer( const peer = createTransportPeer(protocol, socket, [connectionUri]);
createTransportPeer(protocol, socket, [connectionUri]),
true, peer.id = id;
); await this.onNewPeer(peer, true);
} catch (e) { } catch (e) {
if (retried) { if (retried) {
return; return;