Skip to content

Commit

Permalink
xmlhttprequest changed to fetch; optimize memory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
iseriohn committed Jul 24, 2023
1 parent 97622a2 commit c192d4a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 132 deletions.
150 changes: 69 additions & 81 deletions dapps/phase2-registration/src/routes/browser.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
import * as snarkjs from 'snarkjs';
import * as ffjavascript from 'ffjavascript';
import * as fastFile from "fastfile";
import { toB64 } from '@mysten/sui.js';
import { refreshTime, joinQueueMsg, contributeMsg, httpCall, generateSignature } from './utils';
import { toB64, fromB64 } from '@mysten/sui.js';
import { joinQueueMsg, contributeMsg, fetchCall, generateSignature } from './utils';
import { refreshTime } from './config';

async function runSNARKJS(params, index, entropy) {
const oldParams = { type: "mem" };
const fdTo = await fastFile.createOverride(oldParams);
fdTo.write(Uint8Array.from(params));
await fdTo.close();
async function runSNARKJS(params, entropy) {
const oldParams = { type: "mem", data: Uint8Array.from(fromB64(params)) };
const newParams = { type: "mem" };
const curve = await ffjavascript.buildBn128();
const startingTime = (new Date()).getTime();
const contributionHash = await snarkjs.zKey.bellmanContribute(curve, oldParams, newParams, entropy);
const endingTime = (new Date()).getTime();

const elapsedTime = (endingTime - startingTime) / 1000.;
const msg = "The time it takes to contribute for circuit #" + index + " is " + elapsedTime.toString() + "s";
alert(msg);

const fdFrom = await fastFile.readExisting(newParams);
const response = await fdFrom.read(fdFrom.totalSize, 0);
fdFrom.close();
return { params: [].slice.call(response), hash: [].slice.call(contributionHash) };
return [newParams.data, contributionHash];
}

async function startContribution(currentAccount, signMessage, entropy, params, setUserState, setListContribution) {
async function startContribution(currentAccount, signMessage, entropy, old_params, setUserState, setListContribution) {
var new_params = [];
var hashes: string[] = [];
var index = 0;
for (const param of params) {
for (const old_param of old_params) {
index += 1;
var res = await runSNARKJS(param, index, "Circuit#" + index.toString() + ": " + entropy)
new_params.push(res.params);
hashes.push(Buffer.from(res.hash).toString('hex'));
alert("Starting contribution to circuit #" + index.toString());
const startingTime = (new Date()).getTime();
const [new_param, hash] = await runSNARKJS(old_param, "Circuit#" + index.toString() + ": " + entropy)
const endingTime = (new Date()).getTime();
alert("The time it takes to contribute for circuit #" + index + " is " + ((endingTime - startingTime)/1000.).toString() + "s");
new_params.push(toB64(new_param));
console.log("hi");
hashes.push(Buffer.from(hash).toString('hex'));
}

console.log("finish hash");
var toSignRep = contributeMsg(currentAccount.address, hashes);
console.log("toSign", toSignRep);
var sigRep = await generateSignature(signMessage, toSignRep);
Expand All @@ -53,26 +47,26 @@ async function startContribution(currentAccount, signMessage, entropy, params, s
id: 1
});

const httpRep = httpCall(msgContribute);
httpRep.onreadystatechange = async (e) => {
if (httpRep.readyState === 4 && httpRep.status === 200) {
if (JSON.parse(httpRep.responseText).hasOwnProperty("error")) {
alert(currentAccount.address + ": " + httpRep.responseText);
} else {
const contribution = {
"index": JSON.parse(httpRep.responseText).result.index,
"address": currentAccount.address,
"pk": toB64(currentAccount.publicKey),
"hash": hashes,
"sig": sigRep.signature,
}
setListContribution((listContribution: any) => [...listContribution, contribution]);
alert(currentAccount.address + ": " + "Successfully recorded #" + contribution.index + " contribution");
alert("Now submitting contributions and waiting for verification...");
const [http, res] = await fetchCall(msgContribute);
if (http) {
if (res.hasOwnProperty("error")) {
alert(currentAccount.address + ": " + JSON.stringify(res));
} else {
const contribution = {
"index": res.result.index,
"address": currentAccount.address,
"pk": toB64(currentAccount.publicKey),
"hash": hashes,
"sig": sigRep.signature,
}
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
} else if (httpRep.status !== 200) {
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
setListContribution((listContribution: any) => [...listContribution, contribution]);
alert(currentAccount.address + ": " + "Successfully recorded #" + contribution.index + " contribution");
}
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
} else {
alert("Error occurred, please try again");
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
}
}

Expand All @@ -96,50 +90,44 @@ export async function contributeInBrowser(currentAccount, signMessage, entropy,
id: 1
});

const http = httpCall(joinQueueQuery);
http.onreadystatechange = async (e) => {
if (http.readyState === 4 && http.status === 200) {
var responseText = JSON.parse(http.responseText);
if (responseText.hasOwnProperty("error")) {
alert(currentAccount.address + ": " + http.responseText);
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
return;
}
const [http, res] = await fetchCall(joinQueueQuery);
if (http) {
if (res.hasOwnProperty("error")) {
alert(currentAccount.address + ": " + JSON.stringify(res));
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
return;
}
setQueuePosition(preState => new Map(preState.set(currentAccount.address, res.result.queue_position)));
alert(currentAccount.address + ": " + "Added in queue #" + res.result.queue_position.toString() + "; wait for " + (res.result.queue_position - queueStateRef.current.head - 1).toString() + " contributors to finish");
if (res.result.params.length == 0) {
var setIntervalID = setInterval(async function () {
if (queueStateRef.current.head + 1 >= queuePositionRef.current.get(currentAccount.address)) {
const [joinQueueHttp, joinQueueRes] = await fetchCall(joinQueueQuery);
if (joinQueueHttp) {
if (joinQueueRes.hasOwnProperty("error")) {
clearInterval(setIntervalID);
alert(currentAccount.address + ": " + JSON.stringify(joinQueueRes));
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
return;
}

setQueuePosition(preState => new Map(preState.set(currentAccount.address, responseText.result.queue_position)));
alert(currentAccount.address + ": " + "Added in queue #" + responseText.result.queue_position.toString() + "; wait for " + (responseText.result.queue_position - queueStateRef.current.head - 1).toString() + " contributors to finish");
if (responseText.result.params.length == 0) {
var setIntervalID = setInterval(async function () {
if (queueStateRef.current.head + 1 >= queuePositionRef.current.get(currentAccount.address)) {
const joinQueueHttp = httpCall(joinQueueQuery);
joinQueueHttp.onreadystatechange = async (e) => {
if (joinQueueHttp.readyState === 4 && joinQueueHttp.status === 200) {
var responseText = JSON.parse(joinQueueHttp.responseText);
if (responseText.hasOwnProperty("error")) {
clearInterval(setIntervalID);
alert(currentAccount.address + ": " + joinQueueHttp.responseText);
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
return;
}

if (responseText.result.queue_position != queuePositionRef.current.get(currentAccount.address)) {
alert(currentAccount.address + ": " + "Missed slot #" + queuePositionRef.current.get(currentAccount.address).toString() + "; assigned new slot #" + responseText.result.queue_position.toString() + "; wait for " + (responseText.result.queue_position - queueStateRef.current.head - 1).toString() + " contributors to finish");
setQueuePosition(preState => new Map(preState.set(currentAccount.address, responseText.result.queue_position)));
}
if (joinQueueRes.result.queue_position != queuePositionRef.current.get(currentAccount.address)) {
alert(currentAccount.address + ": " + "Missed slot #" + queuePositionRef.current.get(currentAccount.address).toString() + "; assigned new slot #" + joinQueueRes.result.queue_position.toString() + "; wait for " + (joinQueueRes.result.queue_position - queueStateRef.current.head - 1).toString() + " contributors to finish");
setQueuePosition(preState => new Map(preState.set(currentAccount.address, joinQueueRes.result.queue_position)));
}

if (queueStateRef.current.head + 1 == queuePositionRef.current.get(currentAccount.address)) {
clearInterval(setIntervalID);
await startContribution(currentAccount, signMessage, entropy, responseText.result.params, setUserState, setListContribution);
}
}
if (queueStateRef.current.head + 1 == queuePositionRef.current.get(currentAccount.address)) {
clearInterval(setIntervalID);
await startContribution(currentAccount, signMessage, entropy, joinQueueRes.result.params, setUserState, setListContribution);
}
}
}, refreshTime);
} else {
await startContribution(currentAccount, signMessage, entropy, responseText.result.params, setUserState, setListContribution);
}
} else if (http.status !== 200) {
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
}
}, refreshTime);
} else {
await startContribution(currentAccount, signMessage, entropy, res.result.params, setUserState, setListContribution);
}
} else {
alert("Error occurred, please try again");
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
}
}
3 changes: 3 additions & 0 deletions dapps/phase2-registration/src/routes/config.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const refreshTime = 20 * 1000; // Refresh every MONITOR/4 seconds;
export const URL = 'https://record.sui-phase2-ceremony.iseriohn.com';
// export const URL = 'http://localhost:37681';
4 changes: 2 additions & 2 deletions dapps/phase2-registration/src/routes/contribute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Button } from '@/components/ui/button';
import { Tabs } from '@/components/ui/tabs';
import { useWalletKit } from '@mysten/wallet-kit';
import { Terminal } from 'lucide-react';
import { createRef, useRef, useState } from 'react';
import { useRef, useState } from 'react';
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card';
import { refreshTime } from './utils';
import { refreshTime } from './config';
import { contributeInBrowser } from './browser';
import { contributeViaDocker } from './docker';
import { getQueue } from './queue';
Expand Down
38 changes: 19 additions & 19 deletions dapps/phase2-registration/src/routes/docker.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { addEphemeralKeyMsg, generateSignature, httpCall, downloadScript } from "./utils";
import { addEphemeralKeyMsg, generateSignature, fetchCall } from "./utils";
import { Ed25519Keypair, toB64 } from '@mysten/sui.js';

const dockerFileFront =
"# Use a base image with Rust slim \nFROM rust:slim AS base \n# Install system dependencies \nSHELL [\"/bin/bash\", \"-c\"] \nRUN apt-get update -y && apt-get upgrade -y && apt-get install -y sudo wget unzip curl git build-essential clang"
const dockerFileBack =
"\nENV COMMAND=\"cargo run --release -p client ${ADDR} ${ATTESTATION_KEY} ${OPTION} ${ENTROPY}\" \n#RUN git clone https://github.com/MystenLabs/ts-coordinator.git \nRUN wget http://185.209.177.123:8099/ts-coordinator.zip \nRUN unzip ts-coordinator.zip \nWORKDIR /ts-coordinator \nRUN ${COMMAND}";
"# Use a base image with Rust slim \nFROM rust:slim AS base \n# Install system dependencies \nSHELL [\"/bin/bash\", \"-c\"] \nRUN apt-get update -y && apt-get upgrade -y && apt-get install -y sudo wget unzip curl git build-essential clang"
const dockerFileBack =
"\nENV COMMAND=\"cargo run --release -p client ${ADDR} ${ATTESTATION_KEY} ${OPTION} ${ENTROPY}\" \n#RUN git clone https://github.com/MystenLabs/ts-coordinator.git \nRUN wget http://185.209.177.123:8099/ts-coordinator.zip \nRUN unzip ts-coordinator.zip \nWORKDIR /ts-coordinator \nRUN ${COMMAND}";

export async function contributeViaDocker(repo, currentAccount, entropy, signMessage, setUserState) {
setUserState(preState => new Map(preState.set(currentAccount.address, 1)));
Expand All @@ -30,21 +30,21 @@ export async function contributeViaDocker(repo, currentAccount, entropy, signMes
});


var http = httpCall(msg);
http.onreadystatechange = (e) => {
if (http.readyState === 4 && http.status === 200) {
alert(http.responseText);
var responseText = JSON.parse(http.responseText);
if (responseText.hasOwnProperty("result")) {
var text = dockerFileFront + "\nENV ADDR=" + addr;
text = text + "\nENV ATTESTATION_KEY=" + toB64(ephemeralKey.keypair.secretKey);
text = text + "\nENV OPTION=" + repo;
text = text + "\nENV ENTROPY=" + toB64(new TextEncoder().encode(entropy));
text = text + dockerFileBack;
downloadScript("Dockerfile", text);
alert('Please run "sudo docker build --no-cache --progress=plain ." in the same folder Dockerfile is downloaded.');
}
const [http, res] = await fetchCall(msg);
if (http) {
alert(JSON.stringify(res));
if (res.hasOwnProperty("result")) {
var text = dockerFileFront + "\nENV ADDR=" + addr;
text = text + "\nENV ATTESTATION_KEY=" + toB64(ephemeralKey.keypair.secretKey);
text = text + "\nENV OPTION=" + repo;
text = text + "\nENV ENTROPY=" + toB64(new TextEncoder().encode(entropy));
text = text + dockerFileBack;
//downloadScript("Dockerfile", text);
alert('Please run "sudo docker build --no-cache --progress=plain ." in the same folder Dockerfile is downloaded.');
console.log('cargo run --release -p client --features local_rehearsal ' + addr + ' ' + toB64(ephemeralKey.keypair.secretKey) + ' ' + repo + ' ' + toB64(new TextEncoder().encode(entropy)))
}
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
} else {
alert("Error occurred, please try again");
}
setUserState(preState => new Map(preState.set(currentAccount.address, null)));
}
12 changes: 5 additions & 7 deletions dapps/phase2-registration/src/routes/queue.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { httpCall } from './utils';
import { fetchCall } from './utils';

export async function getQueue(setQueueState) {
var msg = JSON.stringify({
Expand All @@ -7,11 +7,9 @@ export async function getQueue(setQueueState) {
id: 1
});

var Http = httpCall(msg);
Http.onreadystatechange = (e) => {
if (Http.readyState === 4 && Http.status === 200) {
console.log(JSON.parse(Http.responseText).result);
setQueueState(JSON.parse(Http.responseText).result);
}
const [http, res] = await fetchCall(msg);
if (http) {
console.log(res.result);
setQueueState(res.result);
}
}
10 changes: 4 additions & 6 deletions dapps/phase2-registration/src/routes/register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Button } from '@/components/ui/button';
import { Tabs } from '@/components/ui/tabs';
import { useWalletKit } from '@mysten/wallet-kit';
import { Terminal } from 'lucide-react';
import { registrationMsg, httpCall, generateSignature } from './utils';
import { registrationMsg, fetchCall, generateSignature } from './utils';

async function register(currentAccount, signMessage) {
var addr = currentAccount.address;
Expand All @@ -27,11 +27,9 @@ async function register(currentAccount, signMessage) {
id: 1
});

var Http = httpCall(msg);
Http.onreadystatechange = (e) => {
if (Http.readyState === 4 && Http.status === 200) {
alert(Http.responseText);
}
const [http, res] = await fetchCall(msg);
if (http) {
alert(JSON.stringify(res));
}
}

Expand Down
41 changes: 24 additions & 17 deletions dapps/phase2-registration/src/routes/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { bcs } from "@mysten/sui.js";
import { saveAs } from 'file-saver';

export const refreshTime = 2.5 * 1000; // Refresh every MONITOR/4 seconds;
import { URL } from './config';

export function registrationMsg(addr) {
return "I register to contribute to Phase2 Ceremony with address " + addr;
Expand All @@ -14,7 +13,7 @@ export function joinQueueMsg(addr, pk) {
export function contributeMsg(addr, params) {
var msg = "I contribute with address " + addr;
for (const [index, param] of params.entries()) {
msg = msg + ' #' + (index+1).toString() +' contribution hash: "' + param + '"';
msg = msg + ' #' + (index + 1).toString() + ' contribution hash: "' + param + '"';
}
return msg;
}
Expand All @@ -30,20 +29,28 @@ export function downloadScript(fileName, text) {
saveAs(blob, fileName);
}

export function httpCall(msg) {
console.log("to send query params:", msg);
const Http = new XMLHttpRequest();
// const url = 'http://localhost:37681';
const url = 'https://record.sui-phase2-ceremony.iseriohn.com';
Http.open("POST", url);
Http.timeout = 2000;
Http.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
Http.setRequestHeader("Access-Control-Allow-Origin", "*.sui-phase2-ceremony.iseriohn.com");
Http.setRequestHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
Http.setRequestHeader("Access-Control-Allow-Headers", "CONTENT_TYPE, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS");
Http.send(msg);

return Http;
export async function fetchCall(data) {
const http = await fetch(URL, {
method: "POST",
mode: "cors",
credentials: "omit",
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Access-Control-Allow-Origin": "*.sui-phase2-ceremony.iseriohn.com",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "CONTENT_TYPE, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS",
},
redirect: "follow",
referrerPolicy: "strict-origin-when-cross-origin",
body: data,
});

if (http.ok) {
const response = await http.json();
return [true, response];
} else {
return [false, null];
}
}

export async function generateSignature(signMessage, msg) {
Expand Down

0 comments on commit c192d4a

Please sign in to comment.