From 4b1c67ec6e5292bfa7949e58f60d8428552487e1 Mon Sep 17 00:00:00 2001 From: souradeep-das Date: Thu, 11 Jul 2024 23:02:19 +0530 Subject: [PATCH 1/3] feat: add admin/node services --- .env.example.admin | 9 + .env.example.node | 9 + contracts/zkdvrf.sol | 2 +- package.json | 7 +- services/admin.ts | 355 +++++++++++++++++++++++++++++++++++++++ services/exec/run.ts | 66 ++++++++ services/exec/runNode.ts | 66 ++++++++ services/node.ts | 294 ++++++++++++++++++++++++++++++++ yarn.lock | 345 +++++++++++++++++++++++++++++++++++-- 9 files changed, 1133 insertions(+), 20 deletions(-) create mode 100644 .env.example.admin create mode 100644 .env.example.node create mode 100644 services/admin.ts create mode 100644 services/exec/run.ts create mode 100644 services/exec/runNode.ts create mode 100644 services/node.ts diff --git a/.env.example.admin b/.env.example.admin new file mode 100644 index 0000000..f5dc565 --- /dev/null +++ b/.env.example.admin @@ -0,0 +1,9 @@ +L2_NODE_WEB3_URL= +POLLING_INTERVAL= +ZK_RAND_ADDRESS= +ADMIN_PRIVATE_KEY= +NODE_ONE_ADDRESS= +NODE_TWO_ADDRESS= +NODE_THREE_ADDRESS= +NODE_FOUR_ADDRESS= +NODE_FIVE_ADDRESS= \ No newline at end of file diff --git a/.env.example.node b/.env.example.node new file mode 100644 index 0000000..4b8622e --- /dev/null +++ b/.env.example.node @@ -0,0 +1,9 @@ +L2_NODE_WEB3_URL= +POLLING_INTERVAL= +ZK_RAND_ADDRESS= +NODE_PRIVATE_KEY= +NODE_ONE_ADDRESS= +NODE_TWO_ADDRESS= +NODE_THREE_ADDRESS= +NODE_FOUR_ADDRESS= +NODE_FIVE_ADDRESS= \ No newline at end of file diff --git a/contracts/zkdvrf.sol b/contracts/zkdvrf.sol index 5e7541b..a9b4090 100644 --- a/contracts/zkdvrf.sol +++ b/contracts/zkdvrf.sol @@ -43,7 +43,7 @@ contract zkdvrf is Ownable { uint32 public threshold; uint32 public ppLength; // current count of members added - uint32 internal currentIndex; + uint32 public currentIndex; // current count of members deposited and registered uint32 internal registeredCount; uint32 internal ppSubmissionCount; diff --git a/package.json b/package.json index 3cbc12e..ac2873a 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,11 @@ "test": "test" }, "dependencies": { + "@eth-optimism/common-ts": "0.2.2", + "@eth-optimism/core-utils": "0.8.1", "@nomiclabs/hardhat-waffle": "^2.0.6", "@openzeppelin/contracts": "^5.0.1", + "bcfg": "^0.2.2", "dotenv": "^16.4.5", "hardhat": "^2.22.1", "hardhat-deploy": "^0.11.45" @@ -37,7 +40,9 @@ "random": "npx hardhat run scripts/random.ts", "lottery:deploy": "npx hardhat run scripts/lottery/deploy.ts", "lottery:admin": "npx hardhat run scripts/lottery/admin.ts", - "lottery:play": "npx hardhat run scripts/lottery/play.ts" + "lottery:play": "npx hardhat run scripts/lottery/play.ts", + "services:admin": "ts-node ./services/exec/run.ts", + "services:node": "ts-node ./services/exec/runNode.ts" }, "repository": { "type": "git", diff --git a/services/admin.ts b/services/admin.ts new file mode 100644 index 0000000..82fbe05 --- /dev/null +++ b/services/admin.ts @@ -0,0 +1,355 @@ +/* Imports: External */ +import { Contract, Wallet, BigNumber, providers } from 'ethers' +import fs from "fs"; +import {promisify} from "util"; +import {exec} from "child_process"; + +/* Imports: Internal */ +import { sleep } from '@eth-optimism/core-utils' +import { BaseService } from '@eth-optimism/common-ts' + +import zkRandContractABI from '../artifacts/contracts/zkdvrf.sol/zkdvrf.json' + +// /* Imports: Inteface */ +// import { +// BobaLinkPairs, +// BobaLinkContracts, +// BobaLinkContract, +// GasPriceOverride, +// } from './utils/types' + +export const memberDir = `./data/members/` +export const mpksPath = `./data/mpks.json` +export const dkgDir = `./data/dkg/` +export const instancesPath = `./data/dkg/all_instances.json` +export const randDir = `./data/random/` + +interface Eval { + indexPlus: number +} + +export interface GasPriceOverride { + gasLimit: number + gasPrice?: number + } + +interface AdminZkRandOptions { + l2RpcProvider: providers.StaticJsonRpcProvider + l2Wallet: Wallet + // chain ID of the L2 network + chainId: number + + zkRandAddress: string + + nodeOneAddress: string + nodeTwoAddress: string + nodeThreeAddress: string + nodeFourAddress: string + nodeFiveAddress: string + + pollingInterval: number +} + +const optionSettings = {} + +export class AdminZkRandService extends BaseService { + constructor(options: AdminZkRandOptions) { + super('AdminZkRandService', options, optionSettings) + } + + private state: { + zkRandContract: Contract + gasOverride: GasPriceOverride + timeOfLastRound: number + } = {} as any + + async _init(): Promise { + this.logger.info('Initializing AdminZkRand service...', { + options: this.options, + }) + + this.logger.info('Connecting to ZkRand contract...', { + bobaLinkPairs: this.options.zkRandAddress, + }) + + this.state.zkRandContract = new Contract( + this.options.zkRandAddress, + zkRandContractABI.abi, + this.options.l2Wallet + ) + + this.logger.info('Connected to ZkRand contract', { + address: this.state.zkRandContract.address, + chainId: this.options.chainId, + rpc: this.state.zkRandContract.provider, + }) + + this.state.gasOverride = { gasLimit: 10000000 } + this.state.timeOfLastRound = 0 // 0 indicates no round has been initiated + } + + async _start(): Promise { + console.log('started') + + let adminFromContract = await this.state.zkRandContract.owner() + console.log(adminFromContract) + + if (adminFromContract !== this.options.l2Wallet.address) { + throw new Error( + `ADMIN_PRIVATE_KEY is not set to zkRand admin ${adminFromContract}` + ) + } + + let memberCountFromContract = await this.state.zkRandContract.memberCount() + console.log(memberCountFromContract) + let currentIndexFromContract = await this.state.zkRandContract.currentIndex() + console.log(currentIndexFromContract) + + // TODO: handle the case where only some members have been added + if (currentIndexFromContract != memberCountFromContract) { + // check if nidkg is already completed, or if this step is already done + const retOne = await this.state.zkRandContract.addPermissionedNodes(this.options.nodeOneAddress) + await retOne.wait() + const retTwo = await this.state.zkRandContract.addPermissionedNodes(this.options.nodeTwoAddress) + await retTwo.wait() + const retThree = await this.state.zkRandContract.addPermissionedNodes(this.options.nodeThreeAddress) + await retThree.wait() + const retFour = await this.state.zkRandContract.addPermissionedNodes(this.options.nodeFourAddress) + await retFour.wait() + const retFive = await this.state.zkRandContract.addPermissionedNodes(this.options.nodeFiveAddress) + await retFive.wait() + } + + while (this.running) { + let contractPhase = await this.state.zkRandContract.contractPhase() + console.log(contractPhase) + if (contractPhase < 2) { + // register when all nodes have added themselves + // check if already registed, and skip + await this.listenRegister() + + // check if nidkg is complete and skip + await this.listenNidkg() + } + + const eventGpp = `GlobalPublicParamsCreated` + this.state.zkRandContract.on(eventGpp, async (event) => { + await this.initiateRand(); + }); + + let secondsElapsed: number + if (this.state.timeOfLastRound == 0) { + secondsElapsed = 0 + console.log('Still waiting on GPP creation') + } else { + secondsElapsed = Math.floor( + (Date.now() - this.state.timeOfLastRound) / 1000 + ) + console.log('Seconds elapsed since last random initiation:', secondsElapsed) + } + + if (secondsElapsed > 3600) { + await this.initiateRand(); + } + + + await this.listenRandThreshold() + + await sleep(this.options.pollingInterval) + } + } + + async listenRegister() { + // check if already registered and skip if true + const eventReg = `RegistrationCompleted` + this.state.zkRandContract.on(eventReg, async (count, event) => { + console.log("\nevent", eventReg, count); + // Proceed to the next step here + const res = await this.state.zkRandContract.startNidkg() + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log("Transaction startNidkg() successful!"); + } else { + console.log("Transaction startNidkg() failed!"); + } + console.log("NIDKG begins...") + }); + } + + async listenNidkg() { + // This will run when the event is emitted + const eventDkg = `NidkgCompleted` + this.state.zkRandContract.on(eventDkg, async (count, event) => { + console.log("\nevent", eventDkg, count); + // read all instances from contract + const ppList = await this.state.zkRandContract.getPpList() + // console.log("\nppList = ", ppList) + // save ppList for rust backend + const ppListHex = ppList.map(subList => + subList.map(num => num.toHexString()) + ); + const obj = JSON.stringify(ppListHex) + await waitForWriteJsonToFile(obj, instancesPath) + //console.log("retrieved all instances from contract") + + + console.log("begin sleep") + await sleep(2000) + console.log("end sleep") + + + // derive global public parameters + const cmd = `RUST_LOG=info ./target/release/client dkg derive` + console.log("running command <", cmd, ">...") + let result = await execPromise(cmd) + console.log(result[`stderr`]) + + const filePath = dkgDir + "gpk.json" + const gpk = readJsonFromFile(filePath); + + const res = await this.state.zkRandContract.computeVk(gpk) + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log("Transaction computeVk(..) successful!"); + } else { + console.log("Transaction computeVk(..) failed!"); + } + + // read global public parameters from the contract and compare them with the local version + const gpkVal = await this.state.zkRandContract.getGpk() + if (BigInt(gpk.x[0]) != gpkVal.x[0] || BigInt(gpk.x[1]) != gpkVal.x[1] + || BigInt(gpk.y[0]) != gpkVal.y[0] || BigInt(gpk.y[1]) != gpkVal.y[1]) { + console.error("gpk doesn't match") + } + + const vkList = await this.state.zkRandContract.getVkList() + const vks = readJsonFromFile(dkgDir + "vks.json") + + if (vkList.length != vks.length) { + console.error("vk list length does not match") + } + + // Check if each element at corresponding indices is equal + for (let i = 0; i < vks.length; i++) { + if (BigInt(vks[i].x) != vkList[i].x || BigInt(vks[i].y) != vkList[i].y) { + console.error(`vk list does not match on ${i}-th vk`) + } + } + }); + } + + async initiateRand() { + // Proceed to the next step here + const res = await this.state.zkRandContract.initiateRandom() + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log("Transaction initiateRandom() successful!"); + this.state.timeOfLastRound = Date.now() + } else { + console.log("Transaction initiateRandom() failed!"); + } + + } + + async listenRandThreshold() { + const eventRandThreshold = `RandomThresholdReached` + this.state.zkRandContract.on(eventRandThreshold, async (roundNum, input, event) => { + console.log("\nevent", eventRandThreshold, `round ${roundNum} input "${input}"`) + + console.log("begin sleep...") + await sleep(2000) + console.log("end sleep") + + let memberCountFromContract = await this.state.zkRandContract.memberCount() + const evals: Eval[] = [] + for (let i = 0; i < memberCountFromContract; i++) { + const evalFromContract = await this.state.zkRandContract.roundToEval(roundNum, i) + if (evalFromContract.indexPlus != 0) { + evals.push(evalFromContract) + } + } + + const pEvals: any = [] + for (let i = 0; i < evals.length; i++) { + const index = evals[i][0] + const value = {x: evals[i][1][0].toHexString(), y: evals[i][1][1].toHexString()} + const proof = {z: evals[i][2][0].toHexString(), c: evals[i][2][1].toHexString()} + + const sigma = { + index: index, + value: value, + proof: proof, + } + + pEvals.push(sigma) + } + + const obj = JSON.stringify(pEvals) + const evalsPath = randDir + `evals.json` + await waitForWriteJsonToFile(obj, evalsPath) + + console.log("begin sleep...") + await sleep(2000) + console.log("end sleep") + + const cmdCombine = `RUST_LOG=info ./target/release/client rand combine "${input}"` + console.log("running command <", cmdCombine, ">...") + let result = await execPromise(cmdCombine) + console.log(result[`stderr`]) + + const cmdVerify = `RUST_LOG=info ./target/release/client rand verify-final "${input}"` + console.log("running command <", cmdVerify, ">...") + result = await execPromise(cmdVerify) + console.log(result[`stderr`]) + + const pseudoPath = randDir + `pseudo.json` + const pseudo = readJsonFromFile(pseudoPath) + console.log("pseudorandom computed", '0x' + Buffer.from(pseudo[`value`]).toString('hex')) + + const res = await this.state.zkRandContract.submitRandom(pseudo) + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log("Transaction submitRandom(..) successful!"); + } else { + console.log("Transaction submitRandom(..) failed!"); + } + + const rand = await this.state.zkRandContract.getLatestRandom() + console.log("✅ pseudorandom from contract", rand.value) + }); + } +} + +export function waitForWriteJsonToFile(obj: string, filePath: string) { + return new Promise((resolve, reject) => { + writeJsonToFile(obj, filePath, () => { + console.log(`JSON file has been saved at ${filePath}`); + resolve(); + }); + }); +} + +export function writeJsonToFile(obj: string, filePath: string, callback: () => void) { + // Write the JSON string to a file + fs.writeFile(filePath, obj, 'utf8', callback); +} + +export const execPromise = promisify(exec); +export function readJsonFromFile(filePath: string): any { + try { + // Read file content + let rawdata = fs.readFileSync(filePath, 'utf-8'); + + // Parse JSON + let jsonData = JSON.parse(rawdata); + + return jsonData; + } catch (error) { + console.error(error); + return null; + } +} \ No newline at end of file diff --git a/services/exec/run.ts b/services/exec/run.ts new file mode 100644 index 0000000..4c8395f --- /dev/null +++ b/services/exec/run.ts @@ -0,0 +1,66 @@ +import { Wallet, providers } from 'ethers' +import { Bcfg } from '@eth-optimism/core-utils' +import * as dotenv from 'dotenv' +import Config from 'bcfg' + +/* Imports: Core */ +import { AdminZkRandService } from '../admin' + +dotenv.config() + +const main = async () => { + const config: Bcfg = new Config('zkRand') + config.load({ + env: true, + argv: true, + }) + + const env = process.env + const L2_NODE_WEB3_URL = config.str('l2-node-web3-url', env.L2_NODE_WEB3_URL) + const ADMIN_PRIVATE_KEY = config.str('admin-private-key', env.ADMIN_PRIVATE_KEY) + + // Optional + const POLLING_INTERVAL = config.uint( + 'polling-interval', + parseInt(env.POLLING_INTERVAL, 10) || 1000 * 12 + ) + + const ZK_RAND_ADDRESS = config.str('zk-rand-address', env.ZK_RAND_ADDRESS) + const NODE_ONE_ADDRESS = config.str('node-one-address', env.NODE_ONE_ADDRESS) + const NODE_TWO_ADDRESS = config.str('node-two-address', env.NODE_TWO_ADDRESS) + const NODE_THREE_ADDRESS = config.str('node-three-address', env.NODE_THREE_ADDRESS) + const NODE_FOUR_ADDRESS = config.str('node-four-address', env.NODE_FOUR_ADDRESS) + const NODE_FIVE_ADDRESS = config.str('node-five-address', env.NODE_FIVE_ADDRESS) + + if (!L2_NODE_WEB3_URL) { + throw new Error('Must pass L2_NODE_WEB3_URL') + } + + const l2Provider = new providers.StaticJsonRpcProvider(L2_NODE_WEB3_URL) + + let wallet: Wallet + wallet = new Wallet(ADMIN_PRIVATE_KEY, l2Provider) + + const chainId = (await l2Provider.getNetwork()).chainId + + const service = new AdminZkRandService({ + l2RpcProvider: l2Provider, + l2Wallet: wallet, + chainId, + zkRandAddress: ZK_RAND_ADDRESS, + nodeOneAddress: NODE_ONE_ADDRESS, + nodeTwoAddress: NODE_TWO_ADDRESS, + nodeThreeAddress: NODE_THREE_ADDRESS, + nodeFourAddress: NODE_FOUR_ADDRESS, + nodeFiveAddress: NODE_FIVE_ADDRESS, + pollingInterval: POLLING_INTERVAL, + }) + + await service.start() +} + +if (require.main === module) { + main() +} + +export default main diff --git a/services/exec/runNode.ts b/services/exec/runNode.ts new file mode 100644 index 0000000..ec79847 --- /dev/null +++ b/services/exec/runNode.ts @@ -0,0 +1,66 @@ +import { Wallet, providers } from 'ethers' +import { Bcfg } from '@eth-optimism/core-utils' +import * as dotenv from 'dotenv' +import Config from 'bcfg' + +/* Imports: Core */ +import { NodeZkRandService } from '../node' + +dotenv.config() + +const main = async () => { + const config: Bcfg = new Config('zkRand') + config.load({ + env: true, + argv: true, + }) + + const env = process.env + const L2_NODE_WEB3_URL = config.str('l2-node-web3-url', env.L2_NODE_WEB3_URL) + const NODE_PRIVATE_KEY = config.str('node-private-key', env.NODE_PRIVATE_KEY) + + // Optional + const POLLING_INTERVAL = config.uint( + 'polling-interval', + parseInt(env.POLLING_INTERVAL, 10) || 1000 * 12 + ) + + const ZK_RAND_ADDRESS = config.str('zk-rand-address', env.ZK_RAND_ADDRESS) + const NODE_ONE_ADDRESS = config.str('node-one-address', env.NODE_ONE_ADDRESS) + const NODE_TWO_ADDRESS = config.str('node-two-address', env.NODE_TWO_ADDRESS) + const NODE_THREE_ADDRESS = config.str('node-three-address', env.NODE_THREE_ADDRESS) + const NODE_FOUR_ADDRESS = config.str('node-four-address', env.NODE_FOUR_ADDRESS) + const NODE_FIVE_ADDRESS = config.str('node-five-address', env.NODE_FIVE_ADDRESS) + + if (!L2_NODE_WEB3_URL) { + throw new Error('Must pass L2_NODE_WEB3_URL') + } + + const l2Provider = new providers.StaticJsonRpcProvider(L2_NODE_WEB3_URL) + + let wallet: Wallet + wallet = new Wallet(NODE_PRIVATE_KEY, l2Provider) + + const chainId = (await l2Provider.getNetwork()).chainId + + const service = new NodeZkRandService({ + l2RpcProvider: l2Provider, + l2Wallet: wallet, + chainId, + zkRandAddress: ZK_RAND_ADDRESS, + nodeOneAddress: NODE_ONE_ADDRESS, + nodeTwoAddress: NODE_TWO_ADDRESS, + nodeThreeAddress: NODE_THREE_ADDRESS, + nodeFourAddress: NODE_FOUR_ADDRESS, + nodeFiveAddress: NODE_FIVE_ADDRESS, + pollingInterval: POLLING_INTERVAL, + }) + + await service.start() +} + +if (require.main === module) { + main() +} + +export default main diff --git a/services/node.ts b/services/node.ts new file mode 100644 index 0000000..304eeb3 --- /dev/null +++ b/services/node.ts @@ -0,0 +1,294 @@ +/* Imports: External */ +import { Contract, Wallet, BigNumber, providers } from 'ethers' +import fs from "fs"; +import {promisify} from "util"; +import {exec} from "child_process"; + +/* Imports: Internal */ +import { sleep } from '@eth-optimism/core-utils' +import { BaseService } from '@eth-optimism/common-ts' + +import zkRandContractABI from '../artifacts/contracts/zkdvrf.sol/zkdvrf.json' + +// /* Imports: Inteface */ +// import { +// BobaLinkPairs, +// BobaLinkContracts, +// BobaLinkContract, +// GasPriceOverride, +// } from './utils/types' + +export const memberDir = `./data/members/` +export const mpksPath = `./data/mpks.json` +export const dkgDir = `./data/dkg/` +export const instancesPath = `./data/dkg/all_instances.json` +export const randDir = `./data/random/` + +interface Eval { + indexPlus: number +} + +export interface GasPriceOverride { + gasLimit: number + gasPrice?: number + } + +interface NodeZkRandOptions { + l2RpcProvider: providers.StaticJsonRpcProvider + l2Wallet: Wallet + // chain ID of the L2 network + chainId: number + + zkRandAddress: string + + nodeOneAddress: string + nodeTwoAddress: string + nodeThreeAddress: string + nodeFourAddress: string + nodeFiveAddress: string + + pollingInterval: number +} + +const optionSettings = {} + +export class NodeZkRandService extends BaseService { + constructor(options: NodeZkRandOptions) { + super('NodeZkRandService', options, optionSettings) + } + + private state: { + zkRandContract: Contract + gasOverride: GasPriceOverride + lastRoundSubmitted: number + } = {} as any + + async _init(): Promise { + this.logger.info('Initializing NodeZkRand service...', { + options: this.options, + }) + + this.logger.info('Connecting to ZkRand contract...', { + bobaLinkPairs: this.options.zkRandAddress, + }) + + this.state.zkRandContract = new Contract( + this.options.zkRandAddress, + zkRandContractABI.abi, + this.options.l2Wallet + ) + + this.logger.info('Connected to ZkRand contract', { + address: this.state.zkRandContract.address, + chainId: this.options.chainId, + rpc: this.state.zkRandContract.provider, + }) + + this.state.gasOverride = { gasLimit: 10000000 } + this.state.lastRoundSubmitted = 0 + } + + async _start(): Promise { + console.log('started') + + while (this.running) { + let contractPhase = await this.state.zkRandContract.contractPhase() + console.log(contractPhase) + if (contractPhase == 0) { + // if addrToNode exists for address + let addrToNode = await this.state.zkRandContract.addrToNode(this.options.l2Wallet.address) + if (addrToNode.nodeAddress == this.options.l2Wallet.address) { + // this indicates the address was added by the admin + await this.registerNode() + await this.listenRegister() + } + } else if (contractPhase == 1) { + // submit public params + await this.submitPP() + // then wait and listen for nidkg completed + await this.listenNidkg() + } + const currentRound = await this.state.zkRandContract.currentRoundNum() + if (currentRound > this.state.lastRoundSubmitted) { + await this.submitPartialEval() + } + await sleep(this.options.pollingInterval) + } + } + + async registerNode() { + // generate member secret key and member public key on grumpkin curve + const index = this.options.l2Wallet.address + const file = `member_${index}` + const command = `RUST_LOG=info ./target/release/client keygen -f ${file}` + + console.log("running command <", command, ">...") + const result = await execPromise(command); + console.log(result[`stderr`]); + + // files need to exist at this location + const filePath = memberDir + file + ".json" + const data = readJsonFromFile(filePath); + const mpk = data[`pk`] + + const res = await this.state.zkRandContract.registerNode(mpk) + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log(`Transaction registerNode(..) from ${index} successful!`); + } else { + console.log(`Transaction registerNode(..) from ${index} failed!`); + } + console.log("member ", index, "registered\n") + } + + async listenRegister() { + const eventName = `RegistrationCompleted` + this.state.zkRandContract.on(eventName, async (count, event) => { + console.log("event", eventName, count); + // Proceed to the next step here + const res = await this.state.zkRandContract.getPkList() + console.log("downloaded all member public keys from contract") + + const pks = res.map(pk => ({x: pk[0].toHexString(), y: pk[1].toHexString()})) + const obj = JSON.stringify(pks); + await waitForWriteJsonToFile(obj, mpksPath); + }); + } + + async listenNidkg() { + const eventName = `NidkgCompleted` + this.state.zkRandContract.on(eventName, async (count, event) => { + console.log("\nevent", eventName, count) + + // read all instances from contract + const ppList = await this.state.zkRandContract.getPpList() + // save ppList for rust backend + const ppListHex = ppList.map(subList => + subList.map(num => num.toHexString()) + ); + const obj = JSON.stringify(ppListHex) + await waitForWriteJsonToFile(obj, instancesPath) + + // each member derives its own secret share and global public parameters + const cmd = `RUST_LOG=info ./target/release/client dkg derive` + const index = await this.state.zkRandContract.getIndexPlus(this.options.l2Wallet.address) + const cmdMember = cmd + ` ${index} -f member_${this.options.l2Wallet.address}` + console.log("running command <", cmdMember, ">...") + const res = await execPromise(cmdMember) + console.log(res[`stderr`]) + }); +} + async submitPartialEval() { + const currentRound = await this.state.zkRandContract.currentRoundNum() + const input = await this.state.zkRandContract.roundInput(currentRound) + + const index = await this.state.zkRandContract.getIndexPlus(this.options.l2Wallet.address) + const cmdEval = `RUST_LOG=info ./target/release/client rand eval ${index} "${input}"` + const cmdVerify = `RUST_LOG=info ./target/release/client rand verify ${index} "${input}"` + + console.log("running command <", cmdEval, ">...") + let result = await execPromise(cmdEval) + console.log(result[`stderr`]) + + console.log("running command <", cmdVerify, ">...") + result = await execPromise(cmdVerify) + console.log(result[`stderr`]) + + const evalPath = randDir + `eval_${index}.json` + const evalJson = readJsonFromFile(evalPath) + const pEval = { + indexPlus: evalJson[`index`], + value: evalJson[`value`], + proof: evalJson[`proof`] + } + + const res = await this.state.zkRandContract.submitPartialEval(pEval) + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log(`Transaction submitPartialEval(..) from member ${this.options.l2Wallet.address} successful!\n`); + this.state.lastRoundSubmitted = currentRound + } else { + console.log(`Transaction submitPartialEval(..) from member ${this.options.l2Wallet.address} failed!\n`); + } + } + + async submitPP() { + const index = await this.state.zkRandContract.getIndexPlus(this.options.l2Wallet.address) + const cmdProve = `RUST_LOG=info ./target/release/client dkg prove ${index}` + const cmdVerify = `RUST_LOG=info ./target/release/client dkg verify ${index}` + + // generate snark proof and instance + console.log("running command <", cmdProve, ">...") + let result = await execPromise(cmdProve) + console.log(result[`stdout`]) + + // verify snark proof and instance + console.log("running command <", cmdVerify, ">...") + result = await execPromise(cmdVerify) + console.log(result[`stdout`]) + + // read snark proof and instance + const proofPath = dkgDir + `proofs/proof_${index}.dat` + const instancePath = dkgDir + `proofs/instance_${index}.json` + + const proof = readBytesFromFile(proofPath) + const instance = readJsonFromFile(instancePath) + + // submit proof and instance to contract + const res = await this.state.zkRandContract.submitPublicParams(instance, proof) + const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); + // Check if the transaction was successful + if (receipt.status === 1) { + console.log(`Transaction submitPublicParams(..) from ${this.options.l2Wallet.address} successful!`); + } else { + console.log(`Transaction submitPublicParams(..) from ${this.options.l2Wallet.address} failed!`); + } + } +} + +export function waitForWriteJsonToFile(obj: string, filePath: string) { + return new Promise((resolve, reject) => { + writeJsonToFile(obj, filePath, () => { + console.log(`JSON file has been saved at ${filePath}`); + resolve(); + }); + }); +} + +export function writeJsonToFile(obj: string, filePath: string, callback: () => void) { + // Write the JSON string to a file + fs.writeFile(filePath, obj, 'utf8', callback); +} + +export const execPromise = promisify(exec); +export function readJsonFromFile(filePath: string): any { + try { + // Read file content + let rawdata = fs.readFileSync(filePath, 'utf-8'); + + // Parse JSON + let jsonData = JSON.parse(rawdata); + + return jsonData; + } catch (error) { + console.error(error); + return null; + } +} + +export function readBytesFromFile(filePath: string): Uint8Array | null { + try { + // Read the file synchronously + const fileData: Buffer = fs.readFileSync(filePath); + + // Access the bytes of the file + const bytes: Uint8Array = new Uint8Array(fileData); + + return bytes; + } catch (err) { + console.error('Error reading file:', err); + return null; + } +} diff --git a/yarn.lock b/yarn.lock index da2ed2c..c2ecb59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,6 +35,39 @@ resolved "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz" integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== +"@eth-optimism/common-ts@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@eth-optimism/common-ts/-/common-ts-0.2.2.tgz#5389905dec8a97809548112b342a48b655369f2e" + integrity sha512-ZTL/+XiSIkrP7LkfkZ+Ab+qXWI3cMrhnnmYEh+i3T6ou5+2J57gkPtA/C5jeDk18zEjDdskASSihWjskA54/XA== + dependencies: + "@eth-optimism/core-utils" "0.8.1" + "@sentry/node" "^6.3.1" + bcfg "^0.1.7" + commander "^9.0.0" + dotenv "^16.0.0" + envalid "^7.2.2" + ethers "^5.5.4" + express "^4.17.1" + lodash "^4.17.21" + pino "^6.11.3" + pino-multi-stream "^5.3.0" + pino-sentry "^0.7.0" + prom-client "^13.1.0" + +"@eth-optimism/core-utils@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.8.1.tgz#ee7d8815f9ddb67ca3e2f3ec1d8515a46af5caf6" + integrity sha512-GJJvw9cBekvR1xH/f2jpgp6MnbWlMBaVm1h3BA0sEzmlaFufTG4ybGrHkL3nQT0Vqtjs3LYjaExkVmsUzpb7xg== + dependencies: + "@ethersproject/abstract-provider" "^5.5.1" + "@ethersproject/bytes" "^5.5.0" + "@ethersproject/providers" "^5.5.3" + "@ethersproject/transactions" "^5.5.0" + "@ethersproject/web" "^5.5.1" + bufio "^1.0.7" + chai "^4.3.4" + ethers "^5.5.4" + "@ethereum-waffle/chai@^3.4.4": version "3.4.4" resolved "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-3.4.4.tgz" @@ -132,7 +165,7 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": +"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.5.1", "@ethersproject/abstract-provider@^5.7.0": version "5.7.0" resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz" integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== @@ -191,7 +224,7 @@ "@ethersproject/logger" "^5.7.0" bn.js "^5.2.1" -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.7.0": +"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.5.0", "@ethersproject/bytes@^5.7.0": version "5.7.0" resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz" integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== @@ -308,7 +341,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.5.3", "@ethersproject/providers@^5.7.2": version "5.7.2" resolved "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -392,7 +425,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.5.0", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -437,7 +470,7 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.5.1", "@ethersproject/web@^5.7.0": version "5.7.1" resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz" integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== @@ -833,6 +866,17 @@ "@sentry/utils" "5.30.0" tslib "^1.9.3" +"@sentry/core@6.19.7": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.19.7.tgz#156aaa56dd7fad8c89c145be6ad7a4f7209f9785" + integrity sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw== + dependencies: + "@sentry/hub" "6.19.7" + "@sentry/minimal" "6.19.7" + "@sentry/types" "6.19.7" + "@sentry/utils" "6.19.7" + tslib "^1.9.3" + "@sentry/hub@5.30.0": version "5.30.0" resolved "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz" @@ -842,6 +886,15 @@ "@sentry/utils" "5.30.0" tslib "^1.9.3" +"@sentry/hub@6.19.7": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.19.7.tgz#58ad7776bbd31e9596a8ec46365b45cd8b9cfd11" + integrity sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA== + dependencies: + "@sentry/types" "6.19.7" + "@sentry/utils" "6.19.7" + tslib "^1.9.3" + "@sentry/minimal@5.30.0": version "5.30.0" resolved "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz" @@ -851,6 +904,15 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sentry/minimal@6.19.7": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.19.7.tgz#b3ee46d6abef9ef3dd4837ebcb6bdfd01b9aa7b4" + integrity sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ== + dependencies: + "@sentry/hub" "6.19.7" + "@sentry/types" "6.19.7" + tslib "^1.9.3" + "@sentry/node@^5.18.1": version "5.30.0" resolved "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz" @@ -866,6 +928,20 @@ lru_map "^0.3.3" tslib "^1.9.3" +"@sentry/node@^6.2.5", "@sentry/node@^6.3.1": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.19.7.tgz#32963b36b48daebbd559e6f13b1deb2415448592" + integrity sha512-gtmRC4dAXKODMpHXKfrkfvyBL3cI8y64vEi3fDD046uqYcrWdgoQsffuBbxMAizc6Ez1ia+f0Flue6p15Qaltg== + dependencies: + "@sentry/core" "6.19.7" + "@sentry/hub" "6.19.7" + "@sentry/types" "6.19.7" + "@sentry/utils" "6.19.7" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + "@sentry/tracing@5.30.0": version "5.30.0" resolved "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz" @@ -882,6 +958,11 @@ resolved "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz" integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== +"@sentry/types@6.19.7": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.19.7.tgz#c6b337912e588083fc2896eb012526cf7cfec7c7" + integrity sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg== + "@sentry/utils@5.30.0": version "5.30.0" resolved "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz" @@ -890,6 +971,14 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sentry/utils@6.19.7": + version "6.19.7" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.19.7.tgz#6edd739f8185fd71afe49cbe351c1bbf5e7b7c79" + integrity sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA== + dependencies: + "@sentry/types" "6.19.7" + tslib "^1.9.3" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" @@ -1394,6 +1483,11 @@ atob@^2.1.2: resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + available-typed-arrays@^1.0.6, available-typed-arrays@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" @@ -1983,6 +2077,20 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcfg@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/bcfg/-/bcfg-0.1.8.tgz#07cfd85f9a36b6df7ca904b0bb99f4deb9685b40" + integrity sha512-1zHJM1/sztv9ldutWyJDZSRYQJEuRBTIzLWZ2J5ncWoWI2T6b4/hahhvQmnzucfeleU5Mx5+bcwCsF2wcWt2vA== + dependencies: + bsert "~0.0.10" + +bcfg@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/bcfg/-/bcfg-0.2.2.tgz#d957cc44fde0b2ec21604f2d29fdb014d6d0bbcf" + integrity sha512-xa7hYK8ZgEV/Wjh+EJiKLLd+h8A0HGyhyntNMvKCeXIGepLqKUL3KYOE5zFz8EBv8sS3XruD5YPmYIjtwFOrZA== + dependencies: + bsert "~0.0.12" + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" @@ -2005,6 +2113,11 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bintrees@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8" + integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw== + bip39@2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz" @@ -2059,7 +2172,7 @@ body-parser@1.20.1: type-is "~1.6.18" unpipe "1.0.0" -body-parser@^1.16.0: +body-parser@1.20.2, body-parser@^1.16.0: version "1.20.2" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -2217,6 +2330,11 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" +bsert@~0.0.10, bsert@~0.0.12: + version "0.0.13" + resolved "https://registry.yarnpkg.com/bsert/-/bsert-0.0.13.tgz#60bfe52b70fc920245496ba5ecab33f121749918" + integrity sha512-gYzSj8I2lDTKvl4aRSYs2CZIpeJugq7RjGhLRG+Jl//gEW5B2u1MKB6exVCL09FqYj6JRQAAgRwQHMOWvr7A8A== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" @@ -2254,6 +2372,11 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.3.0" +bufio@^1.0.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.1.tgz#8d4ab3ddfcd5faa90f996f922f9397d41cbaf2de" + integrity sha512-9oR3zNdupcg/Ge2sSHQF3GX+kmvL/fTPvD0nd5AGLq8SjUYnTz+SlFjK/GXidndbZtIj+pVKXiWeR9w6e9wKCA== + bytes@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" @@ -2376,7 +2499,7 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" -chai@^4.3.6: +chai@^4.3.4, chai@^4.3.6: version "4.4.1" resolved "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz" integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== @@ -2637,6 +2760,16 @@ commander@3.0.2: resolved "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^9.0.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + component-emitter@^1.2.1: version "1.3.1" resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz" @@ -2693,6 +2826,11 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + cookie@^0.4.1: version "0.4.2" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" @@ -3054,7 +3192,7 @@ dom-walk@^0.1.0: resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== -dotenv@^16.4.5: +dotenv@^16.0.0, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== @@ -3071,6 +3209,16 @@ duplexer3@^0.1.4: resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz" integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== +duplexify@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" + integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.2" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" @@ -3145,7 +3293,7 @@ encoding@^0.1.11: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -3165,6 +3313,13 @@ env-paths@^2.2.0: resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +envalid@^7.2.2: + version "7.3.1" + resolved "https://registry.yarnpkg.com/envalid/-/envalid-7.3.1.tgz#5bf6bbb4effab2d64a1991d8078b4ae38924f0d2" + integrity sha512-KL1YRwn8WcoF/Ty7t+yLLtZol01xr9ZJMTjzoGRM8NaSU+nQQjSWOQKKJhJP2P57bpdakJ9jbxqQX4fGTOicZg== + dependencies: + tslib "2.3.1" + errno@~0.1.1: version "0.1.8" resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" @@ -3829,6 +3984,43 @@ express@^4.14.0: utils-merge "1.0.1" vary "~1.1.2" +express@^4.17.1: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + ext@^1.1.2: version "1.7.0" resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz" @@ -3897,6 +4089,16 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-redact@^3.0.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" + integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== + +fast-safe-stringify@^2.0.8: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + fetch-ponyfill@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz" @@ -3985,6 +4187,11 @@ flat@^5.0.2: resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatstr@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" + integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== + flow-stoplight@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/flow-stoplight/-/flow-stoplight-1.0.0.tgz" @@ -6520,6 +6727,42 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== +pino-multi-stream@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pino-multi-stream/-/pino-multi-stream-5.3.0.tgz#2816ec4422c7e37e676a210a1705c7155506afd4" + integrity sha512-4fAGCRll18I+JmoAbxDvU9zc5sera/3c+VgTtUdoNMOZ/VSHB+HMAYtixKpeRmZTDHDDdE2rtwjVkuwWB8mYQA== + dependencies: + pino "^6.0.0" + +pino-sentry@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/pino-sentry/-/pino-sentry-0.7.0.tgz#087717d2787ec437627e97454238ca7ce0562a91" + integrity sha512-/rZO1R/oMcMa4mzfIqW6Afap+TGgVHgB8iZfzwjhLdT2PhyuTUNJ3KJT2eIZ0citsQNv26pxRzIPbqgHuQtUAQ== + dependencies: + "@sentry/node" "^6.2.5" + commander "^2.20.0" + pumpify "^2.0.1" + split2 "^3.1.1" + through2 "^3.0.1" + +pino-std-serializers@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz#b56487c402d882eb96cd67c257868016b61ad671" + integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== + +pino@^6.0.0, pino@^6.11.3: + version "6.14.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-6.14.0.tgz#b745ea87a99a6c4c9b374e4f29ca7910d4c69f78" + integrity sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg== + dependencies: + fast-redact "^3.0.0" + fast-safe-stringify "^2.0.8" + flatstr "^1.0.12" + pino-std-serializers "^3.1.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + sonic-boom "^1.0.2" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" @@ -6560,11 +6803,23 @@ process-nextick-args@~2.0.0: resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + process@^0.11.10: version "0.11.10" resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +prom-client@^13.1.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-13.2.0.tgz#99d13357912dd400f8911b77df19f7b328a93e92" + integrity sha512-wGr5mlNNdRNzEhRYXgboUU2LxHWIojxscJKmtG3R8f4/KiWqyYgXTLHs0+Ted7tG3zFT7pgHJbtomzZ1L0ARaQ== + dependencies: + tdigest "^0.1.1" + promise-to-callback@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz" @@ -6669,6 +6924,15 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +pumpify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-2.0.1.tgz#abfc7b5a621307c728b551decbbefb51f0e4aa1e" + integrity sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw== + dependencies: + duplexify "^4.1.1" + inherits "^2.0.3" + pump "^3.0.0" + punycode@2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz" @@ -6712,6 +6976,11 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" @@ -6774,6 +7043,15 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" +"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" @@ -6797,15 +7075,6 @@ readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.6.0, readable-stream@^3.6.2: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@~1.0.15: version "1.0.34" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" @@ -7372,6 +7641,14 @@ solc@^0.6.3: semver "^5.5.0" tmp "0.0.33" +sonic-boom@^1.0.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e" + integrity sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg== + dependencies: + atomic-sleep "^1.0.0" + flatstr "^1.0.12" + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" @@ -7454,6 +7731,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^3.1.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" + sshpk@^1.7.0: version "1.18.0" resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz" @@ -7489,6 +7773,11 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +stream-shift@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + stream-to-pull-stream@^1.7.1: version "1.7.3" resolved "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.3.tgz" @@ -7713,6 +8002,13 @@ tar@^4.0.2: safe-buffer "^5.2.1" yallist "^3.1.1" +tdigest@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.2.tgz#96c64bac4ff10746b910b0e23b515794e12faced" + integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA== + dependencies: + bintrees "1.0.2" + test-value@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz" @@ -7734,6 +8030,14 @@ through2@^2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" +through2@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + timed-out@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz" @@ -7862,6 +8166,11 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tslib@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tslib@^1.9.3: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" From 62b42179af6e9378bbdfad08069e81daa6d115b4 Mon Sep 17 00:00:00 2001 From: souradeep-das Date: Thu, 11 Jul 2024 23:03:48 +0530 Subject: [PATCH 2/3] rem unused comments --- services/admin.ts | 9 --------- services/node.ts | 9 --------- 2 files changed, 18 deletions(-) diff --git a/services/admin.ts b/services/admin.ts index 82fbe05..5c92348 100644 --- a/services/admin.ts +++ b/services/admin.ts @@ -4,20 +4,11 @@ import fs from "fs"; import {promisify} from "util"; import {exec} from "child_process"; -/* Imports: Internal */ import { sleep } from '@eth-optimism/core-utils' import { BaseService } from '@eth-optimism/common-ts' import zkRandContractABI from '../artifacts/contracts/zkdvrf.sol/zkdvrf.json' -// /* Imports: Inteface */ -// import { -// BobaLinkPairs, -// BobaLinkContracts, -// BobaLinkContract, -// GasPriceOverride, -// } from './utils/types' - export const memberDir = `./data/members/` export const mpksPath = `./data/mpks.json` export const dkgDir = `./data/dkg/` diff --git a/services/node.ts b/services/node.ts index 304eeb3..eba98bd 100644 --- a/services/node.ts +++ b/services/node.ts @@ -4,20 +4,11 @@ import fs from "fs"; import {promisify} from "util"; import {exec} from "child_process"; -/* Imports: Internal */ import { sleep } from '@eth-optimism/core-utils' import { BaseService } from '@eth-optimism/common-ts' import zkRandContractABI from '../artifacts/contracts/zkdvrf.sol/zkdvrf.json' -// /* Imports: Inteface */ -// import { -// BobaLinkPairs, -// BobaLinkContracts, -// BobaLinkContract, -// GasPriceOverride, -// } from './utils/types' - export const memberDir = `./data/members/` export const mpksPath = `./data/mpks.json` export const dkgDir = `./data/dkg/` From a4043697143422122845eeecdbd59078d040bbd3 Mon Sep 17 00:00:00 2001 From: souradeep-das Date: Fri, 12 Jul 2024 19:49:07 +0530 Subject: [PATCH 3/3] add comments --- services/admin.ts | 1 + services/node.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/services/admin.ts b/services/admin.ts index 5c92348..131780d 100644 --- a/services/admin.ts +++ b/services/admin.ts @@ -123,6 +123,7 @@ export class AdminZkRandService extends BaseService { await this.listenNidkg() } + // TODO: need an if here to allow skipping on the second pass const eventGpp = `GlobalPublicParamsCreated` this.state.zkRandContract.on(eventGpp, async (event) => { await this.initiateRand(); diff --git a/services/node.ts b/services/node.ts index eba98bd..ddfad8e 100644 --- a/services/node.ts +++ b/services/node.ts @@ -76,6 +76,7 @@ export class NodeZkRandService extends BaseService { }) this.state.gasOverride = { gasLimit: 10000000 } + // TODO: check the last round from the contract and set this.state.lastRoundSubmitted = 0 } @@ -123,6 +124,8 @@ export class NodeZkRandService extends BaseService { const mpk = data[`pk`] const res = await this.state.zkRandContract.registerNode(mpk) + // const receipt = await res.wait() + // receipt.status const receipt = await this.options.l2RpcProvider.getTransactionReceipt(res.hash); // Check if the transaction was successful if (receipt.status === 1) {