Skip to content

Commit

Permalink
feat(docs): PXE docs (#4021)
Browse files Browse the repository at this point in the history
* explanation
* custom oracles how-to
* multiple pxe in sandbox how-to

---------

Co-authored-by: josh crites <critesjosh@gmail.com>
Co-authored-by: Rahul Kothari <rahul.kothari.201@gmail.com>
  • Loading branch information
3 people authored Jan 25, 2024
1 parent c051dac commit a656034
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 12 deletions.
70 changes: 70 additions & 0 deletions docs/docs/concepts/advanced/private_execution_environment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: Private Execution Environment (PXE)
---

The Private Execution Environment (or PXE, pronounced 'pixie') is a client-side library for the execution of private operations. It is a TypeScript library and can be run within Node, such as when you run the sandbox, within the browser, or any other environment in which TypeScript can run. For example, in future it could be run inside wallet software.

The PXE generates proofs of private function execution, and sends these proofs along with public function requests to the sequencer. Private inputs never leave the client-side PXE.

```mermaid
graph TD;
subgraph client[Client]
subgraph pxe [PXE]
acirSim[ACIR Simulator]
db[Database]
keyStore[KeyStore]
end
end
subgraph server[Application Server]
subgraph pxeService [PXE Service]
acctMgmt[Account Management]
contractTxInteract[Contract & Transaction Interactions]
noteMgmt[Note Management]
end
end
pxe -->|interfaces| server
```

## PXE Service

The PXE is a client-side interface of the PXE Service, which is a set of server-side APIs for interacting with the network. It provides functions for account management, contract and transaction interactions, note management, and more. For a more extensive list of operations, refer to the [PXE reference](../../apis/pxe/interfaces/PXE.md).

## Components

### ACIR simulator

The ACIR (Abstract Circuit Intermediate Representation) simulator handles the accurate execution of smart contract functions by simulating transactions. It generates the required data and inputs for these functions. You can find more details about how it works [here](./acir_simulator.md).

### Database

The database stores transactional data and notes within the user's PXE. In the Aztec protocol, the database is implemented as a key-value database backed by LMDB. There is an interface ([GitHub](https://github.com/AztecProtocol/aztec-packages/blob/ca8b5d9dbff8d8062dbf1cb1bd39d93a4a636e86/yarn-project/pxe/src/database/pxe_database.ts)) for this PXE database that can be implemented in other ways, such as an in-memory database that can be used for testing.

The database stores various types of data, including:

- **Notes**: Encrypted representations of assets.
- **Deferred Notes**: Notes that are intended for a user but cannot yet be decoded due to the associated contract not being present in the database. When new contracts are deployed, there may be some time before it is accessible from the PXE database. When the PXE database is updated, deferred note are decoded.
- **Authentication Witnesses**: Data used to approve others from executing transactions on your behalf
- **Capsules**: External data or data injected into the system via [oracles](#oracles).

### Note discovery

There is an open RFP for how note discovery will work on Aztec. You can find more information in the [forum](https://forum.aztec.network/t/request-for-proposals-note-discovery-protocol/2584).

Currently in the Aztec sandbox, users download every note, compute a secret, and generate the symmetric decryption key from that secret. If the note belongs to them, then the user will have derived the same secret and ultimately the required decryption key.

### Keystore

The keystore is a secure storage for private and public keys.

## Oracles

Oracles are pieces of data that are injected into a smart contract function from the client side. You can read more about why and how they work in the [functions section](../../dev_docs/contracts/syntax/functions.md).

## For developers
To learn how to develop on top of the PXE, refer to these guides:
* [Run more than one PXE on your local machine](../../dev_docs/cli/run_more_than_one_pxe_sandbox.md)
* [Use in-built oracles including oracles for arbitrary data](../../dev_docs/contracts/syntax/oracles.md)
35 changes: 35 additions & 0 deletions docs/docs/dev_docs/cli/run_more_than_one_pxe_sandbox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: How to run more than one PXE in the sandbox
---

When you run the sandbox, the Aztec node and PXE have their own http server. This makes it possible to run two PXEs on your local machine, which can be useful for testing that notes are accurately stored and remaining private in their respective PXEs.

We are working on a better solution for this so expect an update soon, but currently you can follow this guide.

## Run the sandbox in one terminal

Rather than use the usual command, run:
```bash
cd ~/.aztec && docker-compose up
```
This removes any other arguments, allowing you to ensure an isolated environment for the sandbox so it doesn't interfere with another PXE.

## Run PXE mode in another terminal

In another terminal, run:

```bash
docker-compose run -e MODE=pxe -e PXE_PORT=8085 -e AZTEC_NODE_URL='http://aztec-aztec-1:8079' -e TEST_ACCOUNTS='false' -p 8085:8085 aztec
```
This does a few things:
* Starts in PXE mode
* Passes the current Aztec node URL
* Does not load new test accounts
* Sets a port to listen on
* Only runs Aztec PXE, not Ethereum

This command uses the default ports, so they might need to be changed depending on yuor configuration.

You can learn more about custom commands in the [sandbox reference](./sandbox-reference.md).


11 changes: 1 addition & 10 deletions docs/docs/dev_docs/contracts/syntax/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ On this page, you’ll learn more about:
- How constructors work and remain private
- The process of calling functions from within the same smart contract and from different contracts, including calling private functions from private functions, public from public, and even private from public
- What oracles and how Aztec smart contracts might use them
- Built-in oracles

## Visibility

Expand Down Expand Up @@ -109,15 +108,7 @@ Oracles introduce **non-determinism** into a circuit, and thus are `unconstraine
`Aztec.nr` has a module dedicated to its oracles. If you are interested, you can view them by following the link below:
#include_code oracles-module /yarn-project/aztec-nr/aztec/src/oracle.nr rust

### A few useful inbuilt oracles

- [`debug_log`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/debug_log.nr) - Provides a couple of debug functions that can be used to log information to the console.
- [`auth_witness`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/authwit/src/auth_witness.nr) - Provides a way to fetch the authentication witness for a given address. This is useful when building account contracts to support approve-like functionality.
- [`get_l1_to_l2_message`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/get_l1_to_l2_message.nr) - Useful for application that receive messages from L1 to be consumed on L2, such as token bridges or other cross-chain applications.
- [`notes`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/notes.nr) - Provides a lot of functions related to notes, such as fetches notes from storage etc, used behind the scenes for value notes and other pre-build note implementations.
- [`logs`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/logs.nr) - Provides the to log encrypted and unencrypted data.

---
You can learn how to use oracles in your smart contracts [here](../syntax/oracles.md).

## Calling functions from other functions

Expand Down
49 changes: 49 additions & 0 deletions docs/docs/dev_docs/contracts/syntax/oracles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Oracles
---

On this page you will learn:

1. [A list of inbuilt oracles](#inbuilt-oracles)
3. [How to use the debug_log oracle](#how-to-use-the-debug-oracle)
3. [How to use the auth_witness oracle](#how-to-use-the-auth_witness-oracle)
4. [How to use the pop_capsule oracle for arbitrary data](#how-to-use-the-popCapsule-oracle)
4. [Reference](#oracles-reference)

## Inbuilt oracles

- [`debug_log`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/debug_log.nr) - Provides a couple of debug functions that can be used to log information to the console. Read more about debugging [here](../../debugging/main.md).
- [`auth_witness`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/authwit/src/auth_witness.nr) - Provides a way to fetch the authentication witness for a given address. This is useful when building account contracts to support approve-like functionality.
- [`get_l1_to_l2_message`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/get_l1_to_l2_message.nr) - Useful for application that receive messages from L1 to be consumed on L2, such as token bridges or other cross-chain applications.
- [`notes`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/notes.nr) - Provides a lot of functions related to notes, such as fetches notes from storage etc, used behind the scenes for value notes and other pre-build note implementations.
- [`logs`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/logs.nr) - Provides the to log encrypted and unencrypted data.

Find a full list [on GitHub](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec-nr/aztec/src/oracle).

:::note
Please note that it is **not** possible to write a custom oracle for your dapp. Oracles are implemented in the PXE, so all users of your dapp would have to use a PXE service with your custom oracle included. If you want to inject some arbitrary data that does not have a dedicated oracle, you can use [popCapsule](#how-to-use-the-pop_capsule-oracle).
:::

## How to use the popCapsule oracle

`popCapsule` is used for passing artbitrary data. We have not yet included this in Aztec.nr, so it is a bit more complex than the other oracles. You can follow this how-to:

### 1. Define the pop_capsule function

In a new file on the same level as your `main.nr`, implement an unconstrained function that calls the pop_capsule oracle:

#include_code pop_capsule yarn-project/noir-contracts/contracts/slow_tree_contract/src/capsule.nr rust

### 2. Import this into your smart contract

If it lies in the same directory as your smart contract, you can import it like this:

#include_code import_pop_capsule yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr rust

### 3. Use it as any other oracle

Now it becomes a regular oracle you can call like this:

#include_code pop_capsule yarn-project/noir-contracts/contracts/slow_tree_contract/src/main.nr rust


9 changes: 7 additions & 2 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ const sidebars = {
},
"concepts/advanced/public_vm",
"concepts/advanced/contract_creation",
"concepts/advanced/private_execution_environment",
"concepts/advanced/sequencer_selection",
"concepts/advanced/acir_simulator",
],
Expand Down Expand Up @@ -294,7 +295,11 @@ const sidebars = {
type: "doc",
id: "dev_docs/cli/main",
},
items: ["dev_docs/cli/cli-commands", "dev_docs/cli/sandbox-reference"],
items: [
"dev_docs/cli/cli-commands",
"dev_docs/cli/sandbox-reference",
"dev_docs/cli/run_more_than_one_pxe_sandbox"
],
},
{
label: "Aztec.nr Contracts",
Expand Down Expand Up @@ -326,6 +331,7 @@ const sidebars = {
},
"dev_docs/contracts/syntax/events",
"dev_docs/contracts/syntax/functions",
"dev_docs/contracts/syntax/oracles",
{
label: "Proving Historical Blockchain Data",
type: "category",
Expand Down Expand Up @@ -430,7 +436,6 @@ const sidebars = {
},
items: ["dev_docs/testing/cheat_codes"],
},

{
label: "Wallets",
type: "category",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// docs:start:pop_capsule
#[oracle(popCapsule)]
fn pop_capsule_oracle<N>() -> [Field; N] {}

// A capsule is a "blob" of data that is passed to the contract through an oracle.
unconstrained pub fn pop_capsule<N>() -> [Field; N] {
pop_capsule_oracle()
}
// docs:end:pop_capsule

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ contract SlowTree {
SlowMap, Leaf, SlowUpdateProof, compute_merkle_root, deserialize_slow_update_proof
};

// docs:start:import_pop_capsule
use crate::capsule::pop_capsule;
// docs:end:import_pop_capsule
use crate::types::{MembershipProof, deserialize_membership_proof};

// docs:start:constants_and_storage
Expand Down Expand Up @@ -84,7 +86,9 @@ contract SlowTree {
// docs:start:read_at_private
#[aztec(private)]
fn read_at(index: Field) -> Field {
// docs:start:pop_capsule
let fields = pop_capsule();
// docs:end:pop_capsule
let p: MembershipProof<TREE_HEIGHT, MEMBERSHIP_SIZE> = deserialize_membership_proof(fields);
assert(index == p.index, "Index does not match expected");

Expand Down

0 comments on commit a656034

Please sign in to comment.