diff --git a/src/messages/hashQuery.ts b/src/messages/hashQuery.ts new file mode 100644 index 0000000..ed3bbf6 --- /dev/null +++ b/src/messages/hashQuery.ts @@ -0,0 +1,48 @@ +import { S5Node } from "#node.js"; +import { Peer } from "#types.js"; +import Unpacker from "#serialization/unpack.js"; +import { Multihash } from "#multihash.js"; + +export default async function ( + node: S5Node, + peer: Peer, + data: Unpacker, + rawData: Uint8Array, +) { + const hash = new Multihash(data.unpackBinary()); + const types = data.unpackList().map((item) => Number(item)); + + try { + const map = await node.getCachedStorageLocations(hash, types); + + if (Object.keys(map).length > 0) { + const availableNodes = [...map.keys()]; + node.services.p2p.sortNodesByScore(availableNodes); + + const entry = map.get(availableNodes[0]); + + peer.sendMessage(entry?.providerMessage as Uint8Array); + return; + } + } catch (e) { + node.logger.catched(e); + } + + const hashCode = hash.hashCode; + + if (node.hashQueryRoutingTable.has(hashCode)) { + if (!node.hashQueryRoutingTable[hashCode].includes(peer.id)) { + node.hashQueryRoutingTable[hashCode].push(peer.id); + } + return; + } + + node.hashQueryRoutingTable.set(hashCode, new Set([peer.id])); + for (const p of node.services.p2p.peers.values()) { + if (p.id !== peer.id) { + p.sendMessage(rawData); + } + } + + return; +} diff --git a/src/messages/index.ts b/src/messages/index.ts index 2419d1c..b5c8ba0 100644 --- a/src/messages/index.ts +++ b/src/messages/index.ts @@ -2,6 +2,7 @@ import { P2PMessageHandler } from "#types.js"; import handshakeOpen from "#messages/handshakeOpen.js"; import { protocolMethodHandshakeOpen, + protocolMethodHashQuery, protocolMethodRegistryQuery, protocolMethodSignedMessage, recordTypeRegistryEntry, @@ -11,6 +12,7 @@ import registryQuery from "#messages/registryQuery.js"; import registryEntry from "#messages/registryEntry.js"; import storageLocation from "#messages/storageLocation.js"; import signedMessage from "#messages/signedMessage.js"; +import hashQuery from "#messages/hashQuery.js"; const messages = new Map( Object.entries({ @@ -19,6 +21,7 @@ const messages = new Map( [recordTypeRegistryEntry]: registryEntry, [recordTypeStorageLocation]: storageLocation, [protocolMethodSignedMessage]: signedMessage, + [protocolMethodHashQuery]: hashQuery, }).map(([key, value]) => [Number(key), value]), );