Skip to content

Commit

Permalink
feat!: rm outgoing logs (#10486)
Browse files Browse the repository at this point in the history
Remove outgoing logs from aztec.nr.
Remove outgoing note discovery flows from typescript-land.

Outgoing viewing keys are retained, but now aren't used anywhere.

2 weird problems encountered on this journey:
- #10546 <-- an
inexplicable blow-up in the debug_symbols field of two functions in the
StateFulTestContract, despite features only being removed from that
contract.
- #10558 <-- a
debug log keeping the NFT contract from breaking

---------

Co-authored-by: Jan Beneš <[email protected]>
  • Loading branch information
iAmMichaelConnor and benesjan authored Dec 10, 2024
1 parent d194cdf commit c28beec
Show file tree
Hide file tree
Showing 70 changed files with 417 additions and 1,523 deletions.
6 changes: 2 additions & 4 deletions boxes/boxes/react/src/contracts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ contract BoxReact {
let numbers = storage.numbers;
let mut new_number = ValueNote::new(number, owner);

let owner_ovpk_m = get_public_keys(owner).ovpk_m;
numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender()));
numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner, context.msg_sender()));
}

#[private]
Expand All @@ -37,8 +36,7 @@ contract BoxReact {
let numbers = storage.numbers;
let mut new_number = ValueNote::new(number, owner);

let owner_ovpk_m = get_public_keys(owner).ovpk_m;
numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender()));
numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner, context.msg_sender()));
}

unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {
Expand Down
6 changes: 2 additions & 4 deletions boxes/boxes/vanilla/src/contracts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ contract Vanilla {
let numbers = storage.numbers;
let mut new_number = ValueNote::new(number, owner);

let owner_ovpk_m = get_public_keys(owner).ovpk_m;
numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender()));
numbers.at(owner).initialize(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner, context.msg_sender()));
}

#[private]
Expand All @@ -37,8 +36,7 @@ contract Vanilla {
let numbers = storage.numbers;
let mut new_number = ValueNote::new(number, owner);

let owner_ovpk_m = get_public_keys(owner).ovpk_m;
numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner_ovpk_m, owner, context.msg_sender()));
numbers.at(owner).replace(&mut new_number).emit(encode_and_encrypt_note(&mut context, owner, context.msg_sender()));
}

unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {
Expand Down
25 changes: 25 additions & 0 deletions docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@ The `Header` struct has been renamed to `BlockHeader`, and the `get_header()` fa
+ let header = context.get_block_header_at(block_number);
```

### Outgoing Events removed

Previously, every event which was emitted included:
- Incoming Header (to convey the app contract address to the recipient)
- Incoming Ciphertext (to convey the note contents to the recipient)
- Outgoing Header (served as a backup, to convey the app contract address to the "outgoing viewer" - most likely the sender)
- Outgoing Ciphertext (served as a backup, encrypting the summetric key of the incoming ciphertext to the "outgoing viewer" - most likely the sender)

The latter two have been removed from the `.emit()` functions, so now only an Incoming Header and Incoming Ciphertext will be emitted.

The interface for emitting a note has therefore changed, slightly. No more ovpk's need to be derived and passed into `.emit()` functions.

```diff
- nfts.at(to).insert(&mut new_note).emit(encode_and_encrypt_note(&mut context, from_ovpk_m, to, from));
+ nfts.at(to).insert(&mut new_note).emit(encode_and_encrypt_note(&mut context, to, from));
```

The `getOutgoingNotes` function is removed from the PXE interface.

Some aztec.nr library methods' arguments are simplified to remove an `outgoing_viewer` parameter. E.g. `ValueNote::increment`, `ValueNote::decrement`, `ValueNote::decrement_by_at_most`, `EasyPrivateUint::add`, `EasyPrivateUint::sub`.

Further changes are planned, so that:
- Outgoing ciphertexts (or any kind of abstract ciphertext) can be emitted by a contract, and on the other side discovered and then processed by the contract.
- Headers will be removed, due to the new tagging scheme.

## 0.66

### DEBUG env var is removed
Expand Down
8 changes: 8 additions & 0 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use dep::protocol_types::debug_log::debug_log_format;

use crate::{
context::{inputs::PrivateContextInputs, packed_returns::PackedReturns},
hash::{ArgsHasher, hash_args_array},
Expand Down Expand Up @@ -137,6 +139,12 @@ impl PrivateContext {

pub fn push_note_hash(&mut self, note_hash: Field) {
self.note_hashes.push(NoteHash { value: note_hash, counter: self.next_counter() });

// WARNING(https://github.com/AztecProtocol/aztec-packages/issues/10558): if you delete this debug_log_format line, some tests fail.
debug_log_format(
"Context.note_hashes, after pushing new note hash: {0}",
self.note_hashes.storage().map(|nh: NoteHash| nh.value),
);
}

pub fn push_nullifier(&mut self, nullifier: Field) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
use crate::{
context::PrivateContext, encrypted_logs::payload::compute_private_log_payload,
event::event_interface::EventInterface, keys::getters::get_ovsk_app,
};
use dep::protocol_types::{
address::AztecAddress, constants::PRIVATE_LOG_SIZE_IN_FIELDS, public_keys::OvpkM,
event::event_interface::EventInterface,
};
use dep::protocol_types::{address::AztecAddress, constants::PRIVATE_LOG_SIZE_IN_FIELDS};

/// Computes private event log payload and a log hash
fn compute_payload<Event, let N: u32>(
context: PrivateContext,
event: Event,
ovsk_app: Field,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> [Field; PRIVATE_LOG_SIZE_IN_FIELDS]
Expand All @@ -21,60 +17,48 @@ where
let contract_address: AztecAddress = context.this_address();
let plaintext = event.to_be_bytes();

compute_private_log_payload(
contract_address,
ovsk_app,
ovpk,
recipient,
sender,
plaintext,
)
compute_private_log_payload(contract_address, recipient, sender, plaintext)
}

unconstrained fn compute_payload_unconstrained<Event, let N: u32>(
context: PrivateContext,
event: Event,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> [Field; PRIVATE_LOG_SIZE_IN_FIELDS]
where
Event: EventInterface<N>,
{
let ovsk_app = get_ovsk_app(ovpk.hash());
compute_payload(context, event, ovsk_app, ovpk, recipient, sender)
compute_payload(context, event, recipient, sender)
}

pub fn encode_and_encrypt_event<Event, let N: u32>(
context: &mut PrivateContext,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> fn[(&mut PrivateContext, OvpkM, AztecAddress, AztecAddress)](Event) -> ()
) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](Event) -> ()
where
Event: EventInterface<N>,
{
|e: Event| {
let ovsk_app: Field = context.request_ovsk_app(ovpk.hash());
let encrypted_log = compute_payload(*context, e, ovsk_app, ovpk, recipient, sender);
let encrypted_log = compute_payload(*context, e, recipient, sender);
context.emit_private_log(encrypted_log);
}
}

pub fn encode_and_encrypt_event_unconstrained<Event, let N: u32>(
context: &mut PrivateContext,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> fn[(&mut PrivateContext, OvpkM, AztecAddress, AztecAddress)](Event) -> ()
) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](Event) -> ()
where
Event: EventInterface<N>,
{
|e: Event| {
// Unconstrained logs have both their content and encryption unconstrained - it could occur that the
// recipient is unable to decrypt the payload.
let encrypted_log =
unsafe { compute_payload_unconstrained(*context, e, ovpk, recipient, sender) };
unsafe { compute_payload_unconstrained(*context, e, recipient, sender) };
context.emit_private_log(encrypted_log);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
use crate::{
context::PrivateContext,
encrypted_logs::payload::compute_private_log_payload,
keys::getters::get_ovsk_app,
note::{note_emission::NoteEmission, note_interface::NoteInterface},
};
use dep::protocol_types::{
abis::note_hash::NoteHash, address::AztecAddress, constants::PRIVATE_LOG_SIZE_IN_FIELDS,
public_keys::OvpkM,
};

/// Computes private note log payload
fn compute_payload<Note, let N: u32>(
context: PrivateContext,
note: Note,
ovsk_app: Field,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> ([Field; PRIVATE_LOG_SIZE_IN_FIELDS], u32)
Expand All @@ -34,61 +30,48 @@ where

let plaintext = note.to_be_bytes(storage_slot);

let payload = compute_private_log_payload(
contract_address,
ovsk_app,
ovpk,
recipient,
sender,
plaintext,
);
let payload = compute_private_log_payload(contract_address, recipient, sender, plaintext);

(payload, note_hash_counter)
}

unconstrained fn compute_payload_unconstrained<Note, let N: u32>(
context: PrivateContext,
note: Note,
ovpk: OvpkM,
recipient: AztecAddress,
sender: AztecAddress,
) -> ([Field; PRIVATE_LOG_SIZE_IN_FIELDS], u32)
where
Note: NoteInterface<N>,
{
let ovsk_app = get_ovsk_app(ovpk.hash());
compute_payload(context, note, ovsk_app, ovpk, recipient, sender)
compute_payload(context, note, recipient, sender)
}

// This function seems to be affected by the following Noir bug:
// https://github.com/noir-lang/noir/issues/5771
// If you get weird behavior it might be because of it.
pub fn encode_and_encrypt_note<Note, let N: u32>(
context: &mut PrivateContext,
ovpk: OvpkM,
recipient: AztecAddress,
// TODO: We need this because to compute a tagging secret, we require a sender. Should we have the tagging secret oracle take a ovpk_m as input instead of the address?
// We need this because to compute a tagging secret, we require a sender:
sender: AztecAddress,
) -> fn[(&mut PrivateContext, OvpkM, AztecAddress, AztecAddress)](NoteEmission<Note>) -> ()
) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](NoteEmission<Note>) -> ()
where
Note: NoteInterface<N>,
{
|e: NoteEmission<Note>| {
let ovsk_app: Field = context.request_ovsk_app(ovpk.hash());

let (encrypted_log, note_hash_counter) =
compute_payload(*context, e.note, ovsk_app, ovpk, recipient, sender);
compute_payload(*context, e.note, recipient, sender);
context.emit_raw_note_log(encrypted_log, note_hash_counter);
}
}

pub fn encode_and_encrypt_note_unconstrained<Note, let N: u32>(
context: &mut PrivateContext,
ovpk: OvpkM,
recipient: AztecAddress,
// TODO: We need this because to compute a tagging secret, we require a sender. Should we have the tagging secret oracle take a ovpk_m as input instead of the address?
// We need this because to compute a tagging secret, we require a sender:
sender: AztecAddress,
) -> fn[(&mut PrivateContext, OvpkM, AztecAddress, AztecAddress)](NoteEmission<Note>) -> ()
) -> fn[(&mut PrivateContext, AztecAddress, AztecAddress)](NoteEmission<Note>) -> ()
where
Note: NoteInterface<N>,
{
Expand All @@ -104,7 +87,7 @@ where
// return the log from this function to the app, otherwise it could try to do stuff with it and then that might
// be wrong.
let (encrypted_log, note_hash_counter) =
unsafe { compute_payload_unconstrained(*context, e.note, ovpk, recipient, sender) };
unsafe { compute_payload_unconstrained(*context, e.note, recipient, sender) };
context.emit_raw_note_log(encrypted_log, note_hash_counter);
}
}
Loading

0 comments on commit c28beec

Please sign in to comment.