Compare commits

...

2 Commits

Author SHA1 Message Date
tsukino
2ecc850382 refactor: turn p2p prover into interactive verifier plugin prover 2025-07-15 22:37:35 +08:00
tsukino
8cea923685 wip: refactoring p2p 2025-07-15 22:00:53 +08:00
7 changed files with 113 additions and 65 deletions

View File

@@ -72,16 +72,6 @@ export default function Menu(props: {
>
Verify
</MenuRow>
<MenuRow
fa="fa-solid fa-network-wired"
className="border-b border-slate-300"
onClick={() => {
props.setOpen(false);
navigate('/p2p');
}}
>
P2P
</MenuRow>
<MenuRow
className="lg:hidden"
fa="fa-solid fa-up-right-and-down-left-from-center"

View File

@@ -146,6 +146,17 @@ export async function addNotaryRequestProofs(
return newReq;
}
export async function setNotaryRequestSessionId(
id: string,
sessionId: string,
): Promise<RequestHistory | null> {
const existing = await historyDb.get(id);
if (!existing) return null;
const newReq: RequestHistory = { ...existing, sessionId };
await historyDb.put(id, newReq);
return newReq;
}
export async function setNotaryRequestStatus(
id: string,
status: '' | 'pending' | 'success' | 'error',

View File

@@ -25,6 +25,7 @@ import {
setNotaryRequestProgress,
getRequestLogsByTabId,
clearAllRequestLogs,
setNotaryRequestSessionId,
} from './db';
import { addOnePlugin, removeOnePlugin } from '../../reducers/plugins';
import {
@@ -71,6 +72,7 @@ export enum BackgroundActiontype {
get_prove_requests = 'get_prove_requests',
prove_request_start = 'prove_request_start',
process_prove_request = 'process_prove_request',
add_notary_request = 'add_notary_request',
finish_prove_request = 'finish_prove_request',
update_request_progress = 'update_request_progress',
verify_prove_request = 'verify_prove_request',
@@ -222,6 +224,7 @@ export type RequestHistory = {
metadata?: {
[k: string]: string;
};
sessionId?: string;
};
export const initRPC = () => {
@@ -235,6 +238,8 @@ export const initRPC = () => {
return sendResponse();
case BackgroundActiontype.get_prove_requests:
return handleGetProveRequests(request, sendResponse);
case BackgroundActiontype.add_notary_request:
return handleAddNotaryRequest(request, sendResponse);
case BackgroundActiontype.finish_prove_request:
return handleFinishProveRequest(request, sendResponse);
case BackgroundActiontype.update_request_progress:
@@ -397,8 +402,9 @@ async function handleFinishProveRequest(
request: BackgroundAction,
sendResponse: (data?: any) => void,
) {
const { id, proof, error, verification } = request.data;
const { id, proof, error, verification, sessionId } = request.data;
console.log('handleFinishProveRequest', request.data);
if (proof) {
const newReq = await addNotaryRequestProofs(id, proof);
if (!newReq) return;
@@ -420,6 +426,12 @@ async function handleFinishProveRequest(
await pushToRedux(addRequestHistory(await getNotaryRequest(id)));
}
if (sessionId) {
const newReq = await setNotaryRequestSessionId(id, sessionId);
if (!newReq) return;
await pushToRedux(addRequestHistory(await getNotaryRequest(id)));
}
return sendResponse();
}
@@ -713,24 +725,38 @@ async function runP2PPluginProver(request: BackgroundAction, now = Date.now()) {
websocketProxyUrl: _websocketProxyUrl,
maxSentData: _maxSentData,
maxRecvData: _maxRecvData,
clientId,
verifierPlugin,
notaryUrl,
} = request.data;
const rendezvousApi = await getRendezvousApi();
const proverUrl = `${rendezvousApi}?clientId=${clientId}:proof`;
const websocketProxyUrl = _websocketProxyUrl || (await getProxyApi());
const maxSentData = _maxSentData || (await getMaxSent());
const maxRecvData = _maxRecvData || (await getMaxRecv());
const { id } = await addNotaryRequest(now, {
url,
method,
headers,
body,
notaryUrl,
websocketProxyUrl,
maxRecvData,
maxSentData,
secretHeaders,
secretResps: [],
});
await browser.runtime.sendMessage({
type: OffscreenActionTypes.start_p2p_prover,
data: {
id,
pluginUrl,
pluginHex,
url,
method,
headers,
body,
proverUrl,
proverUrl: notaryUrl,
verifierPlugin,
websocketProxyUrl,
maxRecvData,
maxSentData,
@@ -1068,10 +1094,11 @@ async function handleRunPluginByURLRequest(request: BackgroundAction) {
const onPluginRequest = async (req: any) => {
if (req.type !== SidePanelActionTypes.execute_plugin_response) return;
console.log('onPluginRequest', req.data);
if (req.data.url !== url) return;
if (req.data.error) defer.reject(req.data.error);
if (req.data.proof) defer.resolve(req.data.proof);
if (req.data.sessionId) defer.resolve(req.data.sessionId);
browser.runtime.onMessage.removeListener(onPluginRequest);
};

View File

@@ -245,6 +245,7 @@ export const startP2PVerifier = async (request: any) => {
export const startP2PProver = async (request: any) => {
const {
id,
pluginUrl,
pluginHex,
url,
@@ -257,53 +258,56 @@ export const startP2PProver = async (request: any) => {
maxSentData,
secretHeaders,
getSecretResponse,
verifierPlugin,
} = request.data;
const hostname = urlify(url)?.hostname || '';
updateRequestProgress(id, RequestProgress.CreatingProver);
const prover: TProver = await new Prover({
id: pluginUrl,
id,
serverDns: hostname,
maxSentData,
maxRecvData,
serverIdentity: true,
});
browser.runtime.sendMessage({
type: BackgroundActiontype.prover_instantiated,
data: {
pluginUrl,
updateRequestProgress(id, RequestProgress.GettingSession);
const resp = await fetch(`${proverUrl}/session`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
clientType: 'Websocket',
maxRecvData,
maxSentData,
plugin: 'plugin-js',
}),
});
const { sessionId } = await resp.json();
const _url = new URL(proverUrl);
const protocol = _url.protocol === 'https:' ? 'wss' : 'ws';
const pathname = _url.pathname;
const sessionUrl = `${protocol}://${_url.host}${pathname === '/' ? '' : pathname}/notarize?sessionId=${sessionId!}`;
const proofRequestStart = waitForEvent(
OffscreenActionTypes.start_p2p_proof_request,
updateRequestProgress(id, RequestProgress.SettingUpProver);
await prover.setup(sessionUrl);
await handleProgress(
id,
RequestProgress.SendingRequest,
() =>
prover.sendRequest(websocketProxyUrl + `?token=${hostname}`, {
url,
method,
headers,
body,
}),
`Error connecting to websocket proxy: ${websocketProxyUrl}. Please check the proxy URL and ensure it's accessible.`,
);
const proverSetup = prover.setup(proverUrl);
await new Promise((r) => setTimeout(r, 5000));
browser.runtime.sendMessage({
type: BackgroundActiontype.prover_setup,
data: {
pluginUrl,
},
});
await proverSetup;
browser.runtime.sendMessage({
type: BackgroundActiontype.prover_started,
data: {
pluginUrl,
},
});
await proofRequestStart;
await prover.sendRequest(websocketProxyUrl + `?token=${hostname}`, {
url,
method,
headers,
body,
});
updateRequestProgress(id, RequestProgress.ReadingTranscript);
const transcript = await prover.transcript();
let secretResps: string[] = [];
@@ -344,9 +348,15 @@ export const startP2PProver = async (request: any) => {
),
};
const endRequest = waitForEvent(OffscreenActionTypes.end_p2p_proof_request);
await prover.reveal({ ...commit, server_identity: false });
await endRequest;
await prover.reveal({ ...commit, server_identity: true });
updateRequestProgress(id, RequestProgress.FinalizingOutputs);
browser.runtime.sendMessage({
type: BackgroundActiontype.finish_prove_request,
data: {
id,
sessionId: sessionId,
},
});
};
async function createProof(options: {

View File

@@ -149,6 +149,14 @@ function PluginBody({
proof: notaryRequest.proof,
},
});
} else if (notaryRequest?.sessionId) {
browser.runtime.sendMessage({
type: SidePanelActionTypes.execute_plugin_response,
data: {
url,
sessionId: notaryRequest.sessionId,
},
});
} else if (notaryRequest?.status === 'error') {
browser.runtime.sendMessage({
type: SidePanelActionTypes.execute_plugin_response,
@@ -161,7 +169,7 @@ function PluginBody({
},
});
}
}, [url, notaryRequest?.status]);
}, [url, notaryRequest?.status, notaryRequest?.sessionId]);
return (
<div className="flex flex-col p-4">
@@ -316,6 +324,8 @@ function StepContent(
let btnContent = null;
console.log('notaryRequest', notaryRequest);
console.log('notarizationId', notarizationId);
if (prover && p2p) {
btnContent = (
<button
@@ -327,7 +337,7 @@ function StepContent(
<span className="text-sm">View in P2P</span>
</button>
);
} else if (completed) {
} else if (completed || notaryRequest?.sessionId) {
btnContent = (
<button
className={classNames(

View File

@@ -384,15 +384,6 @@ function AdvancedOptions(props: {
setDirty(true);
}}
/>
<InputField
label="Rendezvous API (for P2P)"
value={rendezvous}
type="text"
onChange={(e) => {
setRendezvous(e.target.value);
setDirty(true);
}}
/>
<div className="flex flex-col flex-nowrap py-1 px-2 gap-2">
<div className="font-semibold">Logging Level</div>
<select

View File

@@ -221,11 +221,20 @@ export const makePlugin = async (
}
(async () => {
const { getSecretResponse, body: reqBody } = params;
const {
getSecretResponse,
body: reqBody,
interactive,
verifierPlugin,
} = params;
if (meta?.p2p) {
console.log('interactive', interactive);
console.log('verifierPlugin', verifierPlugin);
console.log('params', params);
if (interactive) {
const pluginHex = Buffer.from(arrayBuffer).toString('hex');
const pluginUrl = await sha256(pluginHex);
handleExecP2PPluginProver({
type: BackgroundActiontype.execute_p2p_plugin_prover,
data: {
@@ -234,7 +243,7 @@ export const makePlugin = async (
pluginHex,
body: reqBody,
now,
clientId: meta.clientId,
verifierPlugin,
},
});
} else {