diff --git a/examples/confidential-coins/scripts/setup b/examples/confidential-coins/scripts/setup index 25698e8..398b72c 100755 --- a/examples/confidential-coins/scripts/setup +++ b/examples/confidential-coins/scripts/setup @@ -41,7 +41,7 @@ POWERSOFTAUFILE="${TEST_DIR}/powersOfTau28_hez_final_08.ptau" # Pre-generated powersOfTau from snarkjs # if ! [ -e ${POWERSOFTAUFILE} ] ; then - curl https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_08.ptau --output ${POWERSOFTAUFILE} + curl https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_08.ptau --output ${POWERSOFTAUFILE} fi # We just need the following files from this setup script. diff --git a/examples/demo-app/core/scripts/setup b/examples/demo-app/core/scripts/setup index 00a31d4..36e3929 100755 --- a/examples/demo-app/core/scripts/setup +++ b/examples/demo-app/core/scripts/setup @@ -37,9 +37,8 @@ circom ${TEST_DIR}/circuit.circom --r1cs --wasm --output ${TEST_DIR} POWERSOFTAUFILE="${TEST_DIR}/powersOfTau28_hez_final_08.ptau" # Pre-generated powersOfTau from snarkjs -# if ! [ -e ${POWERSOFTAUFILE} ] ; then - curl https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_08.ptau --output ${POWERSOFTAUFILE} + curl https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_08.ptau --output ${POWERSOFTAUFILE} fi # We just need the following files from this setup script. diff --git a/upa/scripts/test_upa b/upa/scripts/test_upa index 4554a68..cc9f98a 100755 --- a/upa/scripts/test_upa +++ b/upa/scripts/test_upa @@ -169,7 +169,7 @@ pushd _test_upa # --submission-file submit-multi-4.submission.json # Extract the submissions - upa get-submission `cat submit-1.tx.hash` > submit-1.submission.json + upa get-submission --events `cat submit-1.tx.hash` > submit-1.submission.json upa get-submission `cat submit-multi-4.tx.hash` > submit-multi-4.submission.json multi_4_submissionid=`jq -r .submissionId submit-multi-4.submission.json` diff --git a/upa/scripts/utils.sh b/upa/scripts/utils.sh index e0b65bd..b0e9c90 100644 --- a/upa/scripts/utils.sh +++ b/upa/scripts/utils.sh @@ -94,13 +94,20 @@ function start_daemon() { # 1 - name function stop_daemon() { - pid_file="$1.pid" - cid_file="$1.cid" if [ "${DOCKER}" == "1" ] ; then + cid_file="$1.cid" + if ! [ -e ${cid_file} ] ; then + echo "$1 has no CID file: ${cid_file}" + return + fi + cid=$(cat ${cid_file}) - docker container kill ${cid} + docker container kill ${cid} || \ + echo "Failed stopping container ${cid}. It may have died." + rm ${cid_file} else + pid_file="$1.pid" if ! [ -e ${pid_file} ] ; then echo "$1 has no PID file: ${pid_file}" return diff --git a/upa/src/sdk/events.ts b/upa/src/sdk/events.ts index 12a14d0..7f0a7dd 100644 --- a/upa/src/sdk/events.ts +++ b/upa/src/sdk/events.ts @@ -122,6 +122,27 @@ export abstract class EventGetterBase< return output; } + public parseTransactionReceipt( + txReceipt: ethers.TransactionReceipt + ): EventSet { + const evName = this.eventName(); + const events: EventOutput[] = []; + for (const log of txReceipt.logs) { + const parsed = this.upa.interface.parseLog(log as unknown as ethers.Log)!; + const name = parsed.name; + if (name === evName) { + events.push(this.parseEvent(parsed as unknown as TypedEventLog)); + } + } + return { + blockNumber: txReceipt.blockNumber, + txHash: txReceipt.hash, + events, + }; + } + + abstract eventName(): string; + // TODO: There should be a generic way to write this. abstract parseEvent(ev: TypedEventLog): EventOutput; } @@ -151,6 +172,10 @@ export class ProofSubmittedEventGetter extends EventGetterBase< super(upa, upa.filters.ProofSubmitted(...args)); } + eventName(): string { + return "ProofSubmitted"; + } + parseEvent( ev: TypedEventLog ): ProofSubmittedEvent.OutputObject { @@ -345,6 +370,10 @@ export class SubmissionVerifiedEventGetter extends EventGetterBase< super(upa, upa.filters.SubmissionVerified(...args)); } + eventName(): string { + return "SubmissionVerified"; + } + parseEvent( ev: TypedEventLog ): SubmissionVerifiedEvent.OutputObject { @@ -416,6 +445,10 @@ export class VKRegisteredEventGetter extends EventGetterBase< super(upa, upa.filters.VKRegistered()); } + eventName(): string { + return "VKRegistered"; + } + parseEvent( ev: TypedEventLog ): VKRegisteredEvent.OutputObject { @@ -439,6 +472,10 @@ export class ChallengeEventGetter extends EventGetterBase< super(upa, upa.filters.Challenge()); } + eventName(): string { + return "Challenge"; + } + // eslint-disable-next-line parseEvent(ev: TypedEventLog): ChallengeEventOutput { return {}; @@ -458,6 +495,10 @@ export class SubmissionChallengeSuccessEventGetter extends EventGetterBase< super(upa, upa.filters.SubmissionChallengeSuccess()); } + eventName(): string { + return "SubmissionChallengeSuccess"; + } + // eslint-disable-next-line parseEvent(ev: TypedEventLog): ChallengeEventOutput { return {}; diff --git a/upa/src/tool/getSubmission.ts b/upa/src/tool/getSubmission.ts index abbab11..4162ad6 100644 --- a/upa/src/tool/getSubmission.ts +++ b/upa/src/tool/getSubmission.ts @@ -1,9 +1,12 @@ -import { command, positional, string } from "cmd-ts"; +import { command, flag, positional, string } from "cmd-ts"; import * as options from "./options"; import * as ethers from "ethers"; import * as config from "./config"; import * as utils from "../sdk/utils"; import { Submission } from "../sdk"; +import { EventSet, ProofSubmittedEventGetter } from "../sdk/events"; +// eslint-disable-next-line +import { ProofSubmittedEvent } from "../../typechain-types/contracts/tests/TestUpgradedUpaVerifier"; export const getSubmission = command({ name: "get-submission", @@ -15,9 +18,18 @@ export const getSubmission = command({ displayName: "tx-id", description: "Tx Id of the submission to retrieve", }), + events: flag({ + long: "events", + description: "Dump event data for the submission", + }), }, description: "Get the on-chain submission information associated with a Tx", - handler: async function ({ chainEndpoint, instance, txId }): Promise { + handler: async function ({ + chainEndpoint, + instance, + txId, + events, + }): Promise { const provider = new ethers.JsonRpcProvider(chainEndpoint); const { verifier } = await config.upaFromInstanceFile(instance, provider); @@ -30,6 +42,19 @@ export const getSubmission = command({ txReceipt ); + // If the events flag is given, dump the event data. + if (events) { + const evGetter = new ProofSubmittedEventGetter(verifier); + const eventSet = evGetter.parseTransactionReceipt(txReceipt); + // Put the event set on an `eventSet` attribute of the submission + // object. + ( + submission as unknown as { + eventSet: EventSet; + } + ).eventSet = eventSet; + } + console.log(utils.JSONstringify(submission)); }, }); diff --git a/upa/src/tool/isVerified.ts b/upa/src/tool/isVerified.ts index c154ec4..467c4bc 100644 --- a/upa/src/tool/isVerified.ts +++ b/upa/src/tool/isVerified.ts @@ -97,3 +97,37 @@ export const isVerified = command({ process.exit(verified ? 0 : 1); }, }); + +export const isUnitSubmissionVerified = command({ + name: "is-unit-submission", + description: + "Query UPA contract for verification status of a single-proof submission " + + "with the given proofid", + args: { + chainEndpoint: options.chainEndpoint(), + instance: options.instance(), + proofId: positional({ + type: string, + displayName: "proof-id", + description: "Proof Id to verifiy (must be part of single submission)", + }), + + proofReferenceFile: options.proofReferenceFile(), + }, + handler: async function ({ + chainEndpoint, + instance, + proofId, + }): Promise { + const provider = new ethers.JsonRpcProvider(chainEndpoint); + const upa = await config.upaFromInstanceFile(instance, provider); + + const verified = await upa.verifier.getFunction("isProofVerified(bytes32)")( + proofId + ); + + // write 1/0 to stdout and use exit status to indicate validity + console.log(verified ? "1" : "0"); + process.exit(verified ? 0 : 1); + }, +}); diff --git a/upa/src/tool/query.ts b/upa/src/tool/query.ts index ace8d62..1df3e93 100644 --- a/upa/src/tool/query.ts +++ b/upa/src/tool/query.ts @@ -4,7 +4,11 @@ import { getConfig } from "./getConfig"; import { chainEndpoint, instance } from "./options"; import { ethers } from "ethers"; import { upaFromInstanceFile } from "./config"; -import { isVerified, isSubmissionVerified } from "./isVerified"; +import { + isVerified, + isSubmissionVerified, + isUnitSubmissionVerified, +} from "./isVerified"; import { getAggregatedProofVerifier } from "./aggregatedProofVerifier"; const getVerifierByteCode = command({ @@ -39,5 +43,6 @@ export const query = subcommands({ "verifier-bytecode": getVerifierByteCode, "is-verified": isVerified, "is-submission-verified": isSubmissionVerified, + "is-unit-submission-verified": isUnitSubmissionVerified, }, });