Implemented open error file location

pull/5370/head
ioedeveloper 1 year ago
parent 05e09396e7
commit faa8300641
  1. 14
      apps/circuit-compiler/src/app/components/container.tsx
  2. 12
      apps/circuit-compiler/src/app/components/feedback.tsx
  3. 103
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  4. 3
      apps/circuit-compiler/src/app/types/index.ts
  5. 2
      yarn.lock

@ -23,6 +23,18 @@ export function Container () {
circuitApp.dispatch({ type: 'SET_COMPILER_VERSION', payload: version }) circuitApp.dispatch({ type: 'SET_COMPILER_VERSION', payload: version })
} }
const handleOpenErrorLocation = async (location: string, startRange: string) => {
if (location) {
const fullPathLocation = await circuitApp.plugin.resolveReportPath(location)
await circuitApp.plugin.call('fileManager', 'open', fullPathLocation)
// @ts-ignore
const startPosition: { lineNumber: number; column: number } = await circuitApp.plugin.call('editor', 'getPositionAt', startRange)
// @ts-ignore
await circuitApp.plugin.call('editor', 'gotoLine', startPosition.lineNumber - 1, startPosition.column)
}
}
return ( return (
<section> <section>
<article> <article>
@ -46,7 +58,7 @@ export function Container () {
</WitnessToggler> </WitnessToggler>
</RenderIf> </RenderIf>
<RenderIf condition={circuitApp.appState.status !== 'compiling' && circuitApp.appState.status !== 'computing' && circuitApp.appState.status !== 'generating'}> <RenderIf condition={circuitApp.appState.status !== 'compiling' && circuitApp.appState.status !== 'computing' && circuitApp.appState.status !== 'generating'}>
<CompilerFeedback feedback={circuitApp.appState.feedback} filePathToId={circuitApp.appState.filePathToId} /> <CompilerFeedback feedback={circuitApp.appState.feedback} filePathToId={circuitApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} />
</RenderIf> </RenderIf>
</div> </div>
</div> </div>

@ -1,16 +1,22 @@
import { useState } from 'react' import { useState } from 'react'
import { CompilerFeedbackProps } from '../types' import { CompilerFeedbackProps, CompilerReport } from '../types'
import { RenderIf } from '@remix-ui/helper' import { RenderIf } from '@remix-ui/helper'
import {CopyToClipboard} from '@remix-ui/clipboard' import {CopyToClipboard} from '@remix-ui/clipboard'
import { FeedbackAlert } from './feedbackAlert' import { FeedbackAlert } from './feedbackAlert'
export function CompilerFeedback ({ feedback, filePathToId }: CompilerFeedbackProps) { export function CompilerFeedback ({ feedback, filePathToId, openErrorLocation }: CompilerFeedbackProps) {
const [ showException, setShowException ] = useState<boolean>(true) const [ showException, setShowException ] = useState<boolean>(true)
const handleCloseException = () => { const handleCloseException = () => {
setShowException(false) setShowException(false)
} }
const handleOpenError = (report: CompilerReport) => {
if (report.labels.length > 0) {
openErrorLocation(filePathToId[report.labels[0].file_id], report.labels[0].range.start)
}
}
return ( return (
<div> <div>
<div className="circuit_errors_box py-4"> <div className="circuit_errors_box py-4">
@ -31,7 +37,7 @@ export function CompilerFeedback ({ feedback, filePathToId }: CompilerFeedbackPr
<> <>
{ {
Array.isArray(feedback) && feedback.map((response, index) => ( Array.isArray(feedback) && feedback.map((response, index) => (
<div key={index}> <div key={index} onClick={() => handleOpenError(response)}>
<RenderIf condition={response.type === 'Error'}> <RenderIf condition={response.type === 'Error'}>
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-danger`}> <div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-danger`}>
<FeedbackAlert message={response.message} location={ response.labels[0] ? response.labels[0].message + ` ${filePathToId[response.labels[0].file_id]}:${response.labels[0].range.start}:${response.labels[0].range.end}` : null} /> <FeedbackAlert message={response.message} location={ response.labels[0] ? response.labels[0].message + ` ${filePathToId[response.labels[0].file_id]}:${response.labels[0].range.start}:${response.labels[0].range.end}` : null} />

@ -2,8 +2,7 @@ import { PluginClient } from '@remixproject/plugin'
import { createClient } from '@remixproject/plugin-webview' import { createClient } from '@remixproject/plugin-webview'
import EventManager from 'events' import EventManager from 'events'
import pathModule from 'path' import pathModule from 'path'
// @ts-ignore import { parse, compile, generate_witness, generate_r1cs, compiler_list } from 'circom_wasm'
import { parse, compile, generate_witness, generate_r1cs, compiler_list } from '../../../pkg'
import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper' import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper'
import { CompilationConfig, CompilerReport } from '../types' import { CompilationConfig, CompilerReport } from '../types'
@ -13,8 +12,9 @@ export class CircomPluginClient extends PluginClient {
version: "2.1.5", version: "2.1.5",
prime: "bn128" prime: "bn128"
} }
public lastCompiledCircuitPath: string = '' private lastCompiledCircuitPath: string = ''
public lastParsedFiles: Record<string, string> = {} private lastParsedFiles: Record<string, string> = {}
private lastCompiledFile: string = ''
constructor() { constructor() {
super() super()
@ -43,7 +43,6 @@ export class CircomPluginClient extends PluginClient {
this.lastParsedFiles = await this.resolveDependencies(path, fileContent, this.lastParsedFiles) this.lastParsedFiles = await this.resolveDependencies(path, fileContent, this.lastParsedFiles)
const parsedOutput = parse(path, this.lastParsedFiles) const parsedOutput = parse(path, this.lastParsedFiles)
console.log('parsedOutput: ', parsedOutput)
try { try {
const result: CompilerReport[] = JSON.parse(parsedOutput.report()) const result: CompilerReport[] = JSON.parse(parsedOutput.report())
const mapReportFilePathToId = {} const mapReportFilePathToId = {}
@ -139,6 +138,7 @@ export class CircomPluginClient extends PluginClient {
throw new Error(circuitErrors) throw new Error(circuitErrors)
} else { } else {
this.lastCompiledFile = path
const fileName = extractNameFromKey(path) const fileName = extractNameFromKey(path)
this.lastCompiledCircuitPath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'wasm') this.lastCompiledCircuitPath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'wasm')
@ -156,63 +156,6 @@ export class CircomPluginClient extends PluginClient {
this.internalEvents.emit('circuit_compiling_done', []) this.internalEvents.emit('circuit_compiling_done', [])
} }
} }
// const witness = await generate_witness(compiledOutput, '{ "identityTrapdoor": "12656283236575022300303467601783819380815431272685589718060054649894766174337", "identityNullifier": "15178877681550417450385541477607788220584140707925739215609273992582659710290", "treePathIndices": "0", "treeSiblings": "1", "externalNullifier": "5df6e0e3480d6fbc32925076897ec6b9b935d75ae8f4d9f4858a426f8f6a4ab": "signalHash": "[85, 139, 239, 32, 221, 194, 165, 19, 20, 52, 104, 144, 41, 16, 40, 204, 171, 245, 198, 77, 94, 143, 30, 112, 105, 165, 33, 15, 62, 156, 18, 118]"}')
// const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// const r1cs_ipfs = "http://127.0.0.1:8081/ipfs/QmVzKPbmyuaTUjoLqWEA5wPAMkUqe4t6WYKHeeC9Dot4ds";
// const r1cs_ipfs1 = "http://127.0.0.1:8081/ipfs/QmXP1BC2bc8n1zPnexPoRpFCEDoG9QZc3yZn5Wik5w2TAm";
// const buff = await fetch(r1cs_ipfs1).then( function(res) {
// return res.arrayBuffer();
// }).then(function (ab) {
// return new Uint8Array(ab);
// });
// console.log('r1cs_buff: ', buff)
// // const wasm = "http://127.0.0.1:8081/ipfs/QmUbpEvHHKaHEqYLjhn93S8rEsUGeqiTYgRjGPk7g8tBbz";
// const zkey_0 = { type: "mem" };
// const zkey_1 = { type: "mem" };
// const zkey_final = { type: "mem" };
// console.log('newZkey')
// // @ts-ignore
// await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_0);
// console.log('contribute')
// // @ts-ignore
// await snarkjs.zKey.contribute(zkey_0, zkey_1, "first_contribution", "entropy_QmbMk4ksBYLQzJ6TiZfzaALF8W11xvB8Wz6a2GrG9oDrXW");
// console.log('beacon')
// // @ts-ignore
// await snarkjs.zKey.beacon(zkey_1, zkey_final, "B3", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", 10);
// console.log('verifyFromR1cs')
// // @ts-ignore
// const verifyFromR1csResult = await snarkjs.zKey.verifyFromR1cs(r1cs, ptau_final, zkey_final);
// console.assert(verifyFromR1csResult);
// console.log('verifyFromInit')
// // @ts-ignore
// const verifyFromInit = await snarkjs.zKey.verifyFromInit(zkey_0, ptau_final, zkey_final);
// console.assert(verifyFromInit);
// console.log('exportVerificationKey')
// // @ts-ignore
// const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
// console.log('vKey: ', vKey)
// const templates = {
// groth16: await remix.call('fileManager', 'readFile', './zk/templates/groth16_verifier.sol.ejs')
// }
// const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
// await remix.call('fileManager', 'writeFile', './zk/build/zk_verifier.sol', solidityContract)
// console.log('buffer', (zkey_final as any).data.length)
// await remix.call('fileManager', 'writeFile', './zk/build/zk_setup.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
// console.log('setup done.')
} }
async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> { async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> {
@ -337,4 +280,40 @@ export class CircomPluginClient extends PluginClient {
) )
return output return output
} }
async resolveReportPath (path: string): Promise<string> {
// @ts-ignore
const pathExists = await this.call('fileManager', 'exists', path)
if (pathExists) return path
else {
// if include import (path) does not exist, try to construct relative path using the original file path (current file opened in editor)
let relativePath = pathModule.resolve(this.lastCompiledFile.slice(0, this.lastCompiledFile.lastIndexOf('/')), path)
if (relativePath.indexOf('/') === 0) relativePath = relativePath.slice(1)
// @ts-ignore
const relativePathExists = await this.call('fileManager', 'exists', relativePath)
if (relativePathExists) return relativePath
else {
if (path.startsWith('circomlib')) {
// try to resolve include import from github if it is a circomlib dependency
const splitInclude = path.split('/')
const version = splitInclude[1].match(/v[0-9]+.[0-9]+.[0-9]+/g)
if (version && version[0]) {
path = `/.deps/https/raw.githubusercontent.com/iden3/circomlib/${version[0]}/circuits/${splitInclude.slice(2).join('/')}`
} else {
path = `/.deps/https/raw.githubusercontent.com/iden3/circomlib/master/circuits/${splitInclude.slice(1).join('/')}`
}
// @ts-ignore
const exists = await this.call('fileManager', 'exists', path)
if (exists) return path
else throw new Error(`Report path ${path} do no exist in the Remix FileSystem`)
} else {
throw new Error(`Report path ${path} do no exist in the Remix FileSystem`)
}
}
}
}
} }

@ -47,7 +47,8 @@ export type PrimeValue = "bn128" | "bls12381" | "goldilocks"
export type CompilerFeedbackProps = { export type CompilerFeedbackProps = {
feedback: string | CompilerReport[], feedback: string | CompilerReport[],
filePathToId: Record<string, string> filePathToId: Record<string, string>,
openErrorLocation: (location: string, startRange: string) => void
} }
export type CompilerReport = { export type CompilerReport = {

@ -9729,7 +9729,7 @@ circom_runtime@0.1.22:
"circom_wasm@https://github.com/ioedeveloper/circom_wasm.git": "circom_wasm@https://github.com/ioedeveloper/circom_wasm.git":
version "0.0.0-alpha.7" version "0.0.0-alpha.7"
resolved "https://github.com/ioedeveloper/circom_wasm.git#dca0ba5f8f9c541e9f7e927bb8c32d6e326ce487" resolved "https://github.com/ioedeveloper/circom_wasm.git#247ef96f119227cb9d33b995cb447c28ee9ab0cc"
circular-json@^0.3.0: circular-json@^0.3.0:
version "0.3.3" version "0.3.3"

Loading…
Cancel
Save