Skip to content

Commit

Permalink
feat: update context docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Maddiaa0 committed Sep 6, 2023
1 parent 464b3ae commit 2ab0f65
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 47 deletions.
75 changes: 49 additions & 26 deletions docs/docs/dev_docs/contracts/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ title: Aztec.nr Context
description: Documentation of Aztec's Private and Public execution contexts
hide_table_of_contents: false
---
# Overview of this page (change this title)
# The Function Context

We want ot include some over arching details on what is included inside the context structure, and give an overview of what it actually is.
## What is the context
The context is a variable that is made available within every function in `Aztec.nr`. As mentioned in the [kernel circuit documentation](../../concepts/advanced/circuits/kernels/private_kernel.md). At the beginning of a function's execution, the context contains all of the kernel information that application needs to execute. During the lifecycle of a transaction, the function will update the context with each of it's side effects (created notes, nullifiers etc.). At the end of a function's execution the mutated context is returned to the kernel to be checked for validity.

## What is the context.
The context is a variable that is made available within every function in `Aztec.nr`. As mentioned in the KERNEL CIRCUIT SECTION. The application context is a structure that contains all of the infromation a function needs from the kernel circuit, as well as all the information the kernel needs after a function execution completes.
Behind the scenes, Aztec noir will pass data the kernel needs to and from a circuit, this is abstracted away from the developer. In an developer's eyes; the context is a useful structure that allows access and mutate the state of the `Aztec` blockchain.

Behind the scenes, Aztec noir will pass data the kernel needs to and from a circuit, this is completely abstracted away from the developer. In an application developer's eyes; the context is a useful structure that allows access to anything on the aztec blockchain outside of the current circuit (REWORD THIS SECTION).
## Two context's one API
The `Aztec` blockchain contains two execution environments (ADD REFERENCE).
- Private, for private transactions taking place on user's devices.
- Public, for public transactions taking place on the network's sequencers.

## What is contained within the context.
As there are two distinct execution environments, they both require slightly differing execution contexts. Despite their differences; the API's for interacting with each are unified. Leading to minimal context switch when working between the two environments.

The code snippet below shows what is currently contained within the private context.
The following section will cover both contexts.

## The Private Context

The code snippet below shows what is contained within the private context.
#include_code private-context /yarn-project/noir-libs/noir-aztec/src/context.nr rust

### Private Context Broken Down
Expand Down Expand Up @@ -51,40 +58,56 @@ Another structure that is contained within the context is the Historic Block Dat

#include_code historic-block-data /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

## TODO: gloss this up
Having these tree's on hand allows for a host of interesting use cases. If you can create a merkle proof which matches the root of these trees. Then you can prove that a value exists in the current state of the system.

### Contract Deployment Data
Just like with the `is_contract_deployment` flag mentioned earlier. This flag will only be set to true when the current transaction is one in which a contract is being deployed.

#### TODO : WAT CONTAIN AND WAT DO
Just like with the `is_contract_deployment` flag mentioned earlier. This data will only be set to true when the current transaction is one in which a contract is being deployed.

#include_code contract-deployment-data /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

### Private Global Variables
TODO:
- include in this section how the global variabels can be accessed and what they contain
In the private execution context, we only have access to a subset of the total global variables, we are restricted to those which can be reliably proven by the kernel circuits.

#include_code private-global-variables /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

### Args Hash
To allow for flexibility in the number of arguments supported by Aztec functions, all function inputs are reduced to a singular value which can be proven from within the application.

The `args_hash` is the result of pedersen hashing all of a function's inputs.

## Args Hash
### Return Values
The return values are a set of values that are returned from an applications execution to be passed to other functions through the kernel. Developers do not need to worry about passing their function return values to the `context` directly as `Aztec.nr` takes care of it for you. See the documentation surrounding `Aztec.nr` [macro expansion](../../dev_docs/contracts/functions.md#after-expansion) for more details.

return_values : BoundedVec<Field, RETURN_VALUES_LENGTH>,

### Read Requests
<!-- TODO(maddiaa): leaving as todo until their is further clarification around their implementation in the protocol -->

<!-- args_hash : Field,
return_values : BoundedVec<Field, RETURN_VALUES_LENGTH>,
### New Commitments
New commitments contains an array of all of the commitments created in the current execution context.

read_requests: BoundedVec<Field, MAX_READ_REQUESTS_PER_CALL>,
### New Nullifiers
New nullifiers contains an array of the new nullifiers emitted from the current execution context.

new_commitments: BoundedVec<Field, MAX_NEW_COMMITMENTS_PER_CALL>,
new_nullifiers: BoundedVec<Field, MAX_NEW_NULLIFIERS_PER_CALL>,
nullified_commitments: BoundedVec<Field, MAX_NEW_NULLIFIERS_PER_CALL>,
### Nullified Commitments
Nullified commitments is an optimisation for introduced to help reduce state growth. There are often cases where commitments are created and nullified within the same transaction.
In these cases there is no reason that these commitments should take up space on the node's commitment/nullifier trees. Keeping track of nullified commitments allows us to "cancel out" and prove these cases.

private_call_stack : BoundedVec<Field, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,
public_call_stack : BoundedVec<Field, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL>,
new_l2_to_l1_msgs : BoundedVec<Field, MAX_NEW_L2_TO_L1_MSGS_PER_CALL>, --> -->
### Private Call Stack
The private call stack contains all of the external function calls that have been created within the current context. Any function call objects are hashed and then pushed to the execution stack.
The kernel circuit will orchestrate dispatching the calls and returning the values to the current context.

### Public Call Stack
The public call stack contains all of the external function calls that are created within the current context. Like the private call stack above, the calls are hashed and pushed to this stack. Unlike the private call stack, these calls are not executed client side. Whenever the function is sent to the network, it will have the public call stack attached to it. At this point the sequencer will take over and execute the transactions.

### New L2 to L1 msgs
New L2 to L1 messages contains messages that are delivered to the [l1 outbox](../../concepts/foundation/communication/cross_chain_calls.md) on the execution of each rollup.

## Public Context Inputs
In the current version of the system, the public context is almost a clone of the private execution context. It contains the same call context data, access to the same historic tree roots, however it does NOT have access to contract deployment data, this is due to traditional contract deployments only currently being possible from private transactions.

#include_code public-context-inputs /yarn-project/noir-libs/noir-aztec/src/abi.nr rust
#include_code public-context-inputs /yarn-project/noir-libs/noir-aztec/src/abi.nr rust


### Public Global Variables
The public global variables are provided by the rollup sequencer and consequently contain some more values than the private global variables.

#include_code public-global-variables /yarn-project/noir-libs/noir-aztec/src/abi.nr rust
35 changes: 14 additions & 21 deletions docs/docs/dev_docs/contracts/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,34 +61,28 @@ E.g. `get()`
## Recursive function calls

## L1 --> L2
<!-- TODO: Make a note to refer to the communication docs section -->
The context available within functions includes the ability to send messages to l1.



<!-- TODO: Leave links to the whole flow of sending a message to l2, this section should just show
how the message can be consumed on l2 itself
-->
The context available within functions includes the ability to send messages to l1. For more information on how cross chain communication works in Aztec, see the [documentation on communication.](../../concepts/foundation/communication/cross_chain_calls.md)

#include_code send_to_l2 /yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr rust

### What happens behind the scenes?
When a user sends a message from a portal contract (INCLUDE LINK HERE) to the rollup's inbox it gets processed and added to the `l1 to l2 messages tree` (INCLUDE LINK TO WHERE THIS IS DISCUSSED). The l1 to l2 messages tree contains all messages that have been sent from l1 to the l2. The good thing about this tree is that it does not reveal when it's messages have been spent, as consuming a message from the l1 to l2 messages tree is done by nullifing a message, rather than directly marking it as consumed.
When a user sends a message from a [portal contract](../../concepts/foundation/communication/cross_chain_calls.md#portal) to the rollup's inbox it gets processed and added to the `l1 to l2 messages tree`.
<-- TODO(Maddiaa): INCLUDE LINK TO WHERE the messages tree is discussed elsewhere in the docs. -->
The l1 to l2 messages tree contains all messages that have been sent from l1 to the l2. The good thing about this tree is that it does not reveal when it's messages have been spent, as consuming a message from the l1 to l2 messages tree is done by nullifing a message, rather than marking it as consumed.

When calling the `consume_l1_to_l2_message` function on a contract; a number of actions are performed.
When calling the `consume_l1_to_l2_message` function on a contract; a number of actions are performed by `Aztec.nr`.

<!-- TODO: buff out these bullet points -->
1. As the consume message function is passed a `msgKey` value, we can look up on l1 what the full contents of the message by making an oracle call to get the data.
2. We check that the message recipient is the contract of the current calling context.
3. We check that the message content matches the content reproduced earlier on.
4. We validate that we know the preimage to the message's `secretHash` field. (TODO: SEE MORE ON THIS FOLLOWING A LINK)
5. We compute the nullifier for the message.
1. The `msgKey` value (passed to the consume message function) is used to look up the contents of the l1 message.
2. Check that the message recipient is the contract of the current calling context.
3. Check that the message content matches the content reproduced earlier on.
4. Validate that caller know's the preimage to the message's `secretHash`. See more information [here](../../concepts/foundation/communication/cross_chain_calls.md#messages).
5. We compute the nullifier for the message.
#include_code l1_to_l2_message_compute_nullifier /yarn-project/noir-libs/noir-aztec/src/messaging/l1_to_l2_message.nr rust
6. Finally we push the nullifier to the context. Allowing it to be checked for validity by the kernel and rollup circuits.

#include_code consume_l1_to_l2_message /yarn-project/noir-libs/noir-aztec/src/context.nr rust

The emitted nullifier prevents our message from being consumed again. Users cannot re consume a message as the nullifier would already exist.
As the same nullifier cannot be created twice. We cannot consume the message again.

## L2 --> L1

Expand All @@ -98,7 +92,6 @@ Talk a about the dangers of delegatecall too!


## Deep dive
<!-- TODO: all of the below an be considered as rough notes, and needs to be proof read and proof read and updated! -->
### Function type attributes explained.
Aztec.nr uses an attribute system to annotate a function's type. Annotating a function with the `#[aztec(private)]` attribute tells the framework that this will be a private function that will be executed on a users device. Thus the compiler will create a circuit to define this function.

Expand Down Expand Up @@ -130,9 +123,9 @@ The kernel can then check that all of the values passed to each circuit in a fun

Just as the kernel passes information into the the app circuits, the application must return information about the executed app back to the kernel. This is done through a rigid structure we call the `PrivateCircuitPublicInputs`.

> *Why is it called the `PrivateCircuitPublicInputs`*
> It is commonly asked why the return values of a function in a circuit are labelled as the `Public Inputs`. Common intuition from other programming paradigms suggests that the return values and public inputs should be distinct.
> However; In the eyes of the circuit, anything that is publicly viewable (or checkable) is a public input. Hence in this case, the return values are also public inputs.
> *Why is it called the `PrivateCircuitPublicInputs`*
> It is commonly asked why the return values of a function in a circuit are labelled as the `Public Inputs`. Common intuition from other programming paradigms suggests that the return values and public inputs should be distinct.
> However; In the eyes of the circuit, anything that is publicly viewable (or checkable) is a public input. Hence in this case, the return values are also public inputs.
This structure contains a host of information about the executed program. It will contain any newly created nullifiers, any messages to be sent to l2 and most importantly it will contain the actual return values of the function!

Expand Down
7 changes: 7 additions & 0 deletions yarn-project/noir-libs/noir-aztec/src/abi.nr
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,44 @@ use crate::oracle::debug_log;
use crate::types::vec::BoundedVec;
use crate::types::point::Point;


// docs:start:private-global-variables
struct PrivateGlobalVariables {
chain_id: Field,
version: Field,
}
// docs:end:private-global-variables

impl PrivateGlobalVariables {
fn serialize(self) -> [Field; 2] {
[self.chain_id, self.version]
}
}

// docs:start:public-global-variables
struct PublicGlobalVariables {
chain_id: Field,
version: Field,
block_number: Field,
timestamp: Field,
}
// docs:end:public-global-variables

impl PublicGlobalVariables {
fn serialize(self) -> [Field; 4] {
[self.chain_id, self.version, self.block_number, self.timestamp]
}
}

// docs:start:contract-deployment-data
struct ContractDeploymentData {
deployer_public_key: Point,
constructor_vk_hash : Field,
function_tree_root : Field,
contract_address_salt : Field,
portal_contract_address : Field,
}
// docs:end:contract-deployment-data

impl ContractDeploymentData {
fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {
Expand Down

0 comments on commit 2ab0f65

Please sign in to comment.