Skip to content

Commit

Permalink
feat: add progress for notarization request
Browse files Browse the repository at this point in the history
  • Loading branch information
0xtsukino committed Dec 4, 2024
1 parent b8d068b commit d925ae9
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 31 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion src/entries/Background/db.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Level } from 'level';
import type { RequestHistory } from './rpc';
import { RequestHistory, RequestProgress } from './rpc';
import { PluginConfig, PluginMetadata, sha256 } from '../../utils/misc';
import mutex from './mutex';
const charwise = require('charwise');
Expand Down Expand Up @@ -111,6 +111,24 @@ export async function setNotaryRequestError(
return newReq;
}

export async function setNotaryRequestProgress(
id: string,
progress: RequestProgress,
): Promise<RequestHistory | null> {
const existing = await historyDb.get(id);

if (!existing) return null;

const newReq: RequestHistory = {
...existing,
progress,
};

await historyDb.put(id, newReq);

return newReq;
}

export async function setNotaryRequestVerification(
id: string,
verification: { sent: string; recv: string },
Expand Down
45 changes: 45 additions & 0 deletions src/entries/Background/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
setDefaultPluginsInstalled,
setLocalStorage,
setSessionStorage,
setNotaryRequestProgress,
} from './db';
import { addOnePlugin, removeOnePlugin } from '../../reducers/plugins';
import {
Expand Down Expand Up @@ -86,6 +87,7 @@ export enum BackgroundActiontype {
prove_request_start = 'prove_request_start',
process_prove_request = 'process_prove_request',
finish_prove_request = 'finish_prove_request',
update_request_progress = 'update_request_progress',
verify_prove_request = 'verify_prove_request',
verify_proof = 'verify_proof',
delete_prove_request = 'delete_prove_request',
Expand Down Expand Up @@ -169,6 +171,32 @@ export type RequestLog = {
responseHeaders?: browser.WebRequest.HttpHeaders;
};

export enum RequestProgress {
CreatingProver,
GettingSession,
SettingUpProver,
SendingRequest,
ReadingTranscript,
FinalizingOutputs,
}

export function progressText(progress: RequestProgress): string {
switch (progress) {
case RequestProgress.CreatingProver:
return 'Creating prover...';
case RequestProgress.GettingSession:
return 'Getting session url from notary...';
case RequestProgress.SettingUpProver:
return 'Setting up prover mpc backend...';
case RequestProgress.SendingRequest:
return 'Sending request...';
case RequestProgress.ReadingTranscript:
return 'Reading request transcript...';
case RequestProgress.FinalizingOutputs:
return 'Finalizing notarization outputs...';
}
}

export type RequestHistory = {
id: string;
url: string;
Expand All @@ -180,6 +208,7 @@ export type RequestHistory = {
notaryUrl: string;
websocketProxyUrl: string;
status: '' | 'pending' | 'success' | 'error';
progress?: RequestProgress;
error?: any;
proof?: { session: any; substrings: any };
requestBody?: any;
Expand Down Expand Up @@ -208,6 +237,8 @@ export const initRPC = () => {
return handleGetProveRequests(request, sendResponse);
case BackgroundActiontype.finish_prove_request:
return handleFinishProveRequest(request, sendResponse);
case BackgroundActiontype.update_request_progress:
return handleUpdateRequestProgress(request, sendResponse);
case BackgroundActiontype.delete_prove_request:
return removeNotaryRequest(request.data);
case BackgroundActiontype.retry_prove_request:
Expand Down Expand Up @@ -388,6 +419,19 @@ async function handleFinishProveRequest(
return sendResponse();
}

async function handleUpdateRequestProgress(
request: BackgroundAction,
sendResponse: (data?: any) => void,
) {
const { id, progress } = request.data;

const newReq = await setNotaryRequestProgress(id, progress);
if (!newReq) return;
await pushToRedux(addRequestHistory(await getNotaryRequest(id)));

return sendResponse();
}

async function handleRetryProveReqest(
request: BackgroundAction,
sendResponse: (data?: any) => void,
Expand Down Expand Up @@ -740,6 +784,7 @@ async function handleSetSessionStorage(
await setSessionStorage(hostname, key, value as string);
}

// TODO: Fix non-existent event name
sendResponse({ type: BackgroundActiontype.sessionStorage_set });
}
}
Expand Down
49 changes: 33 additions & 16 deletions src/entries/Offscreen/Offscreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ import * as Comlink from 'comlink';
import { OffscreenActionTypes } from './types';
import {
NotaryServer,
Prover as TProver,
Verifier as TVerifier,
Presentation as TPresentation,
Prover as TProver,
Transcript,
Verifier as TVerifier,
} from 'tlsn-js';
import { verify } from 'tlsn-js-v5';

import { devlog, urlify } from '../../utils/misc';
import {
hexToArrayBuffer,
makePlugin,
safeParseJSON,
urlify,
} from '../../utils/misc';
import { BackgroundActiontype } from '../Background/rpc';
BackgroundActiontype,
progressText,
RequestProgress,
} from '../Background/rpc';
import browser from 'webextension-polyfill';
import { PresentationJSON } from '../../utils/types';
import { PresentationJSON as PresentationJSONa7 } from 'tlsn-js/build/types';
Expand All @@ -25,7 +24,6 @@ import { subtractRanges } from './utils';
import { mapSecretsToRange } from '../Background/plugins/utils';
import { waitForEvent } from '../utils';
import type { ParsedTranscriptData } from 'tlsn-js/src/types';
import { getPluginByHash } from '../Background/db';

const { init, Prover, Presentation, Verifier }: any = Comlink.wrap(
new Worker(new URL('./worker.ts', import.meta.url)),
Expand Down Expand Up @@ -66,13 +64,13 @@ const Offscreen = () => {
proof,
},
});
} catch (error) {
} catch (error: any) {
console.error(error);
browser.runtime.sendMessage({
type: BackgroundActiontype.finish_prove_request,
data: {
id,
error,
error: error?.message || 'Unknown error',
},
});

Expand Down Expand Up @@ -145,13 +143,13 @@ const Offscreen = () => {
});

delete provers[id];
} catch (error) {
} catch (error: any) {
console.error(error);
browser.runtime.sendMessage({
type: BackgroundActiontype.finish_prove_request,
data: {
id,
error,
error: error?.message || 'Unknown error.',
},
});
}
Expand All @@ -172,13 +170,13 @@ const Offscreen = () => {
proof: proof,
},
});
} catch (error) {
} catch (error: any) {
console.error(error);
browser.runtime.sendMessage({
type: BackgroundActiontype.finish_prove_request,
data: {
id,
error,
error: error?.message || 'Unknown error.',
},
});
}
Expand Down Expand Up @@ -420,22 +418,29 @@ async function createProof(options: {

const hostname = urlify(url)?.hostname || '';
const notary = NotaryServer.from(notaryUrl);

updateRequestProgress(id, RequestProgress.CreatingProver);
const prover: TProver = await new Prover({
id,
serverDns: hostname,
maxSentData,
maxRecvData,
});
updateRequestProgress(id, RequestProgress.GettingSession);
const sessionUrl = await notary.sessionUrl(maxSentData, maxRecvData);

await prover.setup(await notary.sessionUrl(maxSentData, maxRecvData));
updateRequestProgress(id, RequestProgress.SettingUpProver);
await prover.setup(sessionUrl);

updateRequestProgress(id, RequestProgress.SendingRequest);
await prover.sendRequest(websocketProxyUrl + `?token=${hostname}`, {
url,
method,
headers,
body,
});

updateRequestProgress(id, RequestProgress.ReadingTranscript);
const transcript = await prover.transcript();

const commit = {
Expand All @@ -449,6 +454,7 @@ async function createProof(options: {
),
};

updateRequestProgress(id, RequestProgress.FinalizingOutputs);
const notarizationOutputs = await prover.notarize(commit);

const presentation = (await new Presentation({
Expand Down Expand Up @@ -584,3 +590,14 @@ async function verifyProof(

return result;
}

function updateRequestProgress(id: string, progress: RequestProgress) {
devlog(`Request ${id}: ${progressText(progress)}`);
browser.runtime.sendMessage({
type: BackgroundActiontype.update_request_progress,
data: {
id,
progress: progress,
},
});
}
33 changes: 21 additions & 12 deletions src/pages/History/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import {
import Icon from '../../components/Icon';
import { getNotaryApi, getProxyApi } from '../../utils/storage';
import { urlify, download, upload } from '../../utils/misc';
import { BackgroundActiontype } from '../../entries/Background/rpc';
import {
BackgroundActiontype,
progressText,
} from '../../entries/Background/rpc';
import Modal, { ModalContent } from '../../components/Modal/Modal';
import classNames from 'classnames';
import copy from 'copy-to-clipboard';
Expand Down Expand Up @@ -119,7 +122,7 @@ export function OneRequestHistory(props: {
return (
<div
className={classNames(
'flex flex-row flex-nowrap border rounded-md p-2 gap-1 hover:bg-slate-50 cursor-pointer',
'flex flex-row flex-nowrap border rounded-md p-2 gap-1 hover:bg-slate-50 cursor-pointer relative',
props.className,
)}
>
Expand Down Expand Up @@ -190,18 +193,24 @@ export function OneRequestHistory(props: {
<RetryButton hidden={hideActions.includes('retry')} />
)}
{status === 'pending' && (
<button className="flex flex-row flex-grow-0 gap-2 self-end items-center justify-end px-2 py-1 bg-slate-100 text-slate-300 font-bold">
<div className="absolute top-0 left-0 w-full h-full text-center flex flex-row flex-grow-0 gap-2 self-end items-center justify-center px-2 py-1 bg-black/70 text-white/90 font-bold">
<Icon className="animate-spin" fa="fa-solid fa-spinner" size={1} />
<span className="text-xs font-bold">Pending</span>
</button>
<span className="text-xs font-bold">
{request?.progress
? `(${request.progress + 1}/6) ${progressText(request.progress)}`
: 'Pending...'}
</span>
</div>
)}
{status !== 'pending' && (
<ActionButton
className="flex flex-row flex-grow-0 gap-2 self-end items-center justify-end px-2 py-1 bg-slate-100 text-slate-300 hover:bg-red-100 hover:text-red-500 hover:font-bold"
onClick={onDelete}
fa="fa-solid fa-trash"
ctaText="Delete"
hidden={hideActions.includes('delete')}
/>
)}
<ActionButton
className="flex flex-row flex-grow-0 gap-2 self-end items-center justify-end px-2 py-1 bg-slate-100 text-slate-300 hover:bg-red-100 hover:text-red-500 hover:font-bold"
onClick={onDelete}
fa="fa-solid fa-trash"
ctaText="Delete"
hidden={hideActions.includes('delete')}
/>
</div>
</div>
);
Expand Down

0 comments on commit d925ae9

Please sign in to comment.