Skip to content

Commit

Permalink
feat(docs): Historical trees docs (AztecProtocol#3895)
Browse files Browse the repository at this point in the history
Please provide a paragraph or two giving a summary of the change,
including relevant motivation and context.

# Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if
the PR is ready to merge.
- [x] If the pull request requires a cryptography review (e.g.
cryptographic algorithm implementations) I have added the 'crypto' tag.
- [x] I have reviewed my diff in github, line by line and removed
unexpected formatting changes, testing logs, or commented-out code.
- [x] Every change is related to the PR description.
- [x] I have
[linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)
this pull request to relevant issues (if any exist).

---------

Co-authored-by: josh crites <[email protected]>
Co-authored-by: Jan Beneš <[email protected]>
Co-authored-by: Rahul Kothari <[email protected]>
  • Loading branch information
4 people authored Jan 24, 2024
1 parent 84c9fdb commit 8c3efba
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 6 deletions.
34 changes: 31 additions & 3 deletions docs/docs/concepts/advanced/data_structures/trees.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Data includes:
- Nullifiers to invalidate old private state ([Nullifier tree](#nullifier-tree))
- Public state ([Public State tree](#public-state-tree))
- Contracts ([Contract tree](#contract-tree))
- Previous block headers ([Archive tree](#archive-tree))
- Archive tree for Historical access ([Archive tree](#archive-tree))
- Global Variables

```mermaid
Expand Down Expand Up @@ -181,9 +181,37 @@ Aztec supports the ability to keep the logic of private functions of a smart con

## Archive Tree

A block includes the root to the Archive Tree (sometimes called the blocks tree).
The archive tree is an append-only Merkle tree that stores hashes of headers of all previous blocks in the chain as its leaves.

The leaves of the tree are hashes of previous block headers. This tree can be used to verify data of any of the trees above at some previous point in time by doing a membership check of the corresponding tree root in the block header and the block header hash in the blocks tree.
As private execution relies on proofs generated by the user, the current block header is not known. We can instead base the proofs on historical state. By including all prior block headers (which include commitments to the state), the historical access tree allows us to easily prove that the historical state that a transaction is using for a proof is valid.

```mermaid
graph TD;
PartialStateReference[<b>Partial State</b><br>snapshot of note hash tree, nullifier tree, contract tree, public data tree]
StateReference[<b>State Reference</b><br>snapshot of L1<>L2 message tree]
GlobalVariables[<b>Global Variables</b><br>block number, timestamp, version, chain_id]
Header[<b>Block Header</b><br>last snapshot of tree, hash of body]
Logs[<b>Transaction Logs</b><br>encrypted & non-encrypted logs]
PublicDataWrite[<b>Public Data Writes</b><br>]
ContractData[<b>Contract Data</b><br>leaf, address]
TxEffect[<b>Transaction Effects</b><br>note hashes, nullifiers, contracts, public writes]
Body[<b> Body</b><br>L1<>L2 messages, transaction effects]
ArchiveTree[<b>Archive Tree</b><br>used to validate user-generated proofs and access historical data]
StateReference --- PartialStateReference
Header --- Body
Header --- StateReference
Header --- GlobalVariables
TxEffect --- ContractData
TxEffect --- PublicDataWrite
TxEffect --- Logs
Body --- TxEffect
HistoricalAccessTree --- Header
```

It can also be used to find information about notes, public state, and contracts that were included in a certain block using [inclusion and non-inclusion proofs](../../../dev_docs/contracts/syntax/historical_access/how_to_prove_history.md).

## Trees of valid Kernel/Rollup circuit Verification Keys

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
title: History Reference
---

<!-- Note: This will soon be moved into an Aztec.nr reference category under Aztec.nr smart contracts -->

## Note inclusion

Note inclusion proves that a note existed (its hash was included in a note hash tree) at a specific block number.

## prove_note_inclusion

`prove_note_inclusion` takes 4 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| note_interface | NoteInterface<Note, N> | Interface for the note with necessary functionality|
| note_with_header| Note | The note you are proving inclusion for |
| block_number | u32 | Block number for proving note's existence |
| context | PrivateContext | Private context |

## prove_note_commitment_inclusion

A **commitment**, also referred to as a **note hash** is a public acknowledgment of the existence of a note without revealing the content of the note. You can learn more about how to compress a note to a note hash [here](../../../../concepts/advanced/data_structures/trees.md#example-note).

`prove_note_commitment_inclusion` takes 3 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| commitment | Field | Note commitment we are checking inclusion of |
| block_number | u32 | Block number for proving note's existence |
| context| PrivateContext | Private Context |

## Note validity

This proves that a note exists and has not been nullified at a specified block.

### prove_note_validity

`prove_note_validity` takes 4 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| note_interface | NoteInterface<Note, N> | Interface for the note with necessary functionality|
| note_with_header| Note | The note you are proving inclusion for |
| block_number | u32 | Block number for proving note's existence |
| context | PrivateContext | Private context |

## Nullifier inclusion

This proves that a nullifier was included in a certain block (can be used to prove that a note had been nullified).

### prove_nullifier_inclusion

`prove_nullifier_inclusion` takes 3 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| nullifier | Field | The nullifier you are proving inclusion for |
| block_number | u32 | Block number for proving note's existence |
| context | PrivateContext | Private context |

## Nullifier non inclusion

This proves that a nullifier was not included in a certain block (can be used to prove that a note had not yet been nullified in a given block).

### prove_nullifier_non_inclusion

`prove_nullifier_non_inclusion` takes 3 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| nullifier | Field | The nullifier you are proving inclusion for |
| block_number | u32 | Block number for proving note's existence |
| context | PrivateContext | Private context |

### note_not_nullified

Instead of passing the nullifier, you can check that a note has not been nullified by passing the note.

## Public value inclusion

This proves that a public value exists at a certain block.

### prove_public_value_inclusion

`prove_public_value_inclusion` takes 4 parameters:

| Name | Type | Description |
|-----------------|------------------------|-----------------------------------------------------|
| value | Field | The public value you are proving inclusion for |
| storage_slot | Field | Storage slot the value exists in |
| block_number | u32 | Block number for proving value's existence |
| context | PrivateContext | Private context |

## Contract inclusion

This proves that a contract exists in, ie had been deployed before or in, a certain block.

### prove_contract_inclusion

`prove_contract_inclusion` takes 7 parameters:

| Name | Type | Description |
|---------------------------|-----------------|-------------------------------------------------------|
| deployer_public_key | GrumpkinPoint | Public key of the contract deployer |
| contract_address_salt | Field | Unique identifier for the contract's address |
| function_tree_root | Field | Root of the contract's function tree |
| constructor_hash | Field | Hash of the contract's constructor |
| portal_contract_address | EthAddress | Ethereum address of the associated portal contract |
| block_number | u32 | Block number for proof verification |
| context | PrivateContext | Private context |

If there is no associated portal contract, you can use a zero Ethereum address:

```ts
new EthAddress(Buffer.alloc(EthAddress.SIZE_IN_BYTES));
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: How to prove existence of historical notes and nullifiers
---

The Aztec Protocol uses an append-only Merkle tree to store hashes of the headers of all previous blocks in the chain as its leaves. This is known as an archive tree. You can learn more about how it works in the [concepts section](../../../../concepts/advanced/data_structures/trees.md#archive-tree).

# History library

The history library allows you to prove any of the following at a given block height before the current height:
* [Note inclusion](./history_lib_reference.md#note-inclusion)
* [Nullifier inclusion](./history_lib_reference.md#nullifier-inclusion)
* [Note validity](./history_lib_reference.md#note-validity)
* [Existence of public value](./history_lib_reference.md#public-value-inclusion)
* [Contract inclusion](./history_lib_reference.md#contract-inclusion)

Using this library, you can check that specific notes or nullifiers were part of Aztec network state at specific blocks. This can be useful for things such as:

* Verifying a minimum timestamp from a private context
* Checking eligibility based on historical events (e.g. for an airdrop by proving that you owned a note)
* Verifying historic ownership / relinquishing of assets
* Proving existence of a value in public data tree at a given contract slot
* Proving that a contract was deployed in a given block with some parameters

**In this guide you will learn how to**
* Prove a note was included in a specified block
* Create a nullifier and prove it was not included in a specified block

For a more extensive reference, go to [the reference page](./history_lib_reference.md).

## 1. Import the `history` library from `aztec`

```rust
aztec::{
#include_code imports yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr raw
}
```

This imports all functions from the `history` library. You should only import the functions you will use in your contract.

## 2. Create a note to prove inclusion of

In general you will likely have the note you want to prove inclusion of. But if you are just experimenting you can create a note with a function like below:

#include_code create_note yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

## 3. Get the note from the PXE

Retrieve the note from the user's PXE.

#include_code get_note_from_pxe yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

In this example, the user's notes are stored in a map called `private_values`. We retrieve this map, then select 1 note from it with the value of `1`.

## 4. Prove that a note was included in a specified block

To prove that a note existed in a specified block, call `prove_note_inclusion` as shown in this example:

#include_code prove_note_inclusion yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

This function takes in 4 arguments:

1. The note interface (`ValueNoteMethods`)
2. The note (`maybe_note.unwrap_unchecked()`). Here, `unwrap_unchecked()` returns the inner value without asserting `self.is_some()`
3. The block number
4. Private context

Note: for this to work, you will need to import `ValueNoteMethods` at the beginning of the contract:

#include_code value_note_imports yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

This will only prove the note existed, not whether or not the note has been nullified. You can prove that a note existed and had not been nullified in a specified block by using `prove_note_validity` which takes the same arguments:

#include_code prove_note_validity yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

## 5. Create a nullifier to prove inclusion of

You can easily nullify a note like so:

#include_code nullify_note yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

This function gets a note from the PXE like we did in [step 3](#3-get-the-note-from-the-pxe) and nullifies it with `remove()`.

You can then compute this nullifier with `note.compute_nullifier(&mut context)`.

## 6. Prove that a nullifier was included in a specified block

Call `prove_nullifier_inclusion` like so:

#include_code prove_nullifier_inclusion yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

This takes three arguments:
1. The nullifier
2. Block number
3. Private context

You can also prove that a nullifier was not included in a specified block by using `prove_nullifier_non_inclusion` which takes the same arguments:

#include_code prove_nullifier_non_inclusion yarn-project/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr rust

## Prove contract inclusion, public value inclusion, and note commitment inclusion

To see what else you can do with the `history` library, check out the [reference](./history_lib_reference.md).
9 changes: 9 additions & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,16 @@ const sidebars = {
},
"dev_docs/contracts/syntax/events",
"dev_docs/contracts/syntax/functions",
{
label: "Proving Historical Blockchain Data",
type: "category",
items: [
"dev_docs/contracts/syntax/historical_access/how_to_prove_history",
"dev_docs/contracts/syntax/historical_access/history_lib_reference",
],
},
"dev_docs/contracts/syntax/slow_updates_tree",

"dev_docs/contracts/syntax/context",
"dev_docs/contracts/syntax/globals",
],
Expand Down
Loading

0 comments on commit 8c3efba

Please sign in to comment.