Skip to content

Commit ebf619d

Browse files
authored
Ocean.js P2P (#429)
* ocean.js libp2p only peerid * stub package for turbopack * ocean.js next.2 * rename peerid * latest ocean.js version * update yarn lock * new fetchlogs p2p method * use proper method for downloading * latest version ocean.js
1 parent 796dff2 commit ebf619d

18 files changed

Lines changed: 556 additions & 2265 deletions

next.config.mjs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
/** @type {import('next').NextConfig} */
22
const nextConfig = {
3-
serverExternalPackages: ['wagmi', '@wagmi/core', '@wagmi/connectors', '@walletconnect/ethereum-provider', '@walletconnect/universal-provider', 'pino', 'pino-pretty', 'thread-stream'],
3+
serverExternalPackages: [
4+
'wagmi',
5+
'@wagmi/core',
6+
'@wagmi/connectors',
7+
'@walletconnect/ethereum-provider',
8+
'@walletconnect/universal-provider',
9+
'pino',
10+
'pino-pretty',
11+
'thread-stream',
12+
],
413
turbopack: {
14+
resolveAlias: {
15+
fs: { browser: './src/empty.js' },
16+
net: { browser: './src/empty.js' },
17+
tls: { browser: './src/empty.js' },
18+
dgram: { browser: './src/empty.js' },
19+
dns: { browser: './src/empty.js' },
20+
'rdf-canonize-native': { browser: './src/empty.js' },
21+
},
522
rules: {
623
'*.svg': {
724
loaders: ['@svgr/webpack'],
@@ -17,8 +34,8 @@ const nextConfig = {
1734
net: false,
1835
tls: false,
1936
dgram: false,
20-
dns: false
21-
}
37+
dns: false,
38+
};
2239
}
2340
config.module.rules.push({
2441
test: /\.svg$/,

package.json

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,11 @@
2121
"@emotion/styled": "^11.14.1",
2222
"@gitbook/embed": "^0.4.0",
2323
"@google/generative-ai": "^0.24.1",
24-
"@libp2p/autonat": "^3.0.9",
25-
"@libp2p/bootstrap": "^12.0.10",
26-
"@libp2p/circuit-relay-v2": "^4.1.2",
27-
"@libp2p/crypto": "^5.1.13",
28-
"@libp2p/dcutr": "^3.0.9",
29-
"@libp2p/identify": "^4.0.9",
30-
"@libp2p/kad-dht": "^16.1.2",
31-
"@libp2p/keychain": "^6.0.9",
32-
"@libp2p/mdns": "^12.0.10",
33-
"@libp2p/peer-id": "^6.0.4",
34-
"@libp2p/peer-id-factory": "^4.2.4",
35-
"@libp2p/ping": "^3.0.9",
36-
"@libp2p/pubsub": "^10.1.18",
37-
"@libp2p/pubsub-peer-discovery": "^12.0.0",
38-
"@libp2p/tcp": "^11.0.9",
39-
"@libp2p/tls": "^3.0.10",
40-
"@libp2p/upnp-nat": "^4.0.9",
41-
"@libp2p/utils": "^7.0.12",
42-
"@libp2p/websockets": "^10.1.2",
4324
"@mui/icons-material": "^7.3.6",
4425
"@mui/material": "^7.3.6",
4526
"@mui/x-data-grid": "^8.14.1",
46-
"@multiformats/multiaddr": "^12.2.3",
4727
"@oceanprotocol/contracts": "2.6.0",
48-
"@oceanprotocol/lib": "5.1.1",
28+
"@oceanprotocol/lib": "8.0.0",
4929
"@ramp-network/ramp-instant-sdk": "^6.2.0",
5030
"@tanstack/react-query": "^5.28.4",
5131
"@wagmi/core": "^3.0.0",
@@ -65,7 +45,6 @@
6545
"jparticles": "^3.5.0",
6646
"json-edit-react": "^1.29.0",
6747
"jszip": "^3.10.1",
68-
"libp2p": "^3.1.2",
6948
"micromodal": "^0.4.10",
7049
"myetherwallet-blockies": "^0.1.1",
7150
"next": "16.1.7",
@@ -76,7 +55,6 @@
7655
"react-dom": "^18",
7756
"react-toastify": "^11.0.5",
7857
"recharts": "^3.3.0",
79-
"uint8arrays": "^4.0.6",
8058
"wagmi": "^3.1.0",
8159
"yup": "^1.7.1"
8260
},

src/components/button/download-logs-button.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ export const DownloadLogsButton = ({ job }: DownloadLogsButtonProps) => {
3030

3131
const { token } = await createAuthToken({
3232
consumerAddress: account.address,
33-
multiaddrsOrPeerId: job.peerId,
33+
nodeUri: job.peerId,
3434
signMessage,
3535
});
3636

37-
const jobStatus = await getComputeJobStatus(job.peerId, jobId, account.address);
37+
const jobStatus = await getComputeJobStatus(job.peerId, jobId, token);
3838
const logFiles: any[] = jobStatus?.[0]?.results?.filter((result: any) => result.filename.includes('.log')) ?? [];
3939

4040
if (logFiles.length === 0) {
@@ -52,15 +52,7 @@ export const DownloadLogsButton = ({ job }: DownloadLogsButtonProps) => {
5252
for (let i = 0; i < logFiles.length; i++) {
5353
setDownloadProgress({ current: i, total: logFiles.length });
5454

55-
const generator = streamComputeResult(
56-
job.peerId,
57-
jobId,
58-
logFiles[i].index,
59-
token,
60-
account.address,
61-
abortController.signal,
62-
logFiles[i].filesize ?? 0
63-
);
55+
const generator = await streamComputeResult(job.peerId, token, jobId, logFiles[i].index);
6456

6557
const chunks: Uint8Array[] = [];
6658
for await (const chunk of generator) {

src/components/button/download-result-button.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,22 @@ export const DownloadResultButton = ({ job }: DownloadResultButtonProps) => {
2727
const jobId = (job.environment ?? job.environmentId).split('-')[0] + '-' + job.jobId;
2828
setIsDownloading(true);
2929

30-
const jobStatus = await getComputeJobStatus(job.peerId, jobId, account.address);
31-
const archive = jobStatus?.[0]?.results?.find((result: any) => result.filename.includes('.tar'));
32-
const filesize: number = archive?.filesize ?? 0;
33-
3430
const { token } = await createAuthToken({
3531
consumerAddress: account.address,
36-
multiaddrsOrPeerId: job.peerId,
32+
nodeUri: job.peerId,
3733
signMessage,
3834
});
3935

36+
const jobStatus = await getComputeJobStatus(job.peerId, jobId, token);
37+
const archive = jobStatus?.[0]?.results?.find((result: any) => result.filename.includes('.tar'));
38+
const filesize: number = archive?.filesize ?? 0;
39+
4040
const abortController = new AbortController();
4141
abortRef.current = abortController;
4242

4343
setDownloadProgress({ bytes: 0, total: filesize });
4444

45-
const generator = streamComputeResult(
46-
job.peerId,
47-
jobId,
48-
archive?.index,
49-
token,
50-
account.address,
51-
abortController.signal,
52-
filesize
53-
);
45+
const generator = await streamComputeResult(job.peerId, token, jobId, archive?.index);
5446

5547
const showSaveFilePicker = (window as any).showSaveFilePicker as
5648
| ((options?: any) => Promise<FileSystemFileHandle>)

src/components/node-details/node-info.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const NodeInfo: React.FC<NodeInfoProps> = ({ envs, node, nodeOnline }) => {
9797
await fetchConfig({
9898
consumerAddress: account.address,
9999
expiryTimestamp: Date.now() + 5 * 60 * 1000, // 5 minutes expiry
100-
multiaddrsOrPeerId: node.id,
100+
nodeUri: node.id,
101101
signMessage,
102102
});
103103
} catch (error) {
@@ -121,7 +121,7 @@ const NodeInfo: React.FC<NodeInfoProps> = ({ envs, node, nodeOnline }) => {
121121
await pushConfig({
122122
consumerAddress: account.address,
123123
expiryTimestamp: Date.now() + 5 * 60 * 1000, // 5 minutes expiry
124-
multiaddrsOrPeerId: node.id,
124+
nodeUri: node.id,
125125
signMessage,
126126
config,
127127
});
@@ -163,8 +163,7 @@ const NodeInfo: React.FC<NodeInfoProps> = ({ envs, node, nodeOnline }) => {
163163
try {
164164
const logs = await getNodeLogs({
165165
consumerAddress: account.address,
166-
expiryTimestamp: Date.now() + 5 * 60 * 1000,
167-
multiaddrsOrPeerId: node.id,
166+
nodeUri: node.id,
168167
params: { startTime, endTime, maxLogs },
169168
signMessage,
170169
});

src/components/run-job/select-resources.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const SelectResources = ({ environment, freeCompute, token }: SelectResourcesPro
5252
setSelectedResources,
5353
} = useRunJobContext();
5454

55-
const { node: p2pNode } = useP2P();
55+
const { isReady: p2pReady } = useP2P();
5656

5757
const [initComputeError, setInitComputeError] = useState<unknown | null>(null);
5858
const [isLoadingCost, setIsLoadingCost] = useState(false);
@@ -198,7 +198,7 @@ const SelectResources = ({ environment, freeCompute, token }: SelectResourcesPro
198198
environment,
199199
freeCompute,
200200
maxJobDurationSeconds: maxJobDurationSec < 1 ? 1 : Math.ceil(maxJobDurationSec),
201-
multiaddrsOrPeerId,
201+
multiaddrsOrPeerId: multiaddrsOrPeerId!,
202202
onError: (error) => setInitComputeError(error),
203203
resources,
204204
tokenAddress: token?.address,
@@ -228,7 +228,7 @@ const SelectResources = ({ environment, freeCompute, token }: SelectResourcesPro
228228
clearTimeout(costEstimateTimeoutRef.current);
229229
}
230230
};
231-
}, [estimateCost, fetchEstimatedCost]);
231+
}, [estimateCost]);
232232

233233
const selectAllGpus = () => {
234234
formik.setFieldValue(
@@ -300,7 +300,7 @@ const SelectResources = ({ environment, freeCompute, token }: SelectResourcesPro
300300
</h3>
301301
);
302302
}
303-
if (!p2pNode || (!estimatedTotalCost && estimatedTotalCost !== 0)) {
303+
if (!p2pReady || (!estimatedTotalCost && estimatedTotalCost !== 0)) {
304304
return (
305305
<h3 className={styles.estimationMessage}>
306306
<CircularProgress size={24} />

src/components/run-job/summary.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ const Summary = ({
118118
try {
119119
const { token: generatedAuthToken } = await createAuthToken({
120120
consumerAddress: account.address,
121-
multiaddrsOrPeerId: multiaddrsOrPeerId!,
121+
nodeUri: multiaddrsOrPeerId!,
122122
signMessage,
123123
});
124124
setAuthToken(generatedAuthToken);
@@ -138,7 +138,7 @@ const Summary = ({
138138
if (!authToken || !account.address || !ocean) {
139139
return;
140140
}
141-
const peerMultiaddr = await getPeerMultiaddr(multiaddrsOrPeerId!);
141+
const peerMultiaddr = await getPeerMultiaddr(nodeInfo.id);
142142
const resources = [
143143
...gpus.map((availableGpu) => ({
144144
id: availableGpu.id,

src/components/run-node/node-connection.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const NodeConnection = () => {
2121

2222
const { account } = useOceanAccount();
2323

24-
const { clearRunNodeSelection, connectToNode, p2pNode, peerId } = useRunNodeContext();
24+
const { clearRunNodeSelection, connectToNode, isP2PReady, peerId } = useRunNodeContext();
2525

2626
// This is a workaround for the modal not closing after connecting
2727
// https://github.com/alchemyplatform/aa-sdk/issues/2327
@@ -84,11 +84,11 @@ const NodeConnection = () => {
8484
<div className="actionsGroupMdEnd">
8585
<Button
8686
color="accent1"
87-
contentBefore={p2pNode ? <LinkIcon /> : null}
88-
loading={!p2pNode || formik.isSubmitting}
87+
contentBefore={isP2PReady ? <LinkIcon /> : null}
88+
loading={!isP2PReady || formik.isSubmitting}
8989
onClick={formik.submitForm}
9090
>
91-
{p2pNode ? 'Connect' : 'Initializing...'}
91+
{isP2PReady ? 'Connect' : 'Initializing...'}
9292
</Button>
9393
</div>
9494
</>

src/context/run-job-context.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
NodeEnvironments,
1212
} from '@/types/environments';
1313
import { roundTokenAmount } from '@/utils/formatters';
14-
import { multiaddr } from '@multiformats/multiaddr';
1514
import axios from 'axios';
1615
import { useSearchParams } from 'next/navigation';
1716
import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
@@ -36,7 +35,7 @@ type RunJobContextType = {
3635
environment: ComputeEnvironment;
3736
freeCompute: boolean;
3837
maxJobDurationSeconds: number;
39-
multiaddrsOrPeerId: MultiaddrsOrPeerId;
38+
multiaddrsOrPeerId: string[] | string;
4039
onError?: (error: unknown) => void;
4140
onSuccess?: (cost: number, minLockSeconds: number) => void;
4241
resources: { id: string; amount: number }[];
@@ -73,7 +72,7 @@ const RunJobContext = createContext<RunJobContextType | undefined>(undefined);
7372

7473
export const RunJobProvider = ({ children }: { children: ReactNode }) => {
7574
const { provider } = useOceanAccount();
76-
const { initializeCompute, node: p2pNode } = useP2P();
75+
const { initializeCompute, isReady: p2pIsReady } = useP2P();
7776

7877
const searchParams = useSearchParams();
7978
const [estimatedTotalCost, setEstimatedTotalCost] = useState<number | null>(null);
@@ -134,8 +133,10 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
134133
setSelectedEnv(environment);
135134
setFreeCompute(freeCompute);
136135
setNodeInfo(nodeInfo);
137-
const multiaddrs = new Set(nodeInfo?.multiaddrs?.filter(Boolean).filter(multiaddr));
138-
setMultiaddrsOrPeerId(multiaddrs.size > 0 ? Array.from(multiaddrs) : nodeInfo?.id);
136+
137+
const addrs = (nodeInfo.multiaddrs ?? []).map((a) => (a.includes('/p2p/') ? a : `${a}/p2p/${nodeInfo.id}`));
138+
setMultiaddrsOrPeerId(addrs.length > 0 ? addrs : nodeInfo.id);
139+
139140
if (resources) {
140141
setSelectedResources(resources);
141142
}
@@ -169,7 +170,7 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
169170
environment: ComputeEnvironment;
170171
freeCompute: boolean;
171172
maxJobDurationSeconds: number;
172-
multiaddrsOrPeerId: MultiaddrsOrPeerId;
173+
multiaddrsOrPeerId: string[] | string;
173174
onError?: (error: unknown) => void;
174175
onSuccess?: (cost: number, minLockSeconds: number) => void;
175176
resources: { id: string; amount: number }[];
@@ -179,7 +180,7 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
179180
setEstimatedTotalCost(0);
180181
return;
181182
}
182-
if (!provider || !p2pNode) {
183+
if (!provider || !p2pIsReady) {
183184
return;
184185
}
185186
try {
@@ -190,8 +191,7 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
190191
multiaddrsOrPeerId,
191192
environment.consumerAddress,
192193
resources,
193-
CHAIN_ID,
194-
provider
194+
CHAIN_ID
195195
);
196196
setEstimatedTotalCost(roundTokenAmount(Number(cost), tokenAddress, 'up'));
197197
setMinLockSeconds(minLockSeconds);
@@ -201,7 +201,7 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
201201
console.error('Failed to fetch estimated cost:', error);
202202
}
203203
},
204-
[initializeCompute, p2pNode, provider]
204+
[initializeCompute, p2pIsReady, provider]
205205
);
206206

207207
/**
@@ -241,7 +241,6 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
241241
);
242242
const foundEnv = foundNode?.computeEnvironments.environments.find((env) => env.id === queryEnv);
243243
if (foundNode && foundEnv) {
244-
const multiaddrs = new Set(foundNode?.multiaddrs?.filter(Boolean).filter(multiaddr));
245244
const queryFree = searchParams.get('free') === 'true';
246245
const qJobDuration = searchParams.get('maxJobDuration');
247246
const queryGpusArray = searchParams.getAll('gpus[]');
@@ -290,6 +289,10 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
290289
nodeInfo: foundNode,
291290
resources,
292291
});
292+
const foundAddrs = (foundNode.multiaddrs ?? []).map((a) =>
293+
a.includes('/p2p/') ? a : `${a}/p2p/${foundNode.id}`
294+
);
295+
const resolvedNodeUri = foundAddrs.length > 0 ? foundAddrs : foundNode.id;
293296
if (!queryFree) {
294297
const queryToken = searchParams.get('token');
295298
if (queryToken) {
@@ -298,7 +301,7 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
298301
environment: foundEnv,
299302
freeCompute: queryFree,
300303
maxJobDurationSeconds: resources.maxJobDurationSeconds,
301-
multiaddrsOrPeerId: multiaddrs.size > 0 ? Array.from(multiaddrs) : foundNode.id,
304+
multiaddrsOrPeerId: resolvedNodeUri,
302305
resources: [
303306
...(resources.cpuId && resources.cpuCores ? [{ id: resources.cpuId, amount: resources.cpuCores }] : []),
304307
...(resources.ramId && resources.ram ? [{ id: resources.ramId, amount: resources.ram }] : []),
@@ -332,13 +335,13 @@ export const RunJobProvider = ({ children }: { children: ReactNode }) => {
332335
const queryFree = searchParams.get('free') === 'true';
333336
// For paid compute, also wait for p2p node and provider in order to fetch the cost
334337
// For free compute, they are not needed
335-
if (queryFree || (p2pNode && provider)) {
338+
if (queryFree || (p2pIsReady && provider)) {
336339
setHydrateFromUrlStarted(true);
337340
hydrateContextFromQueryParams();
338341
}
339342
}
340343
}
341-
}, [hydrateContextFromQueryParams, hydrateFromUrlStarted, p2pNode, provider, searchParams]);
344+
}, [hydrateContextFromQueryParams, hydrateFromUrlStarted, p2pIsReady, provider, searchParams]);
342345

343346
return (
344347
<RunJobContext.Provider

0 commit comments

Comments
 (0)