Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Connor <[email protected]>
  • Loading branch information
LHerskind and iAmMichaelConnor committed Nov 3, 2023
1 parent 605986d commit 9664f0c
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
12 changes: 6 additions & 6 deletions docs/docs/concepts/foundation/state_model/storage_slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ description: How are storage slots derived for public and private state

In Aztec private data and public data are stored in two trees, a public data tree and a private data tree.

These trees have in common that they store state for *all* accounts on the Aztec network directly as leafs. This is different from Ethereum, where a state trie contains smaller tries that hold the individual accounts storage.
These trees have in common that they store state for *all* accounts on the Aztec network directly as leaves. This is different from Ethereum, where a state trie contains smaller tries that hold the individual accounts' storage.

It also means that we need to be careful about how we allocate storage to ensure that they don't collide! We say that storage should be *siloed* to its contract. The exact way of siloing differs a little for public and private storage. Which we will see in the following sections.

## Public State Slots

As mentioned in [State Model](./main.md), Aztec public state behaves similarly to public state on Ethereum from the point of view of the developer. Behind the scenes however, the storage is managed differently. As mentioned, public state have just one large sparse tree in Aztec - so we silo slots of public data by hashing it together with its contract address.
As mentioned in [State Model](./main.md), Aztec public state behaves similarly to public state on Ethereum from the point of view of the developer. Behind the scenes however, the storage is managed differently. As mentioned, public state has just one large sparse tree in Aztec - so we silo slots of public data by hashing it together with its contract address.

The mental model is that we have a key-value store, where the siloed slot is the key, and the value is the data stored in that slot. You can think of the `real_storage_slot` identifying its position in the tree, and the `logical_storage_slot` identifying the position in the contract storage.

Expand All @@ -26,9 +26,9 @@ For structs and arrays, we are logically using a similar storage slot computatio

## Private State Slots - Slots aren't real

Private storage is a different beast. As you might remember from [State Model](./main.md), private state is stored in a append-only tree where each leaf is a note. Being append-only, mean that leafs are never updated or deleted, instead a nullifier is emitted to signify that some note is no longer valid. A major reason we used this tree, is that lookups at a specific storage slot don't really make sense in the context of private state. If you could look up a specific address balance just by looking at the storage slot, even if encrypted you would be able to see it changing! That is not good privacy.
Private storage is a different beast. As you might remember from [State Model](./main.md), private state is stored in a append-only tree where each leaf is a note. Being append-only, means that leaves are never updated or deleted; instead a nullifier is emitted to signify that some note is no longer valid. A major reason we used this tree, is that lookups at a specific storage slot would leak information in the context of private state. If you could look up a specific address balance just by looking at the storage slot, even if encrypted you would be able to see it changing! That is not good privacy.

Following this. The storage slot as we know it doesn't really exists. The leafs of the private data tree are just commitments to content (think of it as a hash of its content).
Following this. The storage slot as we know it doesn't really exists. The leaves of the private data tree are just commitments to content (think of it as a hash of its content).

Nevertheless, the concept of a storage slot is very useful when writing applications, since it allows us to reason about distinct and disjoint pieces of data. For example we can say that the balance of an account is stored in a specific slot and that the balance of another account is stored in another slot with the total supply stored in some third slot. By making sure that these slots are disjoint, we can be sure that the balances are not mixed up and that someone cannot use the total supply as their balance.

Expand All @@ -45,12 +45,12 @@ commitment = H(logical_storage_slot, note_hash);

This siloing (there will be more) is done in the application circuit, since it is not necessary for security of the network (but only the application).
:::info
The private variable wrappers set and singletons in Aztec.nr include this to make it easier for developers to use.
The private variable wrappers `Set` and `Singleton` in Aztec.nr include the `logical_storage_slot` in the commitments they compute, to make it easier for developers to write contracts without having to think about how to correctly handle storage slots.
:::

When reading the values for these notes, the application circuit can then constrain it to only read notes with a specific logical storage slot.

To ensure that one contract's cannot insert storage that other contracts believe is theirs we do a second siloing by hashing the `commitment` with the contract address.
To ensure that one contract cannot insert storage that other contracts would believe is theirs, we do a second siloing by hashing the `commitment` with the contract address.

```rust
siloed_commitment = H(contract_address, commitment);
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/dev_docs/contracts/syntax/storage/storage_slots.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ sequenceDiagram
Context->>Kernel: siloed_note_hash = H(contract_address, inner_note_hash)
```

To clarify what the commitment inserted from above (the `siloed_note_hash`) really is we "unroll" the values to their simplest components. This gives us a better idea around what is actually inserted into the tree.
Notice the `siloed_note_hash` at the very end. It's a commitment that will be inserted into the private data tree. To clarify what this really is, we "unroll" the values to their simplest components. This gives us a better idea around what is actually inserted into the tree.

```rust
siloed_note_hash = H(contract_address, inner_note_hash)
Expand All @@ -56,9 +56,9 @@ Where the `map_slot` is the slot specified in `Storage::init`, recall:
And `to` is the actor who receives the note, `amount` of the note and `randomness` is the randomness used to make the note hiding. Without the `randomness` the note could could just as well be plaintext (computational cost of a preimage attack would be trivial in such a case).

:::info
Beware that this hash computation is what the aztec.nr libraries is doing, and not strict requirements by the network (only the kernel computation is).
Beware that this hash computation is what the aztec.nr library is doing, and not strictly required by the network (only the kernel computation is).
:::

With this note structure, the contract can require that only notes sitting at specific storage slots can be used by specific operations, e.g., if transferring funds from `from` to `to`, the notes to destroy should be linked to `H(map_slot, from)` and the new notes (except the change-note) should be linked to `H(map_slot, to)`.

That way, we can have logical storage slots, without them really exiting. This means that knowing the storage slot for a note is not enough to actually figure out what is in there (which it is in public).
That way, we can have logical storage slots, without them really existing. This means that knowing the storage slot for a note is not enough to actually figure out what is in there (whereas it would be for looking up public state).

0 comments on commit 9664f0c

Please sign in to comment.