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
2 changes: 1 addition & 1 deletion be/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

libp2p:
listenMultiaddrs:
- /ip4/127.0.0.1/tcp/8080/ws
- /ip4/0.0.0.0/tcp/8080/ws
announceMultiaddrs:
- /ip4/127.0.0.1/tcp/8080/ws
# - /dns4/example.com/tcp/443/wss Example of multiaddr with Secure WebSockets
Expand Down
22 changes: 22 additions & 0 deletions be/src/debug-utils/debugPrintGossipScore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { GossipSub } from "@chainsafe/libp2p-gossipsub";
import { shortenPeerId } from "@icod2/protocols";
import type { Libp2p } from "@libp2p/interface";
import type { Logger } from "src/logger.js";

export const debugPrintGossipScore = (libp2p: Libp2p, logger: Logger) => {
const gs = libp2p.services.pubsub as GossipSub;

const scores = Array.from(gs.peers.keys()).map((id: string) => ({
id: shortenPeerId(id),
score: gs.score.score(id),
}));

const mesh = Array.from(gs.mesh.entries()).map(
([topic, peers]: [string, Set<string>]) => ({
topic,
peers: Array.from(peers).map((p) => shortenPeerId(p)),
}),
);

logger.info({ scores, mesh }, "Gossipsub scores/mesh snapshot");
};
22 changes: 22 additions & 0 deletions be/src/debug-utils/debugPubSubMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { shortenPeerId } from "@icod2/protocols";
import type { PubSub } from "@libp2p/interface";
import type { Libp2p } from "libp2p";
import type { Logger } from "src/logger.js";

export const debugPubSubMessages = (
libp2p: Libp2p<{ pubsub: PubSub }>,
logger: Logger,
) => {
libp2p.services.pubsub.addEventListener("message", (e) => {
const msg = e.detail;
logger.info(
{
// @ts-expect-error
from: shortenPeerId(msg.from?.toString()),
topic: msg.topic,
dataLength: msg.data?.length ?? 0,
},
"Pubsub message on roomToken (might be discovery or app msg)",
);
});
};
24 changes: 23 additions & 1 deletion be/src/start-libp2p-relay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import type { Libp2p, PeerId, SubscriptionChangeData } from "@libp2p/interface";
import { tcp } from "@libp2p/tcp";
import { webSockets } from "@libp2p/websockets";
import { createLibp2p } from "libp2p";
import { debugPrintGossipScore } from "./debug-utils/debugPrintGossipScore.js";
import { debugPubSubMessages } from "./debug-utils/debugPubSubMessages.js";
import { getLogger } from "./logger.js";
import { starRoomRegistrationServiceStart } from "./services/room-registration.js";
import { debounce } from "./utils/debounce.js";
Expand Down Expand Up @@ -71,6 +73,22 @@ export async function startLibp2pRelay({
fallbackToFloodsub: true,
floodPublish: true,
doPX: true,
// Relax scoring so peers are not greylisted/pruned in small rooms
scoreParams: {
topics: {},
topicScoreCap: 0,
appSpecificScore: () => 0,
appSpecificWeight: 0,
IPColocationFactorWeight: 0,
behaviourPenaltyWeight: 0,
},
scoreThresholds: {
gossipThreshold: -1,
publishThreshold: -1,
graylistThreshold: -1,
acceptPXThreshold: 0,
opportunisticGraftThreshold: 0,
},
}) as (arg: GossipSubComponents) => GossipSub,
},
});
Expand All @@ -83,7 +101,7 @@ export async function startLibp2pRelay({
const peerMessageExchange = new PeerMessageExchangeProtocol({
protocolId: "/icod2/relay-peer-message-exchange/1.0.0",
});
peerMessageExchange.initialize(libp2p);
peerMessageExchange.initialize(libp2p, { skipHandleInitialization: false });

logger.info(
{ peerId, shortPeerId: shortenPeerId(peerId) },
Expand Down Expand Up @@ -233,6 +251,7 @@ export async function startLibp2pRelay({
const roomStats = getRoomStats();
logger.info({ roomStats }, "Subscription changed");
debouncedPrintInfoAboutPubSubTopics();
debugPrintGossipScore(libp2p, logger);
}

const debouncedLogPeerUpdated = debounce(peerUpdated, 2000);
Expand All @@ -250,6 +269,7 @@ export async function startLibp2pRelay({
function printInfoAboutPubSubTopics() {
const topics = getTopics();
logger.info({ topics }, "All Topics");
debugPrintGossipScore(libp2p, logger);
}

function peerUpdated(peerIdStr: string) {
Expand Down Expand Up @@ -278,6 +298,8 @@ export async function startLibp2pRelay({
return acc;
}, {});
}

debugPubSubMessages(libp2p, logger);
}

function formatConnectedPeers(peers: Set<string>): string[] {
Expand Down
54 changes: 53 additions & 1 deletion fe/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,63 @@
body {
margin: 0;
}

#root {
min-height: 100vh;
}

.preload {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif;
color: #c089ff;
background: transparent;
opacity: 0;
animation: preload-fade 1500ms ease forwards;
animation-delay: 750ms;
}

.preload__spinner {
width: 48px;
height: 48px;
border: 4px solid rgba(192, 137, 255, 0.25);
border-top-color: #c089ff;
border-radius: 50%;
animation: preload-spin 1s linear infinite;
margin-bottom: 12px;
}

@keyframes preload-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@keyframes preload-fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
<title>Stashcrate</title>
</head>
<body>
<div id="root"></div>
<div id="root">
<div class="preload">
<div class="preload__spinner"></div>
<p>Loading Stashcrate...</p>
</div>
</div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
45 changes: 23 additions & 22 deletions fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Theme } from "@radix-ui/themes";
import { type FC, lazy, useEffect, useState } from "react";
import { type FC, useEffect, useState } from "react";
import {
createBrowserRouter,
Link,
Expand All @@ -9,22 +9,6 @@ import {
import Welcome from "./components/Box/sub-pages/Welcome";
import { MainLayout } from "./components/layout/MainLayout";

const LazyUnlockBox = lazy(
() => import("./components/Box/sub-pages/RestoreBoxes/LockedBox"),
);
const LazyLockBox = lazy(() =>
import("./components/Box/sub-pages/CreationBoxes").then((mod) => ({
default: mod.RootLockBox,
})),
);
const LazyComponentsDemo = lazy(() => import("./components/ComponentsDemo"));
const LazyCryptoPlayground = lazy(
() => import("./components/CryptoPlayground"),
);
const LazyDecodePlayground = lazy(
() => import("./components/DecodePlayground"),
);

function useSystemTheme() {
const [theme, setTheme] = useState<"light" | "dark">("light");

Expand Down Expand Up @@ -83,23 +67,40 @@ const router = createBrowserRouter([
children: [
{
path: "/crypto-poc",
Component: LazyCryptoPlayground,
async lazy() {
const mod = await import("./components/CryptoPlayground");
return { Component: mod.default };
},
},
{
path: "/components-demo",
Component: LazyComponentsDemo,
async lazy() {
const mod = await import("./components/ComponentsDemo");
return { Component: mod.default };
},
},
{
path: "/decode-poc",
Component: LazyDecodePlayground,
async lazy() {
const mod = await import("./components/DecodePlayground");
return { Component: mod.default };
},
},
{
path: "/unlock-box/:roomToken?",
Component: LazyUnlockBox,
async lazy() {
const mod = await import(
"./components/Box/sub-pages/RestoreBoxes/LockedBox"
);
return { Component: mod.default };
},
},
{
path: "/lock-box/:roomToken?",
Component: LazyLockBox,
async lazy() {
const mod = await import("./components/Box/sub-pages/CreationBoxes");
return { Component: mod.RootLockBox };
},
},
{
path: "/",
Expand Down
53 changes: 32 additions & 21 deletions fe/src/components/Box/sub-pages/Welcome.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type React from "react";
import type { ReactNode } from "react";
import { Link } from "react-router-dom";
import { NavLink } from "react-router-dom";
import { Button } from "@/ui/Button";
import { Typography } from "@/ui/Typography";

Expand All @@ -16,31 +16,37 @@ const Welcome: React.FC = () => {
<>
<p className="my-1">Start by creating a box. You’ll:</p>
<ul className="my-1">
<li>- Define the message or content you want to protect.</li>
<li>Define the message or content you want to protect.</li>
<li>
- Invite other keyholders (your friends or devices) to join.
Invite other keyholders (your friends or devices) to join.
</li>
<li>
- Set a key threshold (e.g. 3 out of 5) — the number of
keyholders required to unlock the box later
Set a key threshold (e.g. 3 out of 5) — the number of keyholders
required to unlock the box later
</li>
<li>
- Lock the Box, downloads yours and share the remainig Locked
Lock the Box, downloads yours and share the remainig Locked
Boxes with every keyholder
</li>
<li>
- Every Locked Box contains the same ecrypted message, but a
Every Locked Box contains the same ecrypted message, but a
different key.
</li>
</ul>
</>
}
buttonSlot={
<Link to="/lock-box" style={{ textDecoration: "none" }}>
<Button variant="prominent" className="text-nowrap">
Create Box
</Button>
</Link>
<NavLink to="/lock-box" style={{ textDecoration: "none" }}>
{({ isPending, isTransitioning }) => (
<Button
variant="prominent"
className="text-nowrap"
loading={isPending || isTransitioning}
>
Create Box
</Button>
)}
</NavLink>
}
/>
<InfoBox
Expand All @@ -53,22 +59,27 @@ const Welcome: React.FC = () => {
</p>
<ul className="my-1">
<li>
- At least the required number of keyholds (as set during
creation by Key Trehsold) agree to open it.
At least the required number of keyholds (as set during creation
by Key Trehsold) agree to open it.
</li>
<li>
- You’ll confirm your intent to unlock the content with
keyholders
You’ll confirm your intent to unlock the content with keyholders
</li>
</ul>
</>
}
buttonSlot={
<Link to="/unlock-box" style={{ textDecoration: "none" }}>
<Button variant="prominent" className="whitespace-nowrap">
Open a Locked Box
</Button>
</Link>
<NavLink to="/unlock-box" style={{ textDecoration: "none" }}>
{({ isPending, isTransitioning }) => (
<Button
variant="prominent"
className="whitespace-nowrap"
loading={isPending || isTransitioning}
>
Open a Locked Box
</Button>
)}
</NavLink>
}
/>
</div>
Expand Down
18 changes: 18 additions & 0 deletions fe/src/services/libp2p/core/peer-connection-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,26 @@ export const createPeerConnectionHandler = ({
}
});

libp2p.addEventListener("peer:update", (evt) => {
const { peer, previous } = evt.detail;
loggerGate.canLog &&
console.log(
"[peer:update]",
shortenPeerId(peer.id.toString()),
"hadPrevious?",
previous != null,
"addresses:",
peer.addresses.map((a) => a.multiaddr.toString()),
);
});

// 👇 Dial peers discovered via pubsub
libp2p.addEventListener("peer:discovery", async (evt) => {
loggerGate.canLog &&
console.log(
"[peer:discovery] Peer discovered:",
shortenPeerId(evt.detail.id.toString()),
);
// Encapsulate the multiaddrs with the peer ID to ensure correct dialing
// Should be fixed when https://github.com/libp2p/js-libp2p/issues/3239 is resolved.
const discoveredPeerIdStr = evt.detail.id.toString();
Expand Down
Loading