From a6a71d802ce6988e8a3661d8ff8b62956aa71ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 May 2024 15:26:25 -0300 Subject: [PATCH] chore: fix poor performance and long compile times in value_note.derement() (#6523) https://github.com/AztecProtocol/aztec-packages/pull/6405 added a very complicated call (`get_npk_m_hash`) to `destroy_note`, not realizing that `destroy_note` is called in a loop by `decrement`. The loop unrolling caused multiple calls to this function, even though they all had the same arguments, ultimately resulting in humongous RAM usage during compilation (over 40GB just for this contract) and very compilation times (from 30s to multiple minutes). This PR fixes this simply inlining the code for `destroy_note` and fetching the key once at the beginning. It does worry me slightly however that such a large performance hit was not noticed - this likely affected test times as well. --- noir-projects/aztec-nr/value-note/src/utils.nr | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index 8b0b6e2dac95..466cf660d3f8 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -52,7 +52,18 @@ pub fn decrement_by_at_most( let mut decremented = 0; for i in 0..opt_notes.len() { if opt_notes[i].is_some() { - decremented += destroy_note(balance, owner, opt_notes[i].unwrap_unchecked()); + let note = opt_notes[i].unwrap_unchecked(); + + // This is similar to destroy_note, except we only compute the owner_npk_m_hash once instead of doing it in + // each loop iteration. + + // Ensure the note is actually owned by the owner (to prevent user from generating a valid proof while + // spending someone else's notes). + // TODO (#6312): This will break with key rotation. Fix this. Will not be able to pass this after rotating keys. + assert(note.npk_m_hash.eq(owner_npk_m_hash)); + decremented += note.value; + + balance.remove(note); } }