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

docs: remove mentions of slow updates #5884

Merged
merged 6 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 0 additions & 123 deletions docs/docs/developers/contracts/references/slow_updates_tree.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ Note - you could also create a note and send it to the user. The problem is ther

### Reading public storage in private

You can't read public storage in private domain. But nevertheless reading public storage is desirable. There are two ways:
You can't read public storage in private domain. But nevertheless reading public storage is desirable. This is the naive way:

1. For public storage that changes infrequently, use the slow updates tree! Learn more about it [here](../../../../learn/concepts/communication/public_private_calls/slow_updates_tree.md).
<!-- TODO https://github.com/AztecProtocol/aztec-packages/issues/5508: mention SharedMutable as an alternative
-->

2. You pass the data as a parameter to your private method and later assert in public that the data is correct. E.g.:
- You pass the data as a parameter to your private method and later assert in public that the data is correct. E.g.:

```rust
struct Storage {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: How to use the Arhive Tree
title: How to use the Archive Tree
---

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](../../../../../learn/concepts/storage/trees/main.md#archive-tree).
Expand Down

This file was deleted.

This file was deleted.

6 changes: 6 additions & 0 deletions docs/docs/learn/concepts/accounts/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ Storing the signing public key in a private note makes it accessible from the en

Similar to using a private note, but using an immutable private note removes the need to nullify the note on every read. This generates less nullifiers and commitments per transaction, and does not enforce an order across transactions. However, it does not allow the user to rotate their key should they lose it.

<!--TODO https://github.com/AztecProtocol/aztec-packages/issues/5508
mention Shared Mutable, add links, explain limitations (delays)

this is the old text:

### Using the slow updates tree

A compromise between the two solutions above is to use the [slow updates tree](../communication/public_private_calls/slow_updates_tree.md). This would not generate additional nullifiers and commitments for each transaction while allowing the user to rotate their key. However, this causes every transaction to now have a time-to-live determined by the frequency of the slow updates tree.
-->

### Reusing the privacy master key

Expand Down
6 changes: 5 additions & 1 deletion docs/docs/learn/concepts/accounts/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ These two patterns combined allow an account contract to answer whether an actio

Aztec requires users to define [encryption and nullifying keys](./keys.md) that are needed for receiving and spending private notes. Unlike transaction signing, encryption and nullifying is enshrined at the protocol. This means that there is a single scheme used for encryption and nullifying. These keys are derived from a master public key. This master public key, in turn, is used when deterministically deriving the account's address.

A side effect of committing to a master public key as part of the address is that _this key cannot be rotated_. While an account contract implementation could include methods for rotating the signing key, this is unfortunately not possible for encryption and nullifying keys (note that rotating nullifying keys also creates other challenges such as preventing double spends). We are exploring usage of the [slow updates tree](../communication/public_private_calls/slow_updates_tree.md) to enable rotating these keys.
A side effect of committing to a master public key as part of the address is that _this key cannot be rotated_. While an account contract implementation could include methods for rotating the signing key, this is unfortunately not possible for encryption and nullifying keys (note that rotating nullifying keys also creates other challenges such as preventing double spends).

<!-- TODO https://github.com/AztecProtocol/aztec-packages/issues/5508: mention shared mutable
We are exploring usage of sharedmutable[link] to enable rotating these keys.
-->

NOTE: While we entertained the idea of abstracting note encryption, where account contracts would define an `encrypt` method that would use a user-defined scheme, there are two main reasons we decided against this. First is that this entailed that, in order to receive funds, a user had to first deploy their account contract, which is a major UX issue. Second, users could define malicious `encrypt` methods that failed in certain circumstances, breaking application flows that required them to receive a private note. While this issue already exists in Ethereum when transferring ETH (see the [king of the hill](https://coinsbench.com/27-king-ethernaut-da5021cd4aa6)), its impact is made worse in Aztec since any execution failure in a private function makes the entire transaction unprovable (ie it is not possible to catch errors in calls to other private functions), and furthermore because encryption is required for any private state (not just for transferring ETH). Nevertheless, both of these problems are solvable. Initialization can be worked around by embedding a commitment to the bytecode in the address and removing the need for actually deploying contracts before interacting with them, and the king of the hill issue can be mitigated by introducing a full private VM that allows catching reverts. As such, we may be able to abstract encryption in the future as well.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Private - Public execution
title: Private <> Public Communication
---

import Image from "@theme/IdealImage";
Expand Down Expand Up @@ -78,32 +78,10 @@ Theoretically the builder has all the state trees after the public function has

From the above, we should have a decent idea about what private and public functions can do inside the L2, and how they might interact.

<!-- TODO https://github.com/AztecProtocol/aztec-packages/issues/5508: mention SharedMutable
## A note on L2 access control

Many applications rely on some form of access control to function well. USDC have a blacklist, where only parties not on the list should be able to transfer. And other systems such as Aave have limits such that only the pool contract is able to mint debt tokens and transfers held funds.

Access control like this cannot easily be enforced in the private domain, as reading is also nullifying(to ensure data is up to date). However, as it is possible to read historical public state, one can combine private and public functions to get the desired effect.

Say the public state holds a `mapping(address user => bool blacklisted)` and a value with the block number of the last update `last_updated`. The private functions can then use this public blacklist IF it also performs a public function call that reverts if the block number of the historical state is older than the `last_updated`. This means that updating the blacklist would make pending transactions fail, but allow a public blacklist to be used. Similar would work for the Aave example, where it is just a public value with the allowed caller contracts. Example of how this would be written is seen below. Note that because the `onlyFresh` is done in public, the user might not know when he is generating his proof whether it will be valid or not.

```solidity
function transfer(
secret address to,
secret uint256 amount,
secret HistoricalState state
) secret returns(bool) {
if (blacklisted[msg.sender] || blacklisted[to]) revert("Blacklisted");
onlyFresh(state.blockNumber);
// logic
}

function onlyFresh(pub uint256 blockNumber) public {
if (blockNumber < last_updated) revert("Stale state");
}
```

:::info
This is not a perfect solution, as any functions using access control might end up doing a lot of public calls it could put a significant burden on sequencers and greatly increase the cost of the transaction for the user. We are investigating ways to improve.
:::

Using a dual-tree structure with a pending and a current tree, it is possible to update public data from a private function. The update is fulfilled when the pending tree becomes the current after the end of a specified epoch. It is also possible to read historical public data directly from a private function. This works perfectly for public data that is not updated often, such as a blacklist. This structure is called a slow updates tree, and you can read about how it works [in the next section](./slow_updates_tree.md).
-->
Loading
Loading