diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index e587bb7db6c..5a88b6abba8 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -163,10 +163,14 @@ export class Oracle { return toACVMField(0); } - emitUnencryptedLog(message: ACVMField[]): ACVMField { + emitUnencryptedLog([contractAddress]: ACVMField[], [eventSelector]: ACVMField[], message: ACVMField[]): ACVMField { // https://github.com/AztecProtocol/aztec-packages/issues/885 const log = Buffer.concat(message.map(charBuffer => convertACVMFieldToBuffer(charBuffer).subarray(-1))); - this.typedOracle.emitUnencryptedLog(log); + this.typedOracle.emitUnencryptedLog( + AztecAddress.fromString(contractAddress), + FunctionSelector.fromField(fromACVMField(eventSelector)), // TODO: should we rename FunctionSelector to Selector? + log, + ); return toACVMField(0); } diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index a972474b420..bf1388438fb 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -129,7 +129,7 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - emitUnencryptedLog(_log: Buffer): void { + emitUnencryptedLog(_contractAddress: AztecAddress, _eventSelector: FunctionSelector, _log: Buffer): void { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index b11cc97b4e6..1e452186730 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -333,9 +333,12 @@ export class ClientExecutionContext extends ViewDataOracle { /** * Emit an unencrypted log. + * @param contractAddress - The address of the contract emitting the log. + * @param eventSelector - The event selector of the log. * @param log - The unencrypted log to be emitted. */ - public emitUnencryptedLog(log: Buffer) { + public emitUnencryptedLog(contractAddress: AztecAddress, eventSelector: FunctionSelector, log: Buffer) { + // TODO: #2586, #2587 this.unencryptedLogs.push(log); this.log(`Emitted unencrypted log: "${log.toString('ascii')}"`); } diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index e208954ef8c..6d14cc64352 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -136,10 +136,13 @@ export class PublicExecutionContext extends TypedOracle { /** * Emit an unencrypted log. + * @param contractAddress - The address of the contract emitting the log. + * @param eventSelector - The event selector of the log. * @param log - The unencrypted log to be emitted. */ - public emitUnencryptedLog(log: Buffer) { + public emitUnencryptedLog(contractAddress: AztecAddress, eventSelector: FunctionSelector, log: Buffer) { // https://github.com/AztecProtocol/aztec-packages/issues/885 + // TODO: #2586, #2587 this.unencryptedLogs.push(log); this.log(`Emitted unencrypted log: "${log.toString('ascii')}"`); } diff --git a/yarn-project/aztec-nr/aztec/src/log.nr b/yarn-project/aztec-nr/aztec/src/log.nr index 5ddbe4c5605..1c483b76702 100644 --- a/yarn-project/aztec-nr/aztec/src/log.nr +++ b/yarn-project/aztec-nr/aztec/src/log.nr @@ -1,4 +1,4 @@ -use crate::context::PrivateContext; +use crate::context::{PrivateContext, PublicContext}; use crate::oracle; use crate::types::point::Point; @@ -14,9 +14,25 @@ fn emit_encrypted_log( } fn emit_unencrypted_log( + context: &mut PublicContext, + log: T, +) { + let contract_address = context.this_address(); + let event_selector = 5; // TODO: compute actual event selector. + let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); + // context.accumulate_unencrypted_logs(log); +} + +// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy. +// --> might be a better approach to force devs to make a public function call that emits the log if needed then +// it would be less easy to accidentally leak information. +// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log. +fn emit_unencrypted_log_from_private( context: &mut PrivateContext, log: T, ) { - let _ = oracle::logs::emit_unencrypted_log(log); - context.accumulate_unencrypted_logs(log); + let contract_address = context.this_address(); + let event_selector = 5; // TODO: compute actual event selector. + let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log); + // context.accumulate_unencrypted_logs(log); } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/logs.nr b/yarn-project/aztec-nr/aztec/src/oracle/logs.nr index 49d9082b48d..c5cf55724ad 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/logs.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/logs.nr @@ -25,9 +25,9 @@ unconstrained fn emit_encrypted_log( } #[oracle(emitUnencryptedLog)] -fn emit_unencrypted_log_oracle(_message: T) -> Field {} +fn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {} -unconstrained fn emit_unencrypted_log(message: T) -> [Field; NUM_FIELDS_PER_SHA256] { +unconstrained fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] { // https://github.com/AztecProtocol/aztec-packages/issues/885 - [emit_unencrypted_log_oracle(message), 0] + [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0] } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr index 2c661162d84..a1d592fc0ae 100644 --- a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr @@ -5,10 +5,8 @@ contract Child { use dep::aztec::{ abi::CallContext, context::{PrivateContext, PublicContext, Context}, - oracle::{ - logs::emit_unencrypted_log, - compute_selector::compute_selector, - }, + oracle::compute_selector::compute_selector, + log::emit_unencrypted_log, state_vars::public_state::PublicState, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, }; @@ -67,7 +65,7 @@ contract Child { fn pubSetValue(new_value: Field) -> Field { storage.current_value.write(new_value); - let _hash = emit_unencrypted_log(new_value); + emit_unencrypted_log(&mut context, new_value); new_value } @@ -78,7 +76,7 @@ contract Child { let old_value = storage.current_value.read(); storage.current_value.write(old_value + new_value); - let _hash = emit_unencrypted_log(new_value); + emit_unencrypted_log(&mut context, new_value); new_value } @@ -90,7 +88,7 @@ contract Child { check_sender(inputs.call_context); let old_value = storage.current_value.read(); storage.current_value.write(old_value + new_value); - let _hash = emit_unencrypted_log(new_value); + emit_unencrypted_log(&mut context, new_value); new_value } @@ -102,14 +100,14 @@ contract Child { storage.current_value.write(20); - let _hash = emit_unencrypted_log(20); + emit_unencrypted_log(&mut context, 20); } #[aztec(public)] fn setValueTwiceWithNestedLast() { storage.current_value.write(20); - let _hash = emit_unencrypted_log(20); + emit_unencrypted_log(&mut context, 20); let pubSetValueSelector = compute_selector("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); diff --git a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr index 5118a874d78..343d15cb077 100644 --- a/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/private_token_airdrop_contract/src/main.nr @@ -18,7 +18,7 @@ contract PrivateTokenAirdrop { note_header::NoteHeader, utils as note_utils, }, - log::emit_unencrypted_log, + log::emit_unencrypted_log_from_private, }; use crate::claim_note::{ClaimNote, ClaimNoteMethods, CLAIM_NOTE_LEN}; @@ -220,7 +220,7 @@ contract PrivateTokenAirdrop { // In this example, we emit the first output note's commitment to ensure that the unencrypted log // for each call to this function is distinct. This is done to detect any issues while collecting // logs when building a transaction. See: https://github.com/AztecProtocol/aztec-packages/issues/987 - emit_unencrypted_log(&mut context, context.new_commitments.storage[0]); + emit_unencrypted_log_from_private(&mut context, context.new_commitments.storage[0]); } // Helper function to get the balance of a user ("unconstrained" is a Noir alternative of Solidity's "view" function). diff --git a/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr index fb1f0c365e1..23815b7c740 100644 --- a/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/public_token_contract/src/main.nr @@ -3,7 +3,7 @@ contract PublicToken { use dep::std::option::Option; // docs:start:unencrypted_import - use dep::aztec::oracle::logs::emit_unencrypted_log; + use dep::aztec::log::emit_unencrypted_log; // docs:end:unencrypted_import use dep::aztec::{ @@ -53,7 +53,7 @@ contract PublicToken { let new_amount = recipient_balance.read() + amount; // TODO: Remove return value. // docs:start:unencrypted_log - let _hash = emit_unencrypted_log("Coins minted"); + emit_unencrypted_log(&mut context, "Coins minted"); // docs:end:unencrypted_log recipient_balance.write(new_amount); @@ -81,7 +81,7 @@ contract PublicToken { if (current_sender_balance as u126 > amount as u126) { sender_balance.write(current_sender_balance - amount); // TODO: Compiler complains if we don't assign the result of the write to anything - let _hash = emit_unencrypted_log("Coins transferred"); + emit_unencrypted_log(&mut context, "Coins transferred"); let amount = current_recipient_balance + amount; recipient_balance.write(amount); return_value = amount; diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index f467af53656..0e892eb9b98 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -7,9 +7,9 @@ contract Test { oracle::{ get_public_key::get_public_key, context::get_portal_address, - rand::rand, - logs::emit_unencrypted_log + rand::rand }, + log::emit_unencrypted_log, types::vec::BoundedVec, constants_gen::EMPTY_NULLIFIED_COMMITMENT, }; @@ -127,8 +127,8 @@ contract Test { fn emit_unencrypted( value: Field ) -> Field { - let _hash = emit_unencrypted_log(value); - _hash[0] + emit_unencrypted_log(&mut context, value); + 0 } // docs:end:emit_unencrypted_log