diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index ecbc8f16f0c..314dc77414b 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -507,28 +507,42 @@ fn handle_emit_unencrypted_log( inputs.len() ); } - let (event_offset, message_array) = match &inputs[..] { - [ValueOrArray::MemoryAddress(offset), ValueOrArray::HeapArray(array)] => { - (offset.to_usize() as u32, array) + let event_offset = match &inputs[0] { + ValueOrArray::MemoryAddress(offset) => offset.to_usize() as u32, + _ => panic!( + "Unexpected inputs[0] (event) for ForeignCall::EMITUNENCRYPTEDLOG: {:?}", + inputs[0] + ), + }; + let (message_offset, message_size, message_offset_indirect) = match &inputs[1] { + ValueOrArray::HeapArray(array) => { + // Heap array, so offset to array is an indirect memory offset + (array.pointer.to_usize() as u32, array.size as u32, true) } + ValueOrArray::MemoryAddress(single_val) => (single_val.to_usize() as u32, 1 as u32, false), _ => panic!( "Unexpected inputs for ForeignCall::EMITUNENCRYPTEDLOG: {:?}", inputs ), }; + let indirect_flag = if message_offset_indirect { + FIRST_OPERAND_INDIRECT + } else { + 0 + }; avm_instrs.push(AvmInstruction { opcode: AvmOpcode::EMITUNENCRYPTEDLOG, // The message array from Brillig is indirect. - indirect: Some(FIRST_OPERAND_INDIRECT), + indirect: Some(indirect_flag), operands: vec![ AvmOperand::U32 { value: event_offset, }, AvmOperand::U32 { - value: message_array.pointer.to_usize() as u32, + value: message_offset, }, AvmOperand::U32 { - value: message_array.size as u32, + value: message_size, }, ], ..Default::default() diff --git a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr index 30097e522f1..d7180bd8338 100644 --- a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr @@ -38,7 +38,7 @@ impl AvmContext { * Should be automatically convertible to [Field; N]. For example str works with * one char per field. Otherwise you can use CompressedString. */ - pub fn emit_unencrypted_log(&mut self, event_selector: Field, log: T) { + pub fn emit_unencrypted_log_with_selector(&mut self, event_selector: Field, log: T) { emit_unencrypted_log(event_selector, log); } pub fn note_hash_exists(self, note_hash: Field, leaf_index: Field) -> bool { @@ -88,7 +88,7 @@ impl PublicContextInterface for AvmContext { fn emit_unencrypted_log(&mut self, log: T) { let event_selector = 5; // Matches current PublicContext. - self.emit_unencrypted_log(event_selector, log); + self.emit_unencrypted_log_with_selector(event_selector, log); } fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field) { diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 03b9f8912da..d7c66b4432a 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -261,10 +261,10 @@ contract AvmTest { #[aztec(public-vm)] fn emit_unencrypted_log() { - context.emit_unencrypted_log(/*event_selector=*/ 5, /*message=*/ [10, 20, 30]); - context.emit_unencrypted_log(/*event_selector=*/ 8, /*message=*/ "Hello, world!"); + context.emit_unencrypted_log_with_selector(/*event_selector=*/ 5, /*message=*/ [10, 20, 30]); + context.emit_unencrypted_log_with_selector(/*event_selector=*/ 8, /*message=*/ "Hello, world!"); let s: CompressedString<2,44> = CompressedString::from_string("A long time ago, in a galaxy far far away..."); - context.emit_unencrypted_log(/*event_selector=*/ 10, /*message=*/ s); + context.emit_unencrypted_log_with_selector(/*event_selector=*/ 10, /*message=*/ s); } #[aztec(public-vm)]