Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .github/workflows/be-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ jobs:
type=raw,value=latest
type=sha

- name: Get commit date
id: commit-date
run: echo "date=$(git show -s --format=%cI ${{ github.sha }} | cut -c1-19 | sed 's/[:]/-/g')" >> $GITHUB_OUTPUT

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
Expand All @@ -78,3 +82,5 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION_TAG=${{ steps.commit-date.outputs.date }}
4 changes: 4 additions & 0 deletions be/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
FROM node:lts-slim AS base

ARG VERSION_TAG=dev
ENV VERSION_TAG=${VERSION_TAG}
LABEL version="${VERSION_TAG}"

WORKDIR /app

# Copy relevant files early for better caching
Expand Down
6 changes: 3 additions & 3 deletions be/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ libp2p:
logging:
level: info
# axiom:
# enabled: false
# dataset: your-dataset
# orgId: your-org-id
# enabled: true
# dataset: stashcrate-logs
# orgId: coding-nimbus-ovls
# token: your-token # Prefer environment variables AXIOM_TOKEN/AXIOM_ORG_ID/AXIOM_DATASET
# url: https://api.axiom.co
5 changes: 5 additions & 0 deletions be/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ const { libp2p, logging } = config;
const logger = initializeLogger(logging);
startToListenToErrors(logger);

// Log version information on startup
const versionTag = process.env.VERSION_TAG || "dev";
logger.info(`Version: ${versionTag}`);

const stdoutEmitter = new StdoutEmitter();

stdoutEmitter.on("data", (data) => {
Expand All @@ -29,6 +33,7 @@ try {
startLibp2pRelay({
announceMultiaddrs: libp2p.announceMultiaddrs,
listenMultiaddrs: libp2p.listenMultiaddrs,
versionTag,
});
} catch (error) {
logger.error({ error }, "Failed to start libp2p relay");
Expand Down
17 changes: 16 additions & 1 deletion be/src/start-libp2p-relay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
import { noise } from "@chainsafe/libp2p-noise";
import { yamux } from "@chainsafe/libp2p-yamux";
import type { RoomRegistrationProtocolResponses } from "@icod2/protocols";
import { initRoomRegistrationProtocol, shortenPeerId } from "@icod2/protocols";
import {
initRoomRegistrationProtocol,
PeerMessageExchangeProtocol,
shortenPeerId,
} from "@icod2/protocols";
import { autoNAT } from "@libp2p/autonat";
import { circuitRelayServer } from "@libp2p/circuit-relay-v2";
import { identify } from "@libp2p/identify";
Expand All @@ -22,11 +26,13 @@ import { getPeerIdFromEnv } from "./utils/get-or-create-peer-id.js";
export type Args = {
listenMultiaddrs: string[];
announceMultiaddrs?: string[];
versionTag?: string;
};

export async function startLibp2pRelay({
listenMultiaddrs,
announceMultiaddrs,
versionTag = "unknown",
}: Args) {
const logger = getLogger();
const privateKey = await getPeerIdFromEnv();
Expand Down Expand Up @@ -74,6 +80,11 @@ export async function startLibp2pRelay({
const peerId = libp2p.peerId.toString();
const multiaddrs = libp2p.getMultiaddrs();

const peerMessageExchange = new PeerMessageExchangeProtocol({
protocolId: "/icod2/relay-peer-message-exchange/1.0.0",
});
peerMessageExchange.initialize(libp2p);

logger.info(
{ peerId, shortPeerId: shortenPeerId(peerId) },
"Relay peer ready",
Expand Down Expand Up @@ -169,6 +180,10 @@ export async function startLibp2pRelay({
libp2p.addEventListener("peer:connect", (event) => {
const peerIdStr = event.detail.toString();
connectedPeers.add(peerIdStr);
peerMessageExchange.sendMessageToPeer(peerIdStr, {
type: "hello-from-relay",
message: `Hello my I'm a relay. My version is ${versionTag}`,
});
logger.info(
{
peerId: shortenPeerId(peerIdStr),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type PeerMessageExchangeProtocol,
usePeerMessageProto,
} from "../usePeerMessageProto";
import { useRelayPeerMessageProto } from "../useRelayPeerMessageProto";
import { type IgnoredErrors, ignoredErrors } from "./ignoredErrors";

export const useFollowerConnection = ({ roomToken }: { roomToken: string }) => {
Expand All @@ -21,6 +22,8 @@ export const useFollowerConnection = ({ roomToken }: { roomToken: string }) => {
onMessageListener: routerMng.currentCombinedRouter,
});

const relayMessageProto = useRelayPeerMessageProto();

const [error, setError] = useState<
Libp2pServiceErrors | ConnectionErrors | undefined
>(undefined);
Expand Down Expand Up @@ -51,7 +54,7 @@ export const useFollowerConnection = ({ roomToken }: { roomToken: string }) => {
onFailedToConnect: (error) => {
setFilteredError(error);
},
protos: [messageProto],
protos: [messageProto, relayMessageProto],
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type PeerMessageExchangeProtocol,
usePeerMessageProto,
} from "../usePeerMessageProto";
import { useRelayPeerMessageProto } from "../useRelayPeerMessageProto";
import { useRoomRegistration } from "../useRoomRegistrationProto";
import { type IgnoredErrors, ignoredErrors } from "./ignoredErrors";

Expand Down Expand Up @@ -56,6 +57,8 @@ export const useLeaderConnection = ({
onMessageListener: routerMng.currentCombinedRouter,
});

const relayMessageProto = useRelayPeerMessageProto();

const { isRelayReconnecting } = useLibp2p({
roomTokenProvider: roomTokenProvider,
connectedPeersStorage: connectedPeersStorage.current,
Expand All @@ -65,7 +68,7 @@ export const useLeaderConnection = ({
onFailedToConnect: (error) => {
setFilteredError(error);
},
protos: [roomRegistrationObject, messageProto],
protos: [roomRegistrationObject, messageProto, relayMessageProto],
dontDialDiscoveredPeers: true,
});

Expand Down
1 change: 1 addition & 0 deletions fe/src/services/libp2p/useRelayPeerMessageProto/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useRelayPeerMessageProto } from "./useRelayPeerMessageProto";
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { PeerMessageExchangeProtocol } from "@icod2/protocols";
import type { Libp2p } from "@libp2p/interface";
import { useEffect, useRef } from "react";

export const useRelayPeerMessageProto = () => {
const peerMessageProtoRef = useRef<PeerMessageExchangeProtocol | undefined>(
undefined,
);

useEffect(() => {
const peerMessageProto = new PeerMessageExchangeProtocol({
protocolId: "/icod2/relay-peer-message-exchange/1.0.0",
});

peerMessageProtoRef.current = peerMessageProto;
}, []);

return {
initialize: (libp2p: Libp2p) => {
peerMessageProtoRef.current?.initialize(libp2p);
},
peerMessageProtoRef,
};
};
34 changes: 21 additions & 13 deletions libs/protocols/src/peers-message-exchange-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ export class PeerMessageExchangeProtocol<
this.listener = onMessage;
}

initialize(libp2p: Libp2p) {
initialize(
libp2p: Libp2p,
{
skipHandleInitialization = false,
}: { skipHandleInitialization?: boolean } = {},
) {
console.log(
"initialize()",
`protocol: ${this.protocolId}`,
Expand All @@ -54,18 +59,21 @@ export class PeerMessageExchangeProtocol<
if (this.initialized) return;

this.libp2p = libp2p;
registerProtoHandle(this.protocolId, libp2p, (message, peerId) => {
const jsonMessage = parseJsonSafely(message);
if (!jsonMessage) return;
loggerGate.canLog &&
console.log(
"Received message from peer:",
shortenPeerId(peerId),
"message:",
jsonMessage,
);
this.listener?.(peerId, jsonMessage as TPeerMessagePayload, this);
});

if (skipHandleInitialization) {
registerProtoHandle(this.protocolId, libp2p, (message, peerId) => {
const jsonMessage = parseJsonSafely(message);
if (!jsonMessage) return;
loggerGate.canLog &&
console.log(
"Received message from peer:",
shortenPeerId(peerId),
"message:",
jsonMessage,
);
this.listener?.(peerId, jsonMessage as TPeerMessagePayload, this);
});
}

this.initialized = true;
}
Expand Down