Skip to content
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(aztec-noir): align public and private execution patterns #1515

Merged
merged 20 commits into from
Aug 15, 2023

Conversation

Maddiaa0
Copy link
Member

@Maddiaa0 Maddiaa0 commented Aug 10, 2023

Metadata

fixes

Relevant discussions

Overview

This PR aims to align the implementations of Public and Private state.

  • Currently public circuits do not have a context object, this will cause developers to have to learn more than one code path.

Other work I am thinking of completing within this PR
Right now, PublicCircuitPublicInputs (The object which is fed to the public kernel after circuit completion) is not created within the application circuit. It is created within the sequencer. If we zoom out, this is not a direct security concern as execution is occuring within the sequencer, however it does break away from the pattern seen within PrivateExecution where the result of each execution is the PrivateCircuitPublicInputs object.

We could leave this as is, (alot of this code will be dumped when the vm arrives). However similar code paths will make building the library easier. For example, for some library methods we have two implementations, one for public and one for private. More and more standardisation would allow these methods to take in a generic context and utilise the same code paths. (A goal I think is worth pursuing).

Checklist:

Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.

  • If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag.
  • I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code.
  • Every change is related to the PR description.
  • I have linked this pull request to relevant issues (if any exist).

@Maddiaa0 Maddiaa0 changed the title feat: align public and private execution patterns feat(aztec-noir): align public and private execution patterns Aug 10, 2023
@iAmMichaelConnor
Copy link
Contributor

Tagging @sirasistant, as this touches on some design decisions you've made in the past.

let returnValue = base_value + context.chain_id() + context.version() + context.block_number() + context.timestamp();

context.return_values.push(returnValue);
// TODO(MADDIAA): MAYBE we put the return values inside the finish object? That could have nice UX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think return_values are part of the PublicCircuitPublicInputs, although I think there are plans to instead return a return_values_hash. When that change happens, the simulator will keep track of the return_values, and the simulator could return those.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but it's true that even if we do return_values_hash we don't need to keep them inside the context, they can instead be passed as arguments to finish() both in public and private, and when we have return_values_hash then finish(hash_returns(whatever))

@Maddiaa0 Maddiaa0 requested a review from LHerskind August 14, 2023 19:08
@Maddiaa0 Maddiaa0 marked this pull request as ready for review August 14, 2023 19:08
Copy link
Contributor

@LHerskind LHerskind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job. Got some minor comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come the ordering change in here? Was there a mismatch or was this to follow the structure of historic_block_data?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ive made a followup pr that does some reorg to prevent structuring mistakes like this: #1567.

It can be merged into this one or run as a standalone pr. It was a big change so Ive broken it up

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the cpp using a different formatter? Some of these files have different formats without other stuff changing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, i think these changes came from adams commits where he was using clion as his ide

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the tidy not have been angry about it? 👀

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question, im i suppose it exists within both rulesets

@@ -62,7 +62,7 @@ KernelCircuitPublicInputs<NT> native_public_kernel_circuit_private_previous_kern
// validate the kernel execution common to all invocation circumstances
common_validate_kernel_execution(builder, public_kernel_inputs);

// vallidate our public call hash
// valLidate our public call hash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// valLidate our public call hash
// validate our public call hash

);

const argsHash = witnessReader.readField();
const returnValues = padArrayEnd(witnessReader.readFieldArray(RETURN_VALUES_LENGTH), Fr.ZERO, RETURN_VALUES_LENGTH);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to pad it when reading array of length RETURN_VALUES_LENGTH? Won't you be filling RETURN_VALUES_LENGTH - RETURN_VALUES_LENGTH = 0 elements with Fr.ZERO values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is there as a sanity check, i can remove

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just seemed strange when no others had it.

@@ -160,7 +160,8 @@ export class PublicExecutor {
},
});

const returnValues = extractReturnWitness(acir, partialWitness).map(fromACVMField);
const publicInputs = extractPublicCircuitPublicInputs(partialWitness, acir);
const { returnValues } = publicInputs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason you are not doing? Don't seems like you are using the publicInputs

     const { returnValues } = extractPublicCircuitPublicInputs(partialWitness, acir);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of the public inputs is dependant on some ongoing discussions around how we will handle context in the vm setting. I am unsure if we will use the publicInputs further. When i started the work I was under the impression that I was going to. I will update

@@ -261,6 +261,10 @@ impl ContractStorageRead {
fn hash(self) -> Field {
dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]
}

fn empty() -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need empty_contract_storage_read() if we have empty here, seems like we should use the empty instead for clarity.

In call_public_function_with_packed_args in the context we populate contract_storage_read with the empty ones.

]
}
}

fn empty_block_data() -> HistoricBlockData {
HistoricBlockData{ private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, prev_global_variables_hash: 0, public_data_tree_root: 0 }
HistoricBlockData{ private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should replace this with an HistoricBlockData::empty() instead? Seems better for consistency. Only used in context.call_public_function_with_packed_args.


fn empty() -> Self {
Self { storage_slot: 0, old_value: 0, new_value: 0 }
}
}

fn empty_contract_storage_update_request() -> ContractStorageUpdateRequest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My brain want us to use ContractStorageUpdateRequest::empty() where this was used and get rid of this one.

prover_address: Field,


// TODO: include globals in here and check them elsewhere
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you do this as part of this pr or create an issue for it?

Copy link
Member Author

@Maddiaa0 Maddiaa0 Aug 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets create an issue, it is out of scope
edit: #1567

@@ -211,7 +214,7 @@ export class PublicProcessor {
const unencryptedLogsHash = to2Fields(result.unencryptedLogs.hash());
const unencryptedLogPreimagesLength = new Fr(result.unencryptedLogs.getSerializedLength());

return PublicCircuitPublicInputs.from({
const pub = PublicCircuitPublicInputs.from({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you printed pub for debugging, but as not done anymore, you might as well return it directly here 👍.

Comment on lines 23 to 40
open fn mint(
_inputs: PublicContextInputs,
inputs: PublicContextInputs,
amount: Field,
recipient: Field,
) -> pub Field {
) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([amount, recipient]));

let storage = Storage::init();
let recipient_balance = storage.balances.at(recipient);
let new_amount = recipient_balance.read() + amount;
// TODO: Remove return value.
let _hash = emit_unencrypted_log("Coins minted");
recipient_balance.write(new_amount);
new_amount

context.return_values.push(new_amount);

context.finish()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlighting this diff, so I can link to it elsewhere, for a discussion.

Copy link
Contributor

@LHerskind LHerskind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@Maddiaa0 Maddiaa0 merged commit 35a81c3 into master Aug 15, 2023
@Maddiaa0 Maddiaa0 deleted the md/p-context branch August 15, 2023 16:29
@Maddiaa0 Maddiaa0 mentioned this pull request Aug 15, 2023
Maddiaa0 added a commit that referenced this pull request Aug 15, 2023
fixes dirty merge between #1570 and #1515
Maddiaa0 added a commit that referenced this pull request Aug 18, 2023
…ts (#1571)

Add a bit more consistency across the code base, I came into these
issues when working on
#1515.

Running this in a separate pr as it is not directly related. And to
minimise the diff between the two

## Overview
Replaces 6 seperate roots with one single data structure that is used
literally everywhere else
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants