-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Recursion in public kernels and rollup circuits #6425
Conversation
Changes to circuit sizes
🧾 Summary (100% most significant diffs)
Full diff report 👇
|
…ges into pw/proving-e2e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor nits and suggestions on possible future cleanup, but overall looks good to me! Can't wait to get functions working! 🔥
* @param inputs - The public kernel inputs. | ||
* @returns The witness map | ||
*/ | ||
export function convertPublicSetupRollupInputsToWitnessMap(inputs: PublicKernelCircuitPrivateInputs): WitnessMap { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typo. looks like the functions above also call them rollups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
// Verify the previous kernel proof | ||
assert(verify_kernel_proof(self.kernel_data.proof), "kernel proof verification failed"); | ||
// Verify the kernel circuit proof | ||
verify_kernel_proof(self.kernel_data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to have a trait like Verifiable
that all kernel data structs implement, with getters for the vk and public inputs.
Then we could have a single generic verify_protocol_proof
.
|
||
public async verifyProofForCircuit(circuit: ProtocolArtifact, proof: Proof) { | ||
// Create random directory to be used for temp files | ||
const bbWorkingDirectory = `${this.config.bbWorkingDirectory}/${randomBytes(8).toString('hex')}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use your foundations/fs utility here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, thought I had caught them all.
const vkData = await this.updateVerificationKeyAfterProof(provingResult.vkPath!, circuitType); | ||
|
||
// Read the proof and then cleanup up our temporary directory | ||
const rawProof = await fs.readFile(`${provingResult.proofPath!}/${PROOF_FILENAME}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this line the only real difference between createProof and createRecursiveProof?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think you are right actually. Well spotted. I hadn't realised they had converged to be so similar.
(await getTestContractOnPXE(1)).methods.emit_unencrypted(43), | ||
(await getTestContractOnPXE(2)).methods.create_l2_to_l1_message_public(45, 46, EthAddress.random()), | ||
(await getTokenContract(3)).methods.transfer(schnorrWalletAddress.address, recipient.address, 1000, 0), | ||
//(await getTestContractOnPXE(1)).methods.emit_unencrypted(43), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you leaving this commented out just for when we have public working?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, once we have public functions working we should be able to exercise fee payment flows as well.
// stop the fake provers | ||
proverAgents: 0, | ||
realProofs: true, | ||
minTxsPerBlock: 1, // min 2 txs per block |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the comment is corrct, the code is wrong. Nice catch!
tx, | ||
inputs, | ||
treeSnapshots, | ||
provingState.privateKernelVerificationKeys.privateKernelToPublicCircuit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it doesn't matter based on the comment above, but I'm confused why we use the ToPublic
keys here, but prepare for the base rollup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, if there are public functions, then this is the key that will be provided to the first public kernel to verify the previous private kernel. The key that gets given to the base rollup in this case will be the publicKernelTail
and this is done once that circuit has been proven.
If there no public functions then it uses the priveKernelCircuit
key provided further up to prepareBaseRollupInputs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@just-mitch IIUC the ToPublic
key just gets ignored if there are no public function calls in this tx (see the if statement below
if (!numPublicKernels) {
// no public functions, go straight to the base rollup
logger.debug(`Enqueueing base rollup for tx ${txIndex}`);
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
return;
}
tx, | ||
inputs, | ||
treeSnapshots, | ||
provingState.privateKernelVerificationKeys.privateKernelToPublicCircuit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@just-mitch IIUC the ToPublic
key just gets ignored if there are no public function calls in this tx (see the if statement below
if (!numPublicKernels) {
// no public functions, go straight to the base rollup
logger.debug(`Enqueueing base rollup for tx ${txIndex}`);
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
return;
}
This PR adds commands to generate the verification Solidity contract for the RootRollup so that block proofs can be validated onchain Stacked on top of #6425
This PR introduces recursion throughout the server side protocol circuits.
Aggregation Object
code.Closes [Proving Phase 1] Update benchmarks #5241 [Proving Phase 1] Create e2e test exercising all circuits #5245 [Proving Phase 4]: Recursively verify private kernel proofs within the first public kernel circuit #5984 [Proving Phase 4]: Recusively verify public kernel proofs #5985 [Proving Phase 4]: Update benchmarks for public kernel proving #5986 [Proving Phase 5]: Recusively verify the proof from private/public kernels within the base rollup #5989 [Provng Phase 5]: Recursively verify the base rollup proofs within the merge rollup #5990 [Proving Phase 5]: Recusively verify the base/merge proofs within the root rollup #5991