@aztec/protocol-contracts 5.0.0-nightly.20260331 → 5.0.0-nightly.20260402

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "transpiled": true,
3
- "noir_version": "1.0.0-beta.19+0ea490f9eaf15585e3f55d4c44c154f66436e40c",
3
+ "noir_version": "1.0.0-beta.19+c033e48bb813206dd272c1d24ea3c220f69f3fc4",
4
4
  "name": "AuthRegistry",
5
5
  "functions": [
6
6
  {
@@ -2115,7 +2115,7 @@
2115
2115
  }
2116
2116
  }
2117
2117
  },
2118
- "bytecode": "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",
2118
+ "bytecode": "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",
2119
2119
  "debug_symbols": "tVvdbhu5Dn4XX/dCpPgj5VUWB0XaehcBgrTIJgscFH33I85InLH3SJ54pjcl3cTfR4kSRYnMz9O385f3vz4/vfz5/e/Twx8/T19en56fn/76/Pz96+Pb0/eX8r8/T8H+gXh6wPjr0wn8E5ZPOH3KpwcqepgFzAJnEWdBs+DTQy5CTg8ARWqVqco8yxiqhCqxylhlQQMskquUKrXKVGWeJYUqoUqsMlZZ8ajiUcWjikcVjyoeVzyueFzxuOJxxeOKxxWPKx4bXioyz1JClYZX5kcML5fpjTa9Nto6WJtymqa8IGKZUNAqU5V5luYLrM7A6g2s7sDqD9TZIZOUKg0vzR6ZZJ6leSSG2SOTRJPFGp6ssd+Gyg6VHSo7VHao7FC+JdO37KeGof9nlKn9Bvwqn9p6/Pz2ej7bT1YLtCzbH4+v55e308PL+/Pzp9M/j8/v0y/9/ePxZZJvj6/lp8Xs88u3Igvgn0/PZ9N+fVq+HfpfFZb6ZQ3qX4dMWwE45QoguAJImy0A0qwVAiihOAjjBUbsYyhxG4XyXUYwJGpGMAL3jOA+BmGMFYJiAEcguDRD+hBRpUHEFLELofsh0mAgQVMbSMjrgeCd84nUm08Yrc1AvrYCJ4eIH0BwlxQw6SCMx+HTWcYRoTuOweqMDM0jslqd+WocNDAjILZ9WnTSrk+ARygEyVGIsI8yWKNC0IYjNB2cHYzBIsXYQhby2oq4fU7RV7mk7pyG3xIzd0cbyc14pbwyPm1elgHYHalhBZE32xDbUkhh2Z2gshUgpTaIlFMXAAfrseyG5kNdTCgh5xJhsBbRPYGifYRtNqTYRRhMQ8YGkKP0pyHvHcRoPWYfRAqrHQlwaUSEgTez+DDSPesJEdp6QFy501x7YcToGM8+DpBuYImDQJkV2zAS33NwYZSWjKB9rTuXo1UJknwqVklRuhrHIEDmGJZltQrUkfkSY3CM50DNIznk0McYrM1ISzKxLAuUy8mgwYTGsETqsDo/P4QBoa3OCER9DBzkqSAtIWFcZWeQtpsh7MFCJN43lDWG6p0YGBxjleJ9CCMvbskycIv+3inNaTEj980Y7Vgi8h27PomudiwPz9Oy2Zf8auUXyR8AIVrSK16dqrI5ijKy+pSm3B/MIIpiiuLpVbJzpDeYIQj5zRATr8LHh0DUw1jRFe6YEVKfVEqwmMGX2RYP1mlJ4aFdJIpOsXu5G0RTQFpS8JKBp+6E5NEVsTmGgBe/8OahRM6eMq12S5J7J2OVfl9NhgyCafazPuP6oP6AFUR+6RdapbDXVtABF27ef12WA27tovvv3Dcm1deXTWp3ncsoG8XgLzolp6PUA9GwP31R2J++KO5NXzTuT1+GGBvTF+XdZ+3QjI3py2aMQfoyxtiWvgwxNqYvKfzeKd2Yvox3rSTPPUSl+1Q2BlH1dypJMfdA0uiVScXjetEz3AfC6FmQcj8IpUFE5Sy+ZYqO3cQh6e5rWEr741jK++NYDnvjWIb9m3+MsW3jDjE2btxMuzfu2IxtG/fGIo2wLFLtpsh5dO5HXrLb7lviDTNScDO0v1dyHr0GQmqGlAw53AdCvDy3l+tDd0K2xw/l0K8cDA5+iP7CDGXZOobCRzD8OQoIqI9Bu2MQBB69MIo/auFqrV4HkCnL2FtL4f3BEMIBj1IQdr9KARzwlnMDZFtAHINsjIgwKodsDIk3DNkWE29smqXuN9g04wig/p5d9Ix3pSEJwC+Y5TW5e40BSKPLEGdYXrWhH4wgH7BxMBywcRB2bxzE/ReiMcjGGxHg/jRgbMjWMDAG2RYGbqxXpWW95m4XBODokSpHaGdF0an7jgmjghSn5KnAqqSVP2QIob8yZVqV3q8NGRalStkblsoWh3veD9Py5pY49t4PYVSXKsvQa9729rcqC4XrkjXt7Ua4YQl7wlj01Q3835bIsMrlaQnF2E1LjihRwRE1KthfpIIjqlRwRJkKDqhTwRGFKjiiUgVHlKrgiFoVHFCsgiOqVbe2cF6CiaxC0r+28KjatO3ieMMS8WI3lOwmDywZrFgN2XO+kiL1744wqhVtjvVjW2DKTqstMDh3eNTJ5w2JzOsDcHtTZClEOkIM3TIejN70NtfxbqCQlxRLIS/InSiMK5R0vy2biopDlE3Fpxt27K9L8jKtxcX9RpFR346oN5JJpkuI/5SPj1+fXi871q07OuLcHW2nnvUnTzLPcupUT7VVPc39yVz7kydJFv7m7uhJio1k7o6eZMEzF1l3tEnrjp4kVIlVxirJcpm5uXmSUqVWmarMs7R+dYG5X32SaEnm3K8+SbK5mPvVJylVapXJeoPmfnWT1q8+Saiy4FmMtn51e72xfvVJcpVinUG1Xz2E2rA+KdaxHqC2rE8KTIGwNq1be6ZMXfrFDCFTiv9l6oMvwCJN0aYYsr1CiSGb0zQ0xZDNXYpNiU2hphiyuVClKdoUQzZvqiGb21JoiiGbY5IhWz07xaYYspWPEzdFmqJNMWTzU8pVyaEp0BRDNt9lQ7anqUxN4aZIU7QpqSm5KmXWXQPX0LXoGrnGrolr6lpyzTnAOcA5wDnAOcA5wDnAOcA5wDnAOdA50DnQOdA50DnQOdA50DnQOdA5onNE54jOEZ1j+vsR20gw/QXJrIlr6ppzROcg5yDnIOcg5yAfB/k4yMdBPg5yDnIOdg52DnYOdg52DnYOdg52DnYOdg5xDnEOcQ5xDnEOcQ5xDnEOcQ5xDnUOdQ51DnUOdQ51DnUOdQ51DnWO5BzJOZJzTPt6Khb+8/j69Pjl+WwHhJ0h7y9f23lRPr7990f7SfsbqB+v37+ev72/nu1smY6VWP/5oyTaMdrRw/4/8imK/Y9e/Y4dUf8D",
2120
2120
  "verification_key": "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"
2121
2121
  },
@@ -2203,7 +2203,7 @@
2203
2203
  }
2204
2204
  }
2205
2205
  },
2206
- "bytecode": "H4sIAAAAAAAA/+1cTWwbxxXm/v/QsWM7thQrrpReeihQQHZR5BqLciXbsgw76pXdSFuFCEWqy6UR9VCUPRcoKTsteo0lVUXq9tAWKGqgp6JAURHopQgCGAgCJKcEySGBgeSUZcTdfTuzb3ZnObQTRDltODvfm33zvZ95b2Rlu/fbt79brTo/893VasOr1hq+6zWceqtabfu1es3fqtZa1dVmo9XecF6uu3Kv8+Ylr1av19bnnHr9bmm7s3er1livu3e6ve1/zZTY/0mlzFdKfIBSNmBvgLixGSz+Trebjbhdkro9ORDOpZiH8onO7lzwv/6dzl6l5rmrvtz5/WIwa9317q1cvJAtmJwvcc3/xTI5v8Qnf7mzM9jS3vEIZ/+mW3f82m1X5UOSaQSND6HU+eNgLWuO78w1N7eiT7oG1wTA7y01b2/HP8jx+8SIEo4sDb92cvjG8OfrEIT6CoXvK66PrEmps3PLb272El8AwIgdn9u9XHPra5mwZ8iJFb5lKeT8ed7tJeZfzrlwauIPI8FvrMzym9jCiCa6WNQwhvOv8M0/S86/yjd/Yu+m67e9RufNy03Pra03Bibw+tvfOfRybb9edVot1/PnmhubAcMCt7bsOat190eu16o1G91ur3N/yd1oelsvrq15bqsVES/ysYcbmRTwIMZfd/2VQ/cZfIjvvuY/LE2QmIDf2IiGjujoiIGOmOiIhY7Y6EgZHTmGjjyFjhxHR06gI0+jIyfRkVPoyGl05Bl05Aw6chYdwXkwiY48i46cGxArycmv2f8lTDvzlR98nwtzZ2X2wgvsX7NX2u3SAW4qpyeX6KnP5Zn68c1bS2RQPx9nTBTot/g8pBqkt7WG420Fk5Y3X4+A7wUEO9yHUBKQcH+xsXboBgnh53nDS1J4LCIST3+zTGpjGi5tN0gfPDd99DlM3DQtbjoWx4KcEg8pj7yn07SGogyZGHkeKjiVCSWSCSW4rsOc8uD/yaQSvEJJnILC7x9K/NIMljfvgsXszf+0HRw+4LwwdWLpJ09SVEL3bCg0AIFqAWL2rrQ3Nhd/AlV7caiDvvS9wRNhDnEgGvoT8pWTIO4gr5wGwQR55SyIKsNXCLVPMFzGNGdSxe8ypnGXMSHIZaQY3ATqMmbg0ihjnIEZGSJuhhY3w7DvGZjKCYfUxUMa4iFN8ZCWeEhbPGRZPOQx8ZBPiYc8Lh7yhHjIp8VDnhcPeUo85EnxkM+IhzwjHvK0eMiz4iEnxUM+m1Kgy3MI+fzUo3fJGKoxMgqdt0zEnVHoeEahCcoodFrNGppRGHBp1BYYMKMYVVvF0nuqZvxtmChxp/56lPbO5s/9VbgySg3G41CDyv+pRvSpP8//qTqUTnEFtxxz7JZj4pZjCLIck7YcI7acRKn0n4lS6WWvuXGj/XK9tjqwIGfd7XX+sOA6my96nrMFNGhKvc7u4Y9EIVa6W6BSeg4dmULqvwt3R61vFVDdQmfnWtNZg3qAj+Sh0Epj1RsrL1AvAu9kIQdMM40kaViI0FmmUCYiIjpwO9ebCKA5GKZNK2eljvLtFsNe7bGX22zcXi1B9mrTpLPQSFeGS6MiHRhFy21lWlyZkb+UIReEQ8oj++BigcjiD0RmgXKbDIWj5TaTKrfJcbkNUbmVVi0DxppWLbMOdkG5jFiqyTAza+xmZuFmZgoyM4smqYmamQ2XRhHYzmFmKVZtM2zChpsvHFIZ+XJBMTMz+c1MGZuZKQXMzEwzM4VtZubBA1iVJpIGBU/843fojVYYGz2R0B4uTxMkT8spTxUkT4WvYTdsJAH3iLjdloq7LUWQ21KZuhKQzauPK5uXH3c2LzNUR2fzMnwk02AVDrLyZUh/JJuX00iShoUInWUKZSIiomdxQ11q1xO+z4BguBtWwqs/9NW8jHOAEj7Q5QthFS9NaMVLHV/FSy1c8coKbAazSPC1BATxCQsS852dQbjuHbyPSdWGAR9xG/NFNo/2NTp8zP/9anwRkEQ0ElqichLt4KPw0z9kmK0e3dhDtDPwB4hqKnjiXandRiq5lazEizwXQ7kpmdcnUeb1CYq8fy0IPi+94jTQNaUhP4qQH3GcMGQQqnOXnCy4KGbRCc11v1xKKt/MZFrNut+r8nrVUEOf0fXYIaTGoQY9th/K2k2orfyQWgyJ7eGfQnak8U+DK0g5YPclNVSCjDaJLYSAJouAAbSRzUC7CAOttGMlWBXJQAs+4kWNJAMTBUeMgfr4GGhkMtBixJtFmoGJUmuBoFApFBRYnF4cF6cnsjmtFeG01pfOjcmrakyvSnNag495Oa3TKQfNaWN8nNYyOc1qolZoTqeEif1vcvqtZfLMYObs+5fqzuqrl5qvdf56o9lya2vNxoUbrrfR9oM3m41tqHoVOiuVg9fgSEulvTCPCBNfUpGRsuHtblyN/3jw/Fu/vDgZHGtf8pzBnwpF88PPzsghdYY9Z2TKHHcgOP8abpKfkvL470DIBe9AsI9Heucre4Q7AjwCPAI8AjwCPAIUDogltGFRsC+9ggZi5HgTYVxJOd7IfWkjgn6VUXXTMjImmVlbzK8nJTOd1dOUC4QWqmMiuouSvqspujP6kg+OhtjhShvxcDU5SsEg454dxy2EfUbiZjES4ESDiEqOwapignP3YybCh6MD4VE/pmg/ZtR/oMPI7Oj0pV+j+4g4oDw3Iwyutk6iCZPfazDaOolqP+0m9b70l0gBv+G4biHHgYtxgUPBS2EaWt5VnkSDQSlSClMYDQY9BzlUhl6vUnpV4SOqVzmpVxNOwvSqjE+vaqZeNSafWXeHZPTf0ZFGvq5WIKIoeESRBUUUhRlR8itYLlRiVGCJUVOLeIsFtrfIcR8Etc4CjWWbbizr2d3o1MZy4q5kahPk79mdZayxp7My3QD6wRNp7OkFG3t2gcae+lVt7C0wE26bA1LPPJHZzDacDldA08TuS//JbsPZCAMtFgMD6INsBpaLMNBO+8MAsCqSgTZ8zHu5wYSTnkAbzsxkoJ126MNjZOLyeYHEtFIoMWVxenFcnH6YzWm9CKeDxPidMXlVnelVLXaNJC+nE8dJjNPmk7ywYzDoUmEeBy2eSoIx9rzPGH8lgaUrnothxVrLBsz7TLXYAQlvLevgBD5ib1lTp3438+cfX8vuLY8o6D3zxrz8t19NZwsaWvPwZz22wlSeGTC5JOfIsZ8KX+/LRMQCLe28RI5sP3WCRU5Q4gkJyXb8QuL3cry04T7LOqEVM8YI7Z6cjPwhkE2uzsbMIgQkJ5QzJhxLRg9SjEXtybG+LGP04u7rhxorI7usCOLz/4wPPv3vv9e7mXz+AitWD/yCWQAA",
2206
+ "bytecode": "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",
2207
2207
  "debug_symbols": "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"
2208
2208
  },
2209
2209
  {
@@ -2546,8 +2546,8 @@
2546
2546
  }
2547
2547
  }
2548
2548
  },
2549
- "bytecode": "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",
2550
- "debug_symbols": "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"
2549
+ "bytecode": "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",
2550
+ "debug_symbols": "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"
2551
2551
  }
2552
2552
  ],
2553
2553
  "outputs": {
@@ -3221,19 +3221,19 @@
3221
3221
  },
3222
3222
  {
3223
3223
  "name": "test::do_sync_state_does_not_panic_on_empty_logs",
3224
- "start": 9994
3224
+ "start": 9928
3225
3225
  },
3226
3226
  {
3227
3227
  "name": "test::dummy_compute_note_hash",
3228
- "start": 11223
3228
+ "start": 11209
3229
3229
  },
3230
3230
  {
3231
3231
  "name": "test::dummy_compute_note_nullifier",
3232
- "start": 11584
3232
+ "start": 11570
3233
3233
  }
3234
3234
  ],
3235
3235
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/messages/discovery/mod.nr",
3236
- "source": "use crate::logging::{aztecnr_debug_log, aztecnr_debug_log_format, aztecnr_warn_log_format};\nuse crate::protocol::address::AztecAddress;\n\npub(crate) mod nonce_discovery;\npub(crate) mod partial_notes;\npub(crate) mod private_events;\npub mod private_notes;\npub mod process_message;\n\nuse crate::{\n capsules::CapsuleArray,\n messages::{\n discovery::process_message::process_message_ciphertext,\n encoding::MAX_MESSAGE_CONTENT_LEN,\n logs::note::MAX_NOTE_PACKED_LEN,\n processing::{\n get_private_logs, MessageContext, offchain::OffchainInboxSync, OffchainMessageWithContext,\n pending_tagged_log::PendingTaggedLog, validate_and_store_enqueued_notes_and_events,\n },\n },\n utils::array,\n};\n\npub struct NoteHashAndNullifier {\n /// The result of [`crate::note::note_interface::NoteHash::compute_note_hash`].\n pub note_hash: Field,\n /// The result of [`crate::note::note_interface::NoteHash::compute_nullifier_unconstrained`].\n ///\n /// This value is unconstrained, as all of message discovery is unconstrained. It is `None` if the nullifier\n /// cannot be computed (e.g. because the nullifier hiding key is not available).\n pub inner_nullifier: Option<Field>,\n}\n\n/// A contract's way of computing note hashes.\n///\n/// Each contract in the network is free to compute their note's hash as they see fit - the hash function itself is not\n/// enshrined or standardized. Some aztec-nr functions however do need to know the details of this computation (e.g.\n/// when finding new notes), which is what this type represents.\n///\n/// This function takes a note's packed content, storage slot, note type ID, address of the emitting contract and\n/// randomness, and attempts to compute its inner note hash (not siloed by address nor uniqued by nonce).\n///\n/// ## Transient Notes\n///\n/// This function is meant to always be used on **settled** notes, i.e. those that have been inserted into the trees\n/// and for which the nonce is known. It is never invoked in the context of a transient note, as those are not involved\n/// in message processing.\n///\n/// ## Automatic Implementation\n///\n/// The [`[#aztec]`](crate::macros::aztec::aztec) macro automatically creates a correct implementation of this function\n/// for each contract by inspecting all note types in use and the storage layout. This injected function is a\n/// `#[contract_library_method]` called `_compute_note_hash`, and it looks something like this:\n///\n/// ```noir\n/// |packed_note, owner, storage_slot, note_type_id, _contract_address, randomness| {\n/// if note_type_id == MyNoteType::get_id() {\n/// if packed_note.len() != MY_NOTE_TYPE_SERIALIZATION_LENGTH {\n/// Option::none()\n/// } else {\n/// let note = MyNoteType::unpack(aztec::utils::array::subarray(packed_note.storage(), 0));\n/// Option::some(note.compute_note_hash(owner, storage_slot, randomness))\n/// }\n/// } else if note_type_id == MyOtherNoteType::get_id() {\n/// ... // Similar to above but calling MyOtherNoteType::unpack\n/// } else {\n/// Option::none() // Unknown note type ID\n/// };\n/// }\n/// ```\npub type ComputeNoteHash = unconstrained fn(/* packed_note */BoundedVec<Field, MAX_NOTE_PACKED_LEN>, /*\n owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress, /*\nrandomness */ Field) -> Option<Field>;\n\n/// A contract's way of computing note nullifiers.\n///\n/// Like [`ComputeNoteHash`], each contract is free to derive nullifiers as they see fit. This function takes the\n/// unique note hash (used as the note hash for nullification for settled notes), plus the note's packed content and\n/// metadata, and attempts to compute the inner nullifier (not siloed by address).\n///\n/// ## Automatic Implementation\n///\n/// The [`[#aztec]`](crate::macros::aztec::aztec) macro automatically creates a correct implementation of this function\n/// for each contract called `_compute_note_nullifier`. It dispatches on `note_type_id` similarly to\n/// [`ComputeNoteHash`], then calls the note's\n/// [`compute_nullifier_unconstrained`](crate::note::note_interface::NoteHash::compute_nullifier_unconstrained) method.\npub type ComputeNoteNullifier = unconstrained fn(/* unique_note_hash */Field, /* packed_note */ BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n/* owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress,\n/* randomness */ Field) -> Option<Field>;\n\n/// Deprecated: use [`ComputeNoteHash`] and [`ComputeNoteNullifier`] instead.\npub type ComputeNoteHashAndNullifier<Env> = unconstrained fn[Env](/* packed_note */BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n/* owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress,\n/*randomness */ Field, /* note nonce */ Field) -> Option<NoteHashAndNullifier>;\n\n/// A handler for custom messages.\n///\n/// Contracts that emit custom messages (i.e. any with a message type that is not in [`crate::messages::msg_type`])\n/// need to use [`crate::macros::AztecConfig::custom_message_handler`] with a function of this type in order to\n/// process them. They will otherwise be **silently ignored**.\npub type CustomMessageHandler<Env> = unconstrained fn[Env](\n/* contract_address */AztecAddress,\n/* msg_type_id */ u64,\n/* msg_metadata */ u64,\n/* msg_content */ BoundedVec<Field, MAX_MESSAGE_CONTENT_LEN>,\n/* message_context */ MessageContext,\n/* scope */ AztecAddress);\n\n/// Synchronizes the contract's private state with the network.\n///\n/// As blocks are mined, it is possible for a contract's private state to change (e.g. with new notes being created),\n/// but because these changes are private they will be invisible to most actors. This is the function that processes\n/// new transactions in order to discover new notes, events, and other kinds of private state changes.\n///\n/// The private state will be synchronized up to the block that will be used for private transactions (i.e. the anchor\n/// block. This will typically be close to the tip of the chain.\npub unconstrained fn do_sync_state<CustomMessageHandlerEnv>(\n contract_address: AztecAddress,\n compute_note_hash: ComputeNoteHash,\n compute_note_nullifier: ComputeNoteNullifier,\n process_custom_message: Option<CustomMessageHandler<CustomMessageHandlerEnv>>,\n offchain_inbox_sync: Option<OffchainInboxSync<()>>,\n scope: AztecAddress,\n) {\n aztecnr_debug_log!(\"Performing state synchronization\");\n\n // First we process all private logs, which can contain different kinds of messages e.g. private notes, partial\n // notes, private events, etc.\n let logs = get_private_logs(contract_address, scope);\n logs.for_each(|i, pending_tagged_log: PendingTaggedLog| {\n if pending_tagged_log.log.len() == 0 {\n aztecnr_warn_log_format!(\"Skipping empty log from tx {0}\")([pending_tagged_log.context.tx_hash]);\n } else {\n aztecnr_debug_log_format!(\"Processing log with tag {0}\")([pending_tagged_log.log.get(0)]);\n\n // We remove the tag from the pending tagged log and process the message ciphertext contained in it.\n let message_ciphertext = array::subbvec(pending_tagged_log.log, 1);\n\n process_message_ciphertext(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n process_custom_message,\n message_ciphertext,\n pending_tagged_log.context,\n scope,\n );\n }\n\n // We need to delete each log from the array so that we won't process them again. `CapsuleArray::for_each`\n // allows deletion of the current element during iteration, so this is safe.\n // Note that this (and all other database changes) will only be committed if contract execution succeeds,\n // including any enqueued validation requests.\n logs.remove(i);\n });\n\n if offchain_inbox_sync.is_some() {\n let msgs: CapsuleArray<OffchainMessageWithContext> = offchain_inbox_sync.unwrap()(contract_address, scope);\n msgs.for_each(|i, msg| {\n process_message_ciphertext(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n process_custom_message,\n msg.message_ciphertext,\n msg.message_context,\n scope,\n );\n // The inbox sync returns _a copy_ of messages to process, so we clear them as we do so. This is a\n // volatile array with the to-process message, not the actual persistent storage of them.\n msgs.remove(i);\n });\n }\n\n // Then we process all pending partial notes, regardless of whether they were found in the current or previous\n // executions.\n partial_notes::fetch_and_process_partial_note_completion_logs(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n scope,\n );\n\n // Finally we validate all notes and events that were found as part of the previous processes, resulting in them\n // being added to PXE's database and retrievable via oracles (get_notes) and our TS API (PXE::getPrivateEvents).\n validate_and_store_enqueued_notes_and_events(contract_address, scope);\n}\n\nmod test {\n use crate::{\n capsules::CapsuleArray,\n messages::{\n discovery::{CustomMessageHandler, do_sync_state},\n logs::note::MAX_NOTE_PACKED_LEN,\n processing::{\n offchain::OffchainInboxSync, pending_tagged_log::PendingTaggedLog, PENDING_TAGGED_LOG_ARRAY_BASE_SLOT,\n },\n },\n test::helpers::test_environment::TestEnvironment,\n };\n use crate::protocol::address::AztecAddress;\n\n global SCOPE: AztecAddress = AztecAddress { inner: 0xcafe };\n\n #[test]\n unconstrained fn do_sync_state_does_not_panic_on_empty_logs() {\n let env = TestEnvironment::new();\n\n let contract_address = AztecAddress { inner: 0xdeadbeef };\n\n env.utility_context_at(contract_address, |_| {\n let base_slot = PENDING_TAGGED_LOG_ARRAY_BASE_SLOT;\n\n let logs: CapsuleArray<PendingTaggedLog> = CapsuleArray::at(contract_address, base_slot, SCOPE);\n logs.push(PendingTaggedLog { log: BoundedVec::new(), context: std::mem::zeroed() });\n assert_eq(logs.len(), 1);\n\n let no_handler: Option<CustomMessageHandler<()>> = Option::none();\n let no_inbox_sync: Option<OffchainInboxSync<()>> = Option::none();\n do_sync_state(\n contract_address,\n dummy_compute_note_hash,\n dummy_compute_note_nullifier,\n no_handler,\n no_inbox_sync,\n SCOPE,\n );\n\n assert_eq(logs.len(), 0);\n });\n }\n\n unconstrained fn dummy_compute_note_hash(\n _packed_note: BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n _owner: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _contract_address: AztecAddress,\n _randomness: Field,\n ) -> Option<Field> {\n Option::none()\n }\n\n unconstrained fn dummy_compute_note_nullifier(\n _unique_note_hash: Field,\n _packed_note: BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n _owner: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _contract_address: AztecAddress,\n _randomness: Field,\n ) -> Option<Field> {\n Option::none()\n }\n}\n"
3236
+ "source": "use crate::logging::{aztecnr_debug_log, aztecnr_debug_log_format, aztecnr_warn_log_format};\nuse crate::protocol::address::AztecAddress;\n\npub(crate) mod nonce_discovery;\npub(crate) mod partial_notes;\npub(crate) mod private_events;\npub mod private_notes;\npub mod process_message;\n\nuse crate::{\n capsules::CapsuleArray,\n messages::{\n discovery::process_message::process_message_ciphertext,\n encoding::MAX_MESSAGE_CONTENT_LEN,\n logs::note::MAX_NOTE_PACKED_LEN,\n processing::{\n get_private_logs, MessageContext, offchain::OffchainInboxSync, OffchainMessageWithContext,\n pending_tagged_log::PendingTaggedLog, validate_and_store_enqueued_notes_and_events,\n },\n },\n utils::array,\n};\n\npub struct NoteHashAndNullifier {\n /// The result of [`crate::note::note_interface::NoteHash::compute_note_hash`].\n pub note_hash: Field,\n /// The result of [`crate::note::note_interface::NoteHash::compute_nullifier_unconstrained`].\n ///\n /// This value is unconstrained, as all of message discovery is unconstrained. It is `None` if the nullifier\n /// cannot be computed (e.g. because the nullifier hiding key is not available).\n pub inner_nullifier: Option<Field>,\n}\n\n/// A contract's way of computing note hashes.\n///\n/// Each contract in the network is free to compute their note's hash as they see fit - the hash function itself is not\n/// enshrined or standardized. Some aztec-nr functions however do need to know the details of this computation (e.g.\n/// when finding new notes), which is what this type represents.\n///\n/// This function takes a note's packed content, storage slot, note type ID, address of the emitting contract and\n/// randomness, and attempts to compute its inner note hash (not siloed by address nor uniqued by nonce).\n///\n/// ## Transient Notes\n///\n/// This function is meant to always be used on **settled** notes, i.e. those that have been inserted into the trees\n/// and for which the nonce is known. It is never invoked in the context of a transient note, as those are not involved\n/// in message processing.\n///\n/// ## Automatic Implementation\n///\n/// The [`[#aztec]`](crate::macros::aztec::aztec) macro automatically creates a correct implementation of this function\n/// for each contract by inspecting all note types in use and the storage layout. This injected function is a\n/// `#[contract_library_method]` called `_compute_note_hash`, and it looks something like this:\n///\n/// ```noir\n/// |packed_note, owner, storage_slot, note_type_id, _contract_address, randomness| {\n/// if note_type_id == MyNoteType::get_id() {\n/// if packed_note.len() != MY_NOTE_TYPE_SERIALIZATION_LENGTH {\n/// Option::none()\n/// } else {\n/// let note = MyNoteType::unpack(aztec::utils::array::subarray(packed_note.storage(), 0));\n/// Option::some(note.compute_note_hash(owner, storage_slot, randomness))\n/// }\n/// } else if note_type_id == MyOtherNoteType::get_id() {\n/// ... // Similar to above but calling MyOtherNoteType::unpack\n/// } else {\n/// Option::none() // Unknown note type ID\n/// };\n/// }\n/// ```\npub type ComputeNoteHash = unconstrained fn(/* packed_note */BoundedVec<Field, MAX_NOTE_PACKED_LEN>, /*\n owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress, /*\nrandomness */ Field) -> Option<Field>;\n\n/// A contract's way of computing note nullifiers.\n///\n/// Like [`ComputeNoteHash`], each contract is free to derive nullifiers as they see fit. This function takes the\n/// unique note hash (used as the note hash for nullification for settled notes), plus the note's packed content and\n/// metadata, and attempts to compute the inner nullifier (not siloed by address).\n///\n/// ## Automatic Implementation\n///\n/// The [`[#aztec]`](crate::macros::aztec::aztec) macro automatically creates a correct implementation of this function\n/// for each contract called `_compute_note_nullifier`. It dispatches on `note_type_id` similarly to\n/// [`ComputeNoteHash`], then calls the note's\n/// [`compute_nullifier_unconstrained`](crate::note::note_interface::NoteHash::compute_nullifier_unconstrained) method.\npub type ComputeNoteNullifier = unconstrained fn(/* unique_note_hash */Field, /* packed_note */ BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n/* owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress,\n/* randomness */ Field) -> Option<Field>;\n\n/// Deprecated: use [`ComputeNoteHash`] and [`ComputeNoteNullifier`] instead.\npub type ComputeNoteHashAndNullifier<Env> = unconstrained fn[Env](/* packed_note */BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n/* owner */ AztecAddress, /* storage_slot */ Field, /* note_type_id */ Field, /* contract_address */ AztecAddress,\n/*randomness */ Field, /* note nonce */ Field) -> Option<NoteHashAndNullifier>;\n\n/// A handler for custom messages.\n///\n/// Contracts that emit custom messages (i.e. any with a message type that is not in [`crate::messages::msg_type`])\n/// need to use [`crate::macros::AztecConfig::custom_message_handler`] with a function of this type in order to\n/// process them. They will otherwise be **silently ignored**.\npub type CustomMessageHandler<Env> = unconstrained fn[Env](\n/* contract_address */AztecAddress,\n/* msg_type_id */ u64,\n/* msg_metadata */ u64,\n/* msg_content */ BoundedVec<Field, MAX_MESSAGE_CONTENT_LEN>,\n/* message_context */ MessageContext,\n/* scope */ AztecAddress);\n\n/// Synchronizes the contract's private state with the network.\n///\n/// As blocks are mined, it is possible for a contract's private state to change (e.g. with new notes being created),\n/// but because these changes are private they will be invisible to most actors. This is the function that processes\n/// new transactions in order to discover new notes, events, and other kinds of private state changes.\n///\n/// The private state will be synchronized up to the block that will be used for private transactions (i.e. the anchor\n/// block. This will typically be close to the tip of the chain.\npub unconstrained fn do_sync_state<CustomMessageHandlerEnv>(\n contract_address: AztecAddress,\n compute_note_hash: ComputeNoteHash,\n compute_note_nullifier: ComputeNoteNullifier,\n process_custom_message: Option<CustomMessageHandler<CustomMessageHandlerEnv>>,\n offchain_inbox_sync: Option<OffchainInboxSync<()>>,\n scope: AztecAddress,\n) {\n aztecnr_debug_log!(\"Performing state synchronization\");\n\n // First we process all private logs, which can contain different kinds of messages e.g. private notes, partial\n // notes, private events, etc.\n let logs = get_private_logs(contract_address, scope);\n logs.for_each(|i, pending_tagged_log: PendingTaggedLog| {\n if pending_tagged_log.log.len() == 0 {\n aztecnr_warn_log_format!(\"Skipping empty log from tx {0}\")([pending_tagged_log.context.tx_hash]);\n } else {\n aztecnr_debug_log_format!(\"Processing log with tag {0}\")([pending_tagged_log.log.get(0)]);\n\n // We remove the tag from the pending tagged log and process the message ciphertext contained in it.\n let message_ciphertext = array::subbvec(pending_tagged_log.log, 1);\n\n process_message_ciphertext(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n process_custom_message,\n message_ciphertext,\n pending_tagged_log.context,\n scope,\n );\n }\n\n // We need to delete each log from the array so that we won't process them again. `CapsuleArray::for_each`\n // allows deletion of the current element during iteration, so this is safe.\n // Note that this (and all other database changes) will only be committed if contract execution succeeds,\n // including any enqueued validation requests.\n logs.remove(i);\n });\n\n if offchain_inbox_sync.is_some() {\n let msgs: CapsuleArray<OffchainMessageWithContext> = offchain_inbox_sync.unwrap()(contract_address, scope);\n msgs.for_each(|i, msg| {\n process_message_ciphertext(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n process_custom_message,\n msg.message_ciphertext,\n msg.message_context,\n scope,\n );\n // The inbox sync returns _a copy_ of messages to process, so we clear them as we do so. This is a\n // volatile array with the to-process message, not the actual persistent storage of them.\n msgs.remove(i);\n });\n }\n\n // Then we process all pending partial notes, regardless of whether they were found in the current or previous\n // executions.\n partial_notes::fetch_and_process_partial_note_completion_logs(\n contract_address,\n compute_note_hash,\n compute_note_nullifier,\n scope,\n );\n\n // Finally we validate all notes and events that were found as part of the previous processes, resulting in them\n // being added to PXE's database and retrievable via oracles (get_notes) and our TS API (PXE::getPrivateEvents).\n validate_and_store_enqueued_notes_and_events(contract_address, scope);\n}\n\nmod test {\n use crate::{\n capsules::CapsuleArray,\n messages::{\n discovery::{CustomMessageHandler, do_sync_state},\n logs::note::MAX_NOTE_PACKED_LEN,\n processing::{\n offchain::OffchainInboxSync, pending_tagged_log::PendingTaggedLog, PENDING_TAGGED_LOG_ARRAY_BASE_SLOT,\n },\n },\n test::helpers::test_environment::TestEnvironment,\n };\n use crate::protocol::address::AztecAddress;\n\n #[test]\n unconstrained fn do_sync_state_does_not_panic_on_empty_logs() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n\n let contract_address = AztecAddress { inner: 0xdeadbeef };\n\n env.utility_context_at(contract_address, |_| {\n let base_slot = PENDING_TAGGED_LOG_ARRAY_BASE_SLOT;\n\n let logs: CapsuleArray<PendingTaggedLog> = CapsuleArray::at(contract_address, base_slot, scope);\n logs.push(PendingTaggedLog { log: BoundedVec::new(), context: std::mem::zeroed() });\n assert_eq(logs.len(), 1);\n\n let no_handler: Option<CustomMessageHandler<()>> = Option::none();\n let no_inbox_sync: Option<OffchainInboxSync<()>> = Option::none();\n do_sync_state(\n contract_address,\n dummy_compute_note_hash,\n dummy_compute_note_nullifier,\n no_handler,\n no_inbox_sync,\n scope,\n );\n\n assert_eq(logs.len(), 0);\n });\n }\n\n unconstrained fn dummy_compute_note_hash(\n _packed_note: BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n _owner: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _contract_address: AztecAddress,\n _randomness: Field,\n ) -> Option<Field> {\n Option::none()\n }\n\n unconstrained fn dummy_compute_note_nullifier(\n _unique_note_hash: Field,\n _packed_note: BoundedVec<Field, MAX_NOTE_PACKED_LEN>,\n _owner: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _contract_address: AztecAddress,\n _randomness: Field,\n ) -> Option<Field> {\n Option::none()\n }\n}\n"
3237
3237
  },
3238
3238
  "128": {
3239
3239
  "function_locations": [
@@ -3501,23 +3501,23 @@
3501
3501
  },
3502
3502
  {
3503
3503
  "name": "decode_private_event_message",
3504
- "start": 3578
3504
+ "start": 3755
3505
3505
  },
3506
3506
  {
3507
3507
  "name": "test::encode_decode",
3508
- "start": 4950
3508
+ "start": 5127
3509
3509
  },
3510
3510
  {
3511
3511
  "name": "test::decode_empty_content_returns_none",
3512
- "start": 5692
3512
+ "start": 5869
3513
3513
  },
3514
3514
  {
3515
3515
  "name": "test::decode_with_only_reserved_fields_returns_none",
3516
- "start": 5887
3516
+ "start": 6064
3517
3517
  }
3518
3518
  ],
3519
3519
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/messages/logs/event.nr",
3520
- "source": "use crate::{\n event::{event_interface::EventInterface, EventSelector},\n messages::{\n encoding::{encode_message, MAX_MESSAGE_CONTENT_LEN, MESSAGE_EXPANDED_METADATA_LEN},\n msg_type::PRIVATE_EVENT_MSG_TYPE_ID,\n },\n utils::array,\n};\nuse crate::protocol::traits::{FromField, Serialize, ToField};\n\n/// The number of fields in a private event message content that are not the event's serialized representation (1 field\n/// for randomness).\npub(crate) global PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN: u32 = 1;\npub(crate) global PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX: u32 = 0;\n\n/// The maximum length of the packed representation of an event's contents. This is limited by private log size,\n/// encryption overhead and extra fields in the message (e.g. message type id, randomness, etc.).\npub global MAX_EVENT_SERIALIZED_LEN: u32 = MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN;\n\n/// Creates the plaintext for a private event message (i.e. one of type [`PRIVATE_EVENT_MSG_TYPE_ID`]).\n///\n/// This plaintext is meant to be decoded via [`decode_private_event_message`].\npub fn encode_private_event_message<Event>(\n event: Event,\n randomness: Field,\n) -> [Field; PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + <Event as Serialize>::N + MESSAGE_EXPANDED_METADATA_LEN]\nwhere\n Event: EventInterface + Serialize,\n{\n // We use `Serialize` because we want for events to be processable by off-chain actors, e.g. block explorers,\n // wallets and apps, without having to rely on contract invocation. If we used `Packable` we'd need to call utility\n // functions in order to unpack events, which would introduce a level of complexity we don't currently think is\n // worth the savings in DA (for public events) and proving time (when encrypting private event messages).\n let serialized_event = event.serialize();\n\n // If PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN is changed, causing the assertion below to fail, then the\n // encoding below must be updated as well.\n std::static_assert(\n PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN == 1,\n \"unexpected value for PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN\",\n );\n\n let mut msg_plaintext = [0; PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + <Event as Serialize>::N];\n msg_plaintext[PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX] = randomness;\n\n for i in 0..serialized_event.len() {\n msg_plaintext[PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + i] = serialized_event[i];\n }\n\n // The event type id is stored in the message metadata\n encode_message(\n PRIVATE_EVENT_MSG_TYPE_ID,\n Event::get_event_type_id().to_field() as u64,\n msg_plaintext,\n )\n}\n\n/// Decodes the plaintext from a private event message (i.e. one of type [`PRIVATE_EVENT_MSG_TYPE_ID`]).\n///\n/// Returns `None` if `msg_content` has too few fields. This plaintext is meant to have originated\n/// from [`encode_private_event_message`].\n///\n/// Note that while [`encode_private_event_message`] returns a fixed-size array, this function takes a [`BoundedVec`]\n/// instead. This is because when decoding we're typically processing runtime-sized plaintexts, more specifically,\n/// those that originate from [`crate::messages::encryption::message_encryption::MessageEncryption::decrypt`].\npub(crate) unconstrained fn decode_private_event_message(\n msg_metadata: u64,\n msg_content: BoundedVec<Field, MAX_MESSAGE_CONTENT_LEN>,\n) -> Option<(EventSelector, Field, BoundedVec<Field, MAX_EVENT_SERIALIZED_LEN>)> {\n if msg_content.len() <= PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN {\n Option::none()\n } else {\n let event_type_id = EventSelector::from_field(msg_metadata as Field);\n\n // If PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN is changed, causing the assertion below to fail, then the\n // destructuring of the private event message encoding below must be updated as well.\n std::static_assert(\n PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN == 1,\n \"unexpected value for PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN\",\n );\n\n let randomness = msg_content.get(PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX);\n let serialized_event = array::subbvec(msg_content, PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN);\n\n Option::some((event_type_id, randomness, serialized_event))\n }\n}\n\nmod test {\n use crate::{\n event::event_interface::EventInterface,\n messages::{\n encoding::decode_message,\n logs::event::{decode_private_event_message, encode_private_event_message},\n msg_type::PRIVATE_EVENT_MSG_TYPE_ID,\n },\n };\n use crate::protocol::traits::Serialize;\n use crate::test::mocks::mock_event::MockEvent;\n\n global VALUE: Field = 7;\n global RANDOMNESS: Field = 10;\n\n #[test]\n unconstrained fn encode_decode() {\n let event = MockEvent::new(VALUE).build_event();\n\n let message_plaintext = encode_private_event_message(event, RANDOMNESS);\n\n let (msg_type_id, msg_metadata, msg_content) =\n decode_message(BoundedVec::from_array(message_plaintext)).unwrap();\n\n assert_eq(msg_type_id, PRIVATE_EVENT_MSG_TYPE_ID);\n\n let (event_type_id, randomness, serialized_event) =\n decode_private_event_message(msg_metadata, msg_content).unwrap();\n\n assert_eq(event_type_id, MockEvent::get_event_type_id());\n assert_eq(randomness, RANDOMNESS);\n assert_eq(serialized_event, BoundedVec::from_array(event.serialize()));\n }\n\n #[test]\n unconstrained fn decode_empty_content_returns_none() {\n let empty = BoundedVec::new();\n assert(decode_private_event_message(0, empty).is_none());\n }\n\n #[test]\n unconstrained fn decode_with_only_reserved_fields_returns_none() {\n let content = BoundedVec::from_array([0]);\n assert(decode_private_event_message(0, content).is_none());\n }\n}\n"
3520
+ "source": "use crate::{\n event::{event_interface::EventInterface, EventSelector},\n messages::{\n encoding::{encode_message, MAX_MESSAGE_CONTENT_LEN, MESSAGE_EXPANDED_METADATA_LEN},\n msg_type::PRIVATE_EVENT_MSG_TYPE_ID,\n },\n utils::array,\n};\nuse crate::protocol::traits::{FromField, Serialize, ToField};\n\n/// The number of fields in a private event message content that are not the event's serialized representation (1 field\n/// for randomness).\npub(crate) global PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN: u32 = 1;\npub(crate) global PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX: u32 = 0;\n\n/// The maximum length of the packed representation of an event's contents. This is limited by private log size,\n/// encryption overhead and extra fields in the message (e.g. message type id, randomness, etc.).\npub global MAX_EVENT_SERIALIZED_LEN: u32 = MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN;\n\n/// Creates the plaintext for a private event message (i.e. one of type [`PRIVATE_EVENT_MSG_TYPE_ID`]).\n///\n/// This plaintext is meant to be decoded via [`decode_private_event_message`].\npub fn encode_private_event_message<Event>(\n event: Event,\n randomness: Field,\n) -> [Field; PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + <Event as Serialize>::N + MESSAGE_EXPANDED_METADATA_LEN]\nwhere\n Event: EventInterface + Serialize,\n{\n std::static_assert(\n <Event as Serialize>::N <= MAX_EVENT_SERIALIZED_LEN,\n \"event's serialized length exceeds the maximum allowed for private events\",\n );\n\n // We use `Serialize` because we want for events to be processable by off-chain actors, e.g. block explorers,\n // wallets and apps, without having to rely on contract invocation. If we used `Packable` we'd need to call utility\n // functions in order to unpack events, which would introduce a level of complexity we don't currently think is\n // worth the savings in DA (for public events) and proving time (when encrypting private event messages).\n let serialized_event = event.serialize();\n\n // If PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN is changed, causing the assertion below to fail, then the\n // encoding below must be updated as well.\n std::static_assert(\n PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN == 1,\n \"unexpected value for PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN\",\n );\n\n let mut msg_plaintext = [0; PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + <Event as Serialize>::N];\n msg_plaintext[PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX] = randomness;\n\n for i in 0..serialized_event.len() {\n msg_plaintext[PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN + i] = serialized_event[i];\n }\n\n // The event type id is stored in the message metadata\n encode_message(\n PRIVATE_EVENT_MSG_TYPE_ID,\n Event::get_event_type_id().to_field() as u64,\n msg_plaintext,\n )\n}\n\n/// Decodes the plaintext from a private event message (i.e. one of type [`PRIVATE_EVENT_MSG_TYPE_ID`]).\n///\n/// Returns `None` if `msg_content` has too few fields. This plaintext is meant to have originated\n/// from [`encode_private_event_message`].\n///\n/// Note that while [`encode_private_event_message`] returns a fixed-size array, this function takes a [`BoundedVec`]\n/// instead. This is because when decoding we're typically processing runtime-sized plaintexts, more specifically,\n/// those that originate from [`crate::messages::encryption::message_encryption::MessageEncryption::decrypt`].\npub(crate) unconstrained fn decode_private_event_message(\n msg_metadata: u64,\n msg_content: BoundedVec<Field, MAX_MESSAGE_CONTENT_LEN>,\n) -> Option<(EventSelector, Field, BoundedVec<Field, MAX_EVENT_SERIALIZED_LEN>)> {\n if msg_content.len() <= PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN {\n Option::none()\n } else {\n let event_type_id = EventSelector::from_field(msg_metadata as Field);\n\n // If PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN is changed, causing the assertion below to fail, then the\n // destructuring of the private event message encoding below must be updated as well.\n std::static_assert(\n PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN == 1,\n \"unexpected value for PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN\",\n );\n\n let randomness = msg_content.get(PRIVATE_EVENT_MSG_PLAINTEXT_RANDOMNESS_INDEX);\n let serialized_event = array::subbvec(msg_content, PRIVATE_EVENT_MSG_PLAINTEXT_RESERVED_FIELDS_LEN);\n\n Option::some((event_type_id, randomness, serialized_event))\n }\n}\n\nmod test {\n use crate::{\n event::event_interface::EventInterface,\n messages::{\n encoding::decode_message,\n logs::event::{decode_private_event_message, encode_private_event_message},\n msg_type::PRIVATE_EVENT_MSG_TYPE_ID,\n },\n };\n use crate::protocol::traits::Serialize;\n use crate::test::mocks::mock_event::MockEvent;\n\n global VALUE: Field = 7;\n global RANDOMNESS: Field = 10;\n\n #[test]\n unconstrained fn encode_decode() {\n let event = MockEvent::new(VALUE).build_event();\n\n let message_plaintext = encode_private_event_message(event, RANDOMNESS);\n\n let (msg_type_id, msg_metadata, msg_content) =\n decode_message(BoundedVec::from_array(message_plaintext)).unwrap();\n\n assert_eq(msg_type_id, PRIVATE_EVENT_MSG_TYPE_ID);\n\n let (event_type_id, randomness, serialized_event) =\n decode_private_event_message(msg_metadata, msg_content).unwrap();\n\n assert_eq(event_type_id, MockEvent::get_event_type_id());\n assert_eq(randomness, RANDOMNESS);\n assert_eq(serialized_event, BoundedVec::from_array(event.serialize()));\n }\n\n #[test]\n unconstrained fn decode_empty_content_returns_none() {\n let empty = BoundedVec::new();\n assert(decode_private_event_message(0, empty).is_none());\n }\n\n #[test]\n unconstrained fn decode_with_only_reserved_fields_returns_none() {\n let content = BoundedVec::from_array([0]);\n assert(decode_private_event_message(0, content).is_none());\n }\n}\n"
3521
3521
  },
3522
3522
  "141": {
3523
3523
  "function_locations": [
@@ -3627,45 +3627,49 @@
3627
3627
  "name": "sync_inbox",
3628
3628
  "start": 6983
3629
3629
  },
3630
+ {
3631
+ "name": "test::setup",
3632
+ "start": 11875
3633
+ },
3630
3634
  {
3631
3635
  "name": "test::make_msg",
3632
- "start": 12050
3636
+ "start": 12205
3633
3637
  },
3634
3638
  {
3635
3639
  "name": "test::advance_by",
3636
- "start": 12340
3640
+ "start": 12488
3637
3641
  },
3638
3642
  {
3639
3643
  "name": "test::empty_inbox_returns_empty_result",
3640
- "start": 12531
3644
+ "start": 12679
3641
3645
  },
3642
3646
  {
3643
3647
  "name": "test::tx_bound_msg_expires_after_max_msg_ttl",
3644
- "start": 13000
3648
+ "start": 13142
3645
3649
  },
3646
3650
  {
3647
3651
  "name": "test::tx_bound_msg_not_expired_before_max_msg_ttl",
3648
- "start": 13964
3652
+ "start": 14107
3649
3653
  },
3650
3654
  {
3651
3655
  "name": "test::tx_less_msg_expires_after_max_msg_ttl",
3652
- "start": 14921
3656
+ "start": 15065
3653
3657
  },
3654
3658
  {
3655
3659
  "name": "test::unresolved_tx_stays_in_inbox",
3656
- "start": 15862
3660
+ "start": 16007
3657
3661
  },
3658
3662
  {
3659
3663
  "name": "test::multiple_messages_mixed_expiration",
3660
- "start": 16755
3664
+ "start": 16901
3661
3665
  },
3662
3666
  {
3663
3667
  "name": "test::resolved_msg_is_ready_to_process",
3664
- "start": 18479
3668
+ "start": 18640
3665
3669
  }
3666
3670
  ],
3667
3671
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/messages/processing/offchain.nr",
3668
- "source": "use crate::{\n capsules::CapsuleArray,\n context::UtilityContext,\n messages::{\n encoding::MESSAGE_CIPHERTEXT_LEN,\n processing::{get_message_contexts_by_tx_hash, MessageContext, OffchainMessageWithContext},\n },\n oracle::contract_sync::set_contract_sync_cache_invalid,\n protocol::{\n address::AztecAddress,\n constants::MAX_TX_LIFETIME,\n hash::sha256_to_field,\n traits::{Deserialize, Serialize},\n },\n};\n\n/// Base capsule slot for the persistent inbox of [`PendingOffchainMsg`] entries.\n///\n/// This is the slot where we accumulate messages received through [`receive`].\nglobal OFFCHAIN_INBOX_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_INBOX_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to pass tx hash resolution requests to PXE.\nglobal OFFCHAIN_CONTEXT_REQUESTS_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_CONTEXT_REQUESTS_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to read tx context responses from PXE.\nglobal OFFCHAIN_CONTEXT_RESPONSES_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_CONTEXT_RESPONSES_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to collect messages ready for processing.\nglobal OFFCHAIN_READY_MESSAGES_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_READY_MESSAGES_SLOT\".as_bytes());\n\n/// Maximum number of offchain messages accepted by `offchain_receive` in a single call.\npub global MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL: u32 = 16;\n\n/// Tolerance added to the `MAX_TX_LIFETIME` cap for message expiration.\nglobal TX_EXPIRATION_TOLERANCE: u64 = 7200; // 2 hours\n\n/// Maximum time-to-live for a tx-bound offchain message.\n///\n/// After `anchor_block_timestamp + MAX_MSG_TTL`, the message is evicted from the inbox.\nglobal MAX_MSG_TTL: u64 = MAX_TX_LIFETIME + TX_EXPIRATION_TOLERANCE;\n\n/// A function that manages offchain-delivered messages for processing during sync.\n///\n/// Offchain messages are messages that are not broadcasted via onchain logs. They are instead delivered to the\n/// recipient by calling the `offchain_receive` utility function (injected by the `#[aztec]` macro). Message transport\n/// is the app's responsibility. Typical examples of transport methods are: messaging apps, email, QR codes, etc.\n///\n/// Once offchain messages are delivered to the recipient's private environment via `offchain_receive`, messages are\n/// locally stored in a persistent inbox.\n///\n/// This function determines when each message in said inbox is ready for processing, when it can be safely disposed\n/// of, etc.\n///\n/// The only current implementation of an `OffchainInboxSync` is [`sync_inbox`], which manages an inbox with expiration\n/// based eviction and automatic transaction context resolution.\npub(crate) type OffchainInboxSync<Env> = unconstrained fn[Env](\n/* contract_address */AztecAddress, /* scope */ AztecAddress) -> CapsuleArray<OffchainMessageWithContext>;\n\n/// A message delivered via the `offchain_receive` utility function.\npub struct OffchainMessage {\n /// The encrypted message payload.\n pub ciphertext: BoundedVec<Field, MESSAGE_CIPHERTEXT_LEN>,\n /// The intended recipient of the message.\n pub recipient: AztecAddress,\n /// The hash of the transaction that produced this message. `Option::none` indicates a tx-less message.\n pub tx_hash: Option<Field>,\n /// Anchor block timestamp at message emission.\n pub anchor_block_timestamp: u64,\n}\n\n/// An offchain message awaiting processing (or re-processing) in the inbox.\n///\n/// Messages remain in the inbox until they expire, even if they have already been processed. This is necessary to\n/// handle reorgs: a processed message may need to be re-processed if the transaction that provided its context is\n/// reverted. On each sync, resolved messages are promoted to [`OffchainMessageWithContext`] for processing.\n#[derive(Serialize, Deserialize)]\nstruct PendingOffchainMsg {\n /// The encrypted message payload.\n ciphertext: BoundedVec<Field, MESSAGE_CIPHERTEXT_LEN>,\n /// The intended recipient of the message.\n recipient: AztecAddress,\n /// The hash of the transaction that produced this message. A value of 0 indicates a tx-less message.\n tx_hash: Field,\n /// Anchor block timestamp at message emission. Used to compute the effective expiration: messages are evicted\n /// after `anchor_block_timestamp + MAX_MSG_TTL`.\n anchor_block_timestamp: u64,\n}\n\n/// Delivers offchain messages to the given contract's offchain inbox for subsequent processing.\n///\n/// Offchain messages are transaction effects that are not broadcasted via onchain logs. Instead, the sender shares the\n/// message to the recipient through an external channel (e.g. a URL accessible by the recipient). The recipient then\n/// calls this function to hand the messages to the contract so they can be processed through the same mechanisms as\n/// onchain messages.\n///\n/// Each message is routed to the inbox scoped to its `recipient` field, so messages for different accounts are\n/// automatically isolated.\n///\n/// Messages are processed when their originating transaction is found onchain (providing the context needed to\n/// validate resulting notes and events).\n///\n/// Messages are kept in the inbox until they expire. The effective expiration is\n/// `anchor_block_timestamp + MAX_MSG_TTL`.\n///\n/// Processing order is not guaranteed.\npub unconstrained fn receive(\n contract_address: AztecAddress,\n messages: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL>,\n) {\n // May contain duplicates if multiple messages target the same recipient. This is harmless since\n // cache invalidation on the TS side is idempotent (deleting an already-deleted key is a no-op).\n let mut scopes: BoundedVec<AztecAddress, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n let mut i = 0;\n let messages_len = messages.len();\n while i < messages_len {\n let msg = messages.get(i);\n let tx_hash = if msg.tx_hash.is_some() {\n msg.tx_hash.unwrap()\n } else {\n 0\n };\n let inbox: CapsuleArray<PendingOffchainMsg> =\n CapsuleArray::at(contract_address, OFFCHAIN_INBOX_SLOT, msg.recipient);\n inbox.push(\n PendingOffchainMsg {\n ciphertext: msg.ciphertext,\n recipient: msg.recipient,\n tx_hash,\n anchor_block_timestamp: msg.anchor_block_timestamp,\n },\n );\n scopes.push(msg.recipient);\n i += 1;\n }\n\n set_contract_sync_cache_invalid(contract_address, scopes);\n}\n\n/// Returns offchain-delivered messages to process during sync.\n///\n/// Messages remain in the inbox and are reprocessed on each sync until their originating transaction is no longer at\n/// risk of being dropped by a reorg.\npub unconstrained fn sync_inbox(\n contract_address: AztecAddress,\n scope: AztecAddress,\n) -> CapsuleArray<OffchainMessageWithContext> {\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(contract_address, OFFCHAIN_INBOX_SLOT, scope);\n let context_resolution_requests: CapsuleArray<Field> =\n CapsuleArray::at(contract_address, OFFCHAIN_CONTEXT_REQUESTS_SLOT, scope);\n let resolved_contexts: CapsuleArray<Option<MessageContext>> =\n CapsuleArray::at(contract_address, OFFCHAIN_CONTEXT_RESPONSES_SLOT, scope);\n let ready_to_process: CapsuleArray<OffchainMessageWithContext> =\n CapsuleArray::at(contract_address, OFFCHAIN_READY_MESSAGES_SLOT, scope);\n\n // Clear any stale ready messages from a previous run.\n ready_to_process.for_each(|i, _| { ready_to_process.remove(i); });\n\n // Clear any stale context resolution requests/responses from a previous run.\n context_resolution_requests.for_each(|i, _| { context_resolution_requests.remove(i); });\n resolved_contexts.for_each(|i, _| { resolved_contexts.remove(i); });\n\n // Build a request list aligned with the inbox indices.\n let mut i = 0;\n let inbox_len = inbox.len();\n while i < inbox_len {\n let msg = inbox.get(i);\n context_resolution_requests.push(msg.tx_hash);\n i += 1;\n }\n\n // Ask PXE to resolve contexts for all requested tx hashes.\n get_message_contexts_by_tx_hash(\n contract_address,\n OFFCHAIN_CONTEXT_REQUESTS_SLOT,\n OFFCHAIN_CONTEXT_RESPONSES_SLOT,\n scope,\n );\n\n assert_eq(resolved_contexts.len(), inbox_len);\n\n let now = UtilityContext::new().timestamp();\n\n let mut j = inbox_len;\n while j > 0 {\n // This loop decides what to do with each message in the offchain message inbox. We need to handle 3\n // different scenarios for each message.\n //\n // 1. The TX that emitted this message is still not known to PXE: in this case we can't yet process this\n // message, as any notes or events discovered will fail to be validated. So we leave the message in the inbox,\n // awaiting for future syncs to detect that the TX became available.\n //\n // 2. The message is not associated to a TX to begin with. The current version of offchain message processing\n // does not support this case, but in the future it will. Right now, a message without an associated TX will\n // sit in the inbox until it expires.\n //\n // 3. The TX that emitted this message has been found by PXE. That gives us all the information needed to\n // process the message. We add the message to the `ready_to_process` CapsuleArray so that the `sync_state` loop\n // processes it.\n //\n // In all cases, if the message has expired (i.e. `now > anchor_block_timestamp + MAX_MSG_TTL`), we remove it\n // from the inbox.\n //\n // Note: the loop runs backwards because it might call `inbox.remove(j)` to purge expired messages and we also\n // need to align it with `resolved_contexts.get(j)`. Going from last to first simplifies the algorithm as\n // not yet visited element indexes remain stable.\n j -= 1;\n let maybe_ctx = resolved_contexts.get(j);\n let msg = inbox.get(j);\n\n // Compute the message's effective expiration timestamp to determine if we can purge it from the inbox.\n let effective_expiration = msg.anchor_block_timestamp + MAX_MSG_TTL;\n\n // Message expired. We remove it from the inbox.\n if now > effective_expiration {\n inbox.remove(j);\n }\n\n // Scenario 1: associated TX not yet available. We keep the message in the inbox, as it might become\n // processable as new blocks get mined.\n // Scenario 2: no TX associated to message. The message will sit in the inbox until it expires.\n if maybe_ctx.is_none() {\n continue;\n }\n\n // Scenario 3: Message is ready to process, add to result array. Note we still keep it in the inbox unless we\n // consider it has expired: this is because we need to account for reorgs. If reorg occurs after we processed\n // a message, the effects of processing the message get rewind. However, the associated TX can be included in\n // a subsequent block. Should that happen, the message must be re-processed to ensure consistency.\n let message_context = maybe_ctx.unwrap();\n ready_to_process.push(OffchainMessageWithContext { message_ciphertext: msg.ciphertext, message_context });\n }\n\n ready_to_process\n}\n\nmod test {\n use crate::{\n capsules::CapsuleArray, oracle::random::random, protocol::address::AztecAddress,\n test::helpers::test_environment::TestEnvironment,\n };\n use super::{\n MAX_MSG_TTL, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL, OFFCHAIN_INBOX_SLOT, OffchainMessage, PendingOffchainMsg,\n receive, sync_inbox,\n };\n\n global SCOPE: AztecAddress = AztecAddress { inner: 0xcafe };\n\n /// Creates an `OffchainMessage` with dummy ciphertext and `SCOPE` as recipient.\n fn make_msg(tx_hash: Option<Field>, anchor_block_timestamp: u64) -> OffchainMessage {\n OffchainMessage { ciphertext: BoundedVec::new(), recipient: SCOPE, tx_hash, anchor_block_timestamp }\n }\n\n /// Advances the TXE block timestamp by `offset` seconds and returns the resulting timestamp.\n unconstrained fn advance_by(env: TestEnvironment, offset: u64) -> u64 {\n env.advance_next_block_timestamp_by(offset);\n env.mine_block();\n env.last_block_timestamp()\n }\n\n #[test]\n unconstrained fn empty_inbox_returns_empty_result() {\n let env = TestEnvironment::new();\n env.utility_context(|context| {\n let result = sync_inbox(context.this_address(), SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> =\n CapsuleArray::at(context.this_address(), OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0);\n assert_eq(inbox.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn tx_bound_msg_expires_after_max_msg_ttl() {\n let env = TestEnvironment::new();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, MAX_MSG_TTL + 1);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 0); // expired, removed\n });\n }\n\n #[test]\n unconstrained fn tx_bound_msg_not_expired_before_max_msg_ttl() {\n let env = TestEnvironment::new();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance, but not past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 1); // not expired, stays\n });\n }\n\n #[test]\n unconstrained fn tx_less_msg_expires_after_max_msg_ttl() {\n let env = TestEnvironment::new();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(Option::none(), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, MAX_MSG_TTL + 1);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 0); // expired, removed\n });\n }\n\n #[test]\n unconstrained fn unresolved_tx_stays_in_inbox() {\n let env = TestEnvironment::new();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0); // not resolved, not ready\n assert_eq(inbox.len(), 1); // not expired, stays\n });\n }\n\n #[test]\n unconstrained fn multiple_messages_mixed_expiration() {\n let env = TestEnvironment::new();\n let anchor_ts = advance_by(env, 10);\n\n let survivor_tx_hash = random();\n\n env.utility_context(|context| {\n let address = context.this_address();\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n // Message 0: tx-bound, anchor_ts in the past so it expires at\n // anchor_ts + MAX_MSG_TTL. We set anchor to 0 so it expires quickly.\n msgs.push(make_msg(Option::some(random()), 0));\n // Message 1: tx-bound, anchor_ts is recent so it survives.\n msgs.push(make_msg(Option::some(survivor_tx_hash), anchor_ts));\n // Message 2: tx-less, anchor_ts=0 so it also expires.\n msgs.push(make_msg(Option::none(), 0));\n receive(address, msgs);\n });\n\n // Advance past MAX_MSG_TTL for anchor_ts=0, but not for anchor_ts=anchor_ts.\n let _now = advance_by(env, MAX_MSG_TTL);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n assert_eq(result.len(), 0); // all contexts are None\n // Message 0 expired (anchor=0), message 1 survived (anchor=anchor_ts),\n // Message 2 expired (anchor=0).\n assert_eq(inbox.len(), 1);\n assert_eq(inbox.get(0).tx_hash, survivor_tx_hash);\n });\n }\n\n // -- Resolved context (ready to process) ------------------------------\n\n #[test]\n unconstrained fn resolved_msg_is_ready_to_process() {\n let env = TestEnvironment::new();\n // TestEnvironment::new() deploys protocol contracts, creating blocks with tx effects.\n // In TXE, tx hashes equal Fr(blockNumber), so Fr(1) is the tx effect from block 1.\n // We use this as a \"known resolvable\" tx hash.\n let known_tx_hash: Field = 1;\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(Option::some(known_tx_hash), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, SCOPE);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, SCOPE);\n\n // The message should be ready to process since its tx context was resolved.\n assert_eq(result.len(), 1);\n\n let ctx = result.get(0).message_context;\n assert_eq(ctx.tx_hash, known_tx_hash);\n assert(ctx.first_nullifier_in_tx != 0, \"resolved context must have a first nullifier\");\n\n // Message stays in inbox (not expired) for potential reorg reprocessing.\n assert_eq(inbox.len(), 1);\n });\n }\n}\n"
3672
+ "source": "use crate::{\n capsules::CapsuleArray,\n context::UtilityContext,\n messages::{\n encoding::MESSAGE_CIPHERTEXT_LEN,\n processing::{get_message_contexts_by_tx_hash, MessageContext, OffchainMessageWithContext},\n },\n oracle::contract_sync::set_contract_sync_cache_invalid,\n protocol::{\n address::AztecAddress,\n constants::MAX_TX_LIFETIME,\n hash::sha256_to_field,\n traits::{Deserialize, Serialize},\n },\n};\n\n/// Base capsule slot for the persistent inbox of [`PendingOffchainMsg`] entries.\n///\n/// This is the slot where we accumulate messages received through [`receive`].\nglobal OFFCHAIN_INBOX_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_INBOX_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to pass tx hash resolution requests to PXE.\nglobal OFFCHAIN_CONTEXT_REQUESTS_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_CONTEXT_REQUESTS_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to read tx context responses from PXE.\nglobal OFFCHAIN_CONTEXT_RESPONSES_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_CONTEXT_RESPONSES_SLOT\".as_bytes());\n\n/// Capsule array slot used by [`sync_inbox`] to collect messages ready for processing.\nglobal OFFCHAIN_READY_MESSAGES_SLOT: Field = sha256_to_field(\"AZTEC_NR::OFFCHAIN_READY_MESSAGES_SLOT\".as_bytes());\n\n/// Maximum number of offchain messages accepted by `offchain_receive` in a single call.\npub global MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL: u32 = 16;\n\n/// Tolerance added to the `MAX_TX_LIFETIME` cap for message expiration.\nglobal TX_EXPIRATION_TOLERANCE: u64 = 7200; // 2 hours\n\n/// Maximum time-to-live for a tx-bound offchain message.\n///\n/// After `anchor_block_timestamp + MAX_MSG_TTL`, the message is evicted from the inbox.\nglobal MAX_MSG_TTL: u64 = MAX_TX_LIFETIME + TX_EXPIRATION_TOLERANCE;\n\n/// A function that manages offchain-delivered messages for processing during sync.\n///\n/// Offchain messages are messages that are not broadcasted via onchain logs. They are instead delivered to the\n/// recipient by calling the `offchain_receive` utility function (injected by the `#[aztec]` macro). Message transport\n/// is the app's responsibility. Typical examples of transport methods are: messaging apps, email, QR codes, etc.\n///\n/// Once offchain messages are delivered to the recipient's private environment via `offchain_receive`, messages are\n/// locally stored in a persistent inbox.\n///\n/// This function determines when each message in said inbox is ready for processing, when it can be safely disposed\n/// of, etc.\n///\n/// The only current implementation of an `OffchainInboxSync` is [`sync_inbox`], which manages an inbox with expiration\n/// based eviction and automatic transaction context resolution.\npub(crate) type OffchainInboxSync<Env> = unconstrained fn[Env](\n/* contract_address */AztecAddress, /* scope */ AztecAddress) -> CapsuleArray<OffchainMessageWithContext>;\n\n/// A message delivered via the `offchain_receive` utility function.\npub struct OffchainMessage {\n /// The encrypted message payload.\n pub ciphertext: BoundedVec<Field, MESSAGE_CIPHERTEXT_LEN>,\n /// The intended recipient of the message.\n pub recipient: AztecAddress,\n /// The hash of the transaction that produced this message. `Option::none` indicates a tx-less message.\n pub tx_hash: Option<Field>,\n /// Anchor block timestamp at message emission.\n pub anchor_block_timestamp: u64,\n}\n\n/// An offchain message awaiting processing (or re-processing) in the inbox.\n///\n/// Messages remain in the inbox until they expire, even if they have already been processed. This is necessary to\n/// handle reorgs: a processed message may need to be re-processed if the transaction that provided its context is\n/// reverted. On each sync, resolved messages are promoted to [`OffchainMessageWithContext`] for processing.\n#[derive(Serialize, Deserialize)]\nstruct PendingOffchainMsg {\n /// The encrypted message payload.\n ciphertext: BoundedVec<Field, MESSAGE_CIPHERTEXT_LEN>,\n /// The intended recipient of the message.\n recipient: AztecAddress,\n /// The hash of the transaction that produced this message. A value of 0 indicates a tx-less message.\n tx_hash: Field,\n /// Anchor block timestamp at message emission. Used to compute the effective expiration: messages are evicted\n /// after `anchor_block_timestamp + MAX_MSG_TTL`.\n anchor_block_timestamp: u64,\n}\n\n/// Delivers offchain messages to the given contract's offchain inbox for subsequent processing.\n///\n/// Offchain messages are transaction effects that are not broadcasted via onchain logs. Instead, the sender shares the\n/// message to the recipient through an external channel (e.g. a URL accessible by the recipient). The recipient then\n/// calls this function to hand the messages to the contract so they can be processed through the same mechanisms as\n/// onchain messages.\n///\n/// Each message is routed to the inbox scoped to its `recipient` field, so messages for different accounts are\n/// automatically isolated.\n///\n/// Messages are processed when their originating transaction is found onchain (providing the context needed to\n/// validate resulting notes and events).\n///\n/// Messages are kept in the inbox until they expire. The effective expiration is\n/// `anchor_block_timestamp + MAX_MSG_TTL`.\n///\n/// Processing order is not guaranteed.\npub unconstrained fn receive(\n contract_address: AztecAddress,\n messages: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL>,\n) {\n // May contain duplicates if multiple messages target the same recipient. This is harmless since\n // cache invalidation on the TS side is idempotent (deleting an already-deleted key is a no-op).\n let mut scopes: BoundedVec<AztecAddress, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n let mut i = 0;\n let messages_len = messages.len();\n while i < messages_len {\n let msg = messages.get(i);\n let tx_hash = if msg.tx_hash.is_some() {\n msg.tx_hash.unwrap()\n } else {\n 0\n };\n let inbox: CapsuleArray<PendingOffchainMsg> =\n CapsuleArray::at(contract_address, OFFCHAIN_INBOX_SLOT, msg.recipient);\n inbox.push(\n PendingOffchainMsg {\n ciphertext: msg.ciphertext,\n recipient: msg.recipient,\n tx_hash,\n anchor_block_timestamp: msg.anchor_block_timestamp,\n },\n );\n scopes.push(msg.recipient);\n i += 1;\n }\n\n set_contract_sync_cache_invalid(contract_address, scopes);\n}\n\n/// Returns offchain-delivered messages to process during sync.\n///\n/// Messages remain in the inbox and are reprocessed on each sync until their originating transaction is no longer at\n/// risk of being dropped by a reorg.\npub unconstrained fn sync_inbox(\n contract_address: AztecAddress,\n scope: AztecAddress,\n) -> CapsuleArray<OffchainMessageWithContext> {\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(contract_address, OFFCHAIN_INBOX_SLOT, scope);\n let context_resolution_requests: CapsuleArray<Field> =\n CapsuleArray::at(contract_address, OFFCHAIN_CONTEXT_REQUESTS_SLOT, scope);\n let resolved_contexts: CapsuleArray<Option<MessageContext>> =\n CapsuleArray::at(contract_address, OFFCHAIN_CONTEXT_RESPONSES_SLOT, scope);\n let ready_to_process: CapsuleArray<OffchainMessageWithContext> =\n CapsuleArray::at(contract_address, OFFCHAIN_READY_MESSAGES_SLOT, scope);\n\n // Clear any stale ready messages from a previous run.\n ready_to_process.for_each(|i, _| { ready_to_process.remove(i); });\n\n // Clear any stale context resolution requests/responses from a previous run.\n context_resolution_requests.for_each(|i, _| { context_resolution_requests.remove(i); });\n resolved_contexts.for_each(|i, _| { resolved_contexts.remove(i); });\n\n // Build a request list aligned with the inbox indices.\n let mut i = 0;\n let inbox_len = inbox.len();\n while i < inbox_len {\n let msg = inbox.get(i);\n context_resolution_requests.push(msg.tx_hash);\n i += 1;\n }\n\n // Ask PXE to resolve contexts for all requested tx hashes.\n get_message_contexts_by_tx_hash(\n contract_address,\n OFFCHAIN_CONTEXT_REQUESTS_SLOT,\n OFFCHAIN_CONTEXT_RESPONSES_SLOT,\n scope,\n );\n\n assert_eq(resolved_contexts.len(), inbox_len);\n\n let now = UtilityContext::new().timestamp();\n\n let mut j = inbox_len;\n while j > 0 {\n // This loop decides what to do with each message in the offchain message inbox. We need to handle 3\n // different scenarios for each message.\n //\n // 1. The TX that emitted this message is still not known to PXE: in this case we can't yet process this\n // message, as any notes or events discovered will fail to be validated. So we leave the message in the inbox,\n // awaiting for future syncs to detect that the TX became available.\n //\n // 2. The message is not associated to a TX to begin with. The current version of offchain message processing\n // does not support this case, but in the future it will. Right now, a message without an associated TX will\n // sit in the inbox until it expires.\n //\n // 3. The TX that emitted this message has been found by PXE. That gives us all the information needed to\n // process the message. We add the message to the `ready_to_process` CapsuleArray so that the `sync_state` loop\n // processes it.\n //\n // In all cases, if the message has expired (i.e. `now > anchor_block_timestamp + MAX_MSG_TTL`), we remove it\n // from the inbox.\n //\n // Note: the loop runs backwards because it might call `inbox.remove(j)` to purge expired messages and we also\n // need to align it with `resolved_contexts.get(j)`. Going from last to first simplifies the algorithm as\n // not yet visited element indexes remain stable.\n j -= 1;\n let maybe_ctx = resolved_contexts.get(j);\n let msg = inbox.get(j);\n\n // Compute the message's effective expiration timestamp to determine if we can purge it from the inbox.\n let effective_expiration = msg.anchor_block_timestamp + MAX_MSG_TTL;\n\n // Message expired. We remove it from the inbox.\n if now > effective_expiration {\n inbox.remove(j);\n }\n\n // Scenario 1: associated TX not yet available. We keep the message in the inbox, as it might become\n // processable as new blocks get mined.\n // Scenario 2: no TX associated to message. The message will sit in the inbox until it expires.\n if maybe_ctx.is_none() {\n continue;\n }\n\n // Scenario 3: Message is ready to process, add to result array. Note we still keep it in the inbox unless we\n // consider it has expired: this is because we need to account for reorgs. If reorg occurs after we processed\n // a message, the effects of processing the message get rewind. However, the associated TX can be included in\n // a subsequent block. Should that happen, the message must be re-processed to ensure consistency.\n let message_context = maybe_ctx.unwrap();\n ready_to_process.push(OffchainMessageWithContext { message_ciphertext: msg.ciphertext, message_context });\n }\n\n ready_to_process\n}\n\nmod test {\n use crate::{\n capsules::CapsuleArray, oracle::random::random, protocol::address::AztecAddress,\n test::helpers::test_environment::TestEnvironment,\n };\n use super::{\n MAX_MSG_TTL, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL, OFFCHAIN_INBOX_SLOT, OffchainMessage, PendingOffchainMsg,\n receive, sync_inbox,\n };\n\n unconstrained fn setup() -> (TestEnvironment, AztecAddress) {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n (env, scope)\n }\n\n /// Creates an `OffchainMessage` with dummy ciphertext and the given scope as recipient.\n fn make_msg(recipient: AztecAddress, tx_hash: Option<Field>, anchor_block_timestamp: u64) -> OffchainMessage {\n OffchainMessage { ciphertext: BoundedVec::new(), recipient, tx_hash, anchor_block_timestamp }\n }\n\n /// Advances the TXE block timestamp by `offset` seconds and returns the resulting timestamp.\n unconstrained fn advance_by(env: TestEnvironment, offset: u64) -> u64 {\n env.advance_next_block_timestamp_by(offset);\n env.mine_block();\n env.last_block_timestamp()\n }\n\n #[test]\n unconstrained fn empty_inbox_returns_empty_result() {\n let (env, scope) = setup();\n env.utility_context(|context| {\n let result = sync_inbox(context.this_address(), scope);\n let inbox: CapsuleArray<PendingOffchainMsg> =\n CapsuleArray::at(context.this_address(), OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0);\n assert_eq(inbox.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn tx_bound_msg_expires_after_max_msg_ttl() {\n let (env, scope) = setup();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(scope, Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, MAX_MSG_TTL + 1);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 0); // expired, removed\n });\n }\n\n #[test]\n unconstrained fn tx_bound_msg_not_expired_before_max_msg_ttl() {\n let (env, scope) = setup();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(scope, Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance, but not past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 1); // not expired, stays\n });\n }\n\n #[test]\n unconstrained fn tx_less_msg_expires_after_max_msg_ttl() {\n let (env, scope) = setup();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(scope, Option::none(), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n // Advance past anchor_ts + MAX_MSG_TTL.\n let _now = advance_by(env, MAX_MSG_TTL + 1);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0); // context is None, not ready\n assert_eq(inbox.len(), 0); // expired, removed\n });\n }\n\n #[test]\n unconstrained fn unresolved_tx_stays_in_inbox() {\n let (env, scope) = setup();\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(scope, Option::some(random()), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0); // not resolved, not ready\n assert_eq(inbox.len(), 1); // not expired, stays\n });\n }\n\n #[test]\n unconstrained fn multiple_messages_mixed_expiration() {\n let (env, scope) = setup();\n let anchor_ts = advance_by(env, 10);\n\n let survivor_tx_hash = random();\n\n env.utility_context(|context| {\n let address = context.this_address();\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n // Message 0: tx-bound, anchor_ts in the past so it expires at\n // anchor_ts + MAX_MSG_TTL. We set anchor to 0 so it expires quickly.\n msgs.push(make_msg(scope, Option::some(random()), 0));\n // Message 1: tx-bound, anchor_ts is recent so it survives.\n msgs.push(make_msg(scope, Option::some(survivor_tx_hash), anchor_ts));\n // Message 2: tx-less, anchor_ts=0 so it also expires.\n msgs.push(make_msg(scope, Option::none(), 0));\n receive(address, msgs);\n });\n\n // Advance past MAX_MSG_TTL for anchor_ts=0, but not for anchor_ts=anchor_ts.\n let _now = advance_by(env, MAX_MSG_TTL);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n assert_eq(result.len(), 0); // all contexts are None\n // Message 0 expired (anchor=0), message 1 survived (anchor=anchor_ts),\n // Message 2 expired (anchor=0).\n assert_eq(inbox.len(), 1);\n assert_eq(inbox.get(0).tx_hash, survivor_tx_hash);\n });\n }\n\n // -- Resolved context (ready to process) ------------------------------\n\n #[test]\n unconstrained fn resolved_msg_is_ready_to_process() {\n let (env, scope) = setup();\n // TestEnvironment::new() deploys protocol contracts, creating blocks with tx effects.\n // In TXE, tx hashes equal Fr(blockNumber), so Fr(1) is the tx effect from block 1.\n // We use this as a \"known resolvable\" tx hash.\n let known_tx_hash: Field = 1;\n let anchor_ts = advance_by(env, 10);\n\n env.utility_context(|context| {\n let mut msgs: BoundedVec<OffchainMessage, MAX_OFFCHAIN_MESSAGES_PER_RECEIVE_CALL> = BoundedVec::new();\n msgs.push(make_msg(scope, Option::some(known_tx_hash), anchor_ts));\n receive(context.this_address(), msgs);\n });\n\n let _now = advance_by(env, 100);\n\n env.utility_context(|context| {\n let address = context.this_address();\n let result = sync_inbox(address, scope);\n let inbox: CapsuleArray<PendingOffchainMsg> = CapsuleArray::at(address, OFFCHAIN_INBOX_SLOT, scope);\n\n // The message should be ready to process since its tx context was resolved.\n assert_eq(result.len(), 1);\n\n let ctx = result.get(0).message_context;\n assert_eq(ctx.tx_hash, known_tx_hash);\n assert(ctx.first_nullifier_in_tx != 0, \"resolved context must have a first nullifier\");\n\n // Message stays in inbox (not expired) for potential reorg reprocessing.\n assert_eq(inbox.len(), 1);\n });\n }\n}\n"
3669
3673
  },
3670
3674
  "16": {
3671
3675
  "function_locations": [
@@ -3963,19 +3967,19 @@
3963
3967
  },
3964
3968
  {
3965
3969
  "name": "try_aes128_decrypt",
3966
- "start": 1040
3970
+ "start": 1046
3967
3971
  },
3968
3972
  {
3969
3973
  "name": "test::aes_encrypt_then_decrypt",
3970
- "start": 1894
3974
+ "start": 1860
3971
3975
  },
3972
3976
  {
3973
3977
  "name": "test::aes_encrypt_then_decrypt_with_bad_sym_key_is_caught",
3974
- "start": 3264
3978
+ "start": 3150
3975
3979
  }
3976
3980
  ],
3977
3981
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/oracle/aes128_decrypt.nr",
3978
- "source": "#[oracle(aztec_utl_decryptAes128)]\nunconstrained fn aes128_decrypt_oracle<let N: u32>(\n ciphertext: BoundedVec<u8, N>,\n iv: [u8; 16],\n sym_key: [u8; 16],\n) -> Option<BoundedVec<u8, N>> {}\n\n/// Attempts to decrypt a ciphertext using AES128.\n///\n/// Returns `Option::some(plaintext)` on success, or `Option::none()` if decryption fails (e.g. due to malformed\n/// ciphertext). Note that decryption with the wrong key will still return `Some` with garbage data, it's up to\n/// the calling function to verify correctness (e.g. via a MAC check).\n///\n/// Note that we accept ciphertext as a BoundedVec, not as an array. This is because this function is typically used\n/// when processing logs and at that point we don't have comptime information about the length of the ciphertext as\n/// the log is not specific to any individual note.\n// TODO(F-498): review naming consistency\npub unconstrained fn try_aes128_decrypt<let N: u32>(\n ciphertext: BoundedVec<u8, N>,\n iv: [u8; 16],\n sym_key: [u8; 16],\n) -> Option<BoundedVec<u8, N>> {\n aes128_decrypt_oracle(ciphertext, iv, sym_key)\n}\n\nmod test {\n use crate::{\n keys::ecdh_shared_secret::compute_app_siloed_shared_secret,\n messages::encryption::aes128::derive_aes_symmetric_key_and_iv_from_shared_secret,\n utils::{array::subarray::subarray, point::point_from_x_coord},\n };\n use crate::protocol::address::AztecAddress;\n use crate::test::helpers::test_environment::TestEnvironment;\n use super::try_aes128_decrypt;\n use poseidon::poseidon2::Poseidon2;\n use std::aes128::aes128_encrypt;\n\n global CONTRACT_ADDRESS: AztecAddress = AztecAddress { inner: 42 };\n global TEST_PLAINTEXT_LENGTH: u32 = 10;\n global TEST_CIPHERTEXT_LENGTH: u32 = 16;\n global TEST_PADDING_LENGTH: u32 = TEST_CIPHERTEXT_LENGTH - TEST_PLAINTEXT_LENGTH;\n\n #[test]\n unconstrained fn aes_encrypt_then_decrypt() {\n let env = TestEnvironment::new();\n\n env.utility_context(|_| {\n let shared_secret_point = point_from_x_coord(1).unwrap();\n let s_app = compute_app_siloed_shared_secret(shared_secret_point, CONTRACT_ADDRESS);\n\n let (sym_key, iv) = derive_aes_symmetric_key_and_iv_from_shared_secret::<1>(s_app)[0];\n\n let plaintext: [u8; TEST_PLAINTEXT_LENGTH] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n let ciphertext: [u8; TEST_CIPHERTEXT_LENGTH] = aes128_encrypt(plaintext, iv, sym_key);\n\n let ciphertext_bvec = BoundedVec::<u8, TEST_CIPHERTEXT_LENGTH>::from_array(ciphertext);\n\n let received_plaintext = try_aes128_decrypt(ciphertext_bvec, iv, sym_key).unwrap();\n assert_eq(received_plaintext.len(), TEST_PLAINTEXT_LENGTH);\n assert_eq(received_plaintext.max_len(), TEST_CIPHERTEXT_LENGTH);\n assert_eq(subarray::<_, _, TEST_PLAINTEXT_LENGTH>(received_plaintext.storage(), 0), plaintext);\n assert_eq(\n subarray::<_, _, TEST_PADDING_LENGTH>(received_plaintext.storage(), TEST_PLAINTEXT_LENGTH),\n [0 as u8; TEST_PADDING_LENGTH],\n );\n })\n }\n\n global TEST_MAC_LENGTH: u32 = 32;\n\n #[test(should_fail_with = \"mac does not match\")]\n unconstrained fn aes_encrypt_then_decrypt_with_bad_sym_key_is_caught() {\n let env = TestEnvironment::new();\n\n env.utility_context(|_| {\n // The AES decryption oracle will not fail for any valid ciphertext; it will always return\n // `Some` with some data. Whether the decryption was successful is up to the app to check in a\n // custom way.\n //\n // E.g. if it's a note that's been encrypted, upon decryption the app can check whether the\n // note hash exists onchain. If it doesn't, that's a strong indicator that decryption failed.\n //\n // E.g. for non-note messages, the plaintext could include a MAC\n // (https://en.wikipedia.org/wiki/Message_authentication_code). We demonstrate this approach in\n // this test: we compute a MAC, include it in the plaintext, encrypt, and then verify that\n // decryption with a bad key produces a MAC mismatch.\n let shared_secret_point = point_from_x_coord(1).unwrap();\n let s_app = compute_app_siloed_shared_secret(shared_secret_point, CONTRACT_ADDRESS);\n\n let (sym_key, iv) = derive_aes_symmetric_key_and_iv_from_shared_secret::<1>(s_app)[0];\n\n let mac_preimage = 0x42;\n let mac = Poseidon2::hash([mac_preimage], 1);\n let mac_as_bytes = mac.to_be_bytes::<TEST_MAC_LENGTH>();\n\n let plaintext: [u8; TEST_PLAINTEXT_LENGTH] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n // We append the mac to the plaintext. It doesn't necessarily have to be 32 bytes; that's quite an extreme\n // length. 16 bytes or 8 bytes might be sufficient, and would save on data broadcasting costs. The shorter\n // the mac, the more possibility of false positive decryptions (decryption seemingly succeeding, but the\n // decrypted plaintext being garbage). Some projects use the `iv` (all 16 bytes or the first 8 bytes) as a\n // mac.\n let mut plaintext_with_mac = [0 as u8; TEST_PLAINTEXT_LENGTH + TEST_MAC_LENGTH];\n for i in 0..TEST_PLAINTEXT_LENGTH {\n plaintext_with_mac[i] = plaintext[i];\n }\n for i in 0..TEST_MAC_LENGTH {\n plaintext_with_mac[TEST_PLAINTEXT_LENGTH + i] = mac_as_bytes[i];\n }\n\n let ciphertext = aes128_encrypt(plaintext_with_mac, iv, sym_key);\n\n // We now would broadcast the tuple [ciphertext, mac] to the network. The recipient will then decrypt the\n // ciphertext, and if the mac inside the received plaintext matches the mac that was broadcast, then the\n // recipient knows that decryption was successful.\n\n // For this test, we intentionally mutate the sym_key to a bad one, so that decryption fails. This allows\n // us to explore how the recipient can detect failed decryption by checking the decrypted mac against the\n // broadcasted mac.\n let mut bad_sym_key = sym_key;\n bad_sym_key[0] = 0;\n\n // We need to convert the array to a BoundedVec because the oracle expects a BoundedVec as it's designed to\n // work with logs of unknown length.\n let ciphertext_bvec = BoundedVec::<u8, 48>::from_array(ciphertext);\n // Decryption with wrong key still returns Some (with garbage).\n let received_plaintext = try_aes128_decrypt(ciphertext_bvec, iv, bad_sym_key).unwrap();\n\n let extracted_mac_as_bytes: [u8; TEST_MAC_LENGTH] =\n subarray(received_plaintext.storage(), TEST_PLAINTEXT_LENGTH);\n\n assert_eq(mac_as_bytes, extracted_mac_as_bytes, \"mac does not match\");\n });\n }\n}\n"
3982
+ "source": "#[oracle(aztec_utl_decryptAes128)]\nunconstrained fn aes128_decrypt_oracle<let N: u32>(\n ciphertext: BoundedVec<u8, N>,\n iv: [u8; 16],\n sym_key: [u8; 16],\n) -> Option<BoundedVec<u8, N>> {}\n\n/// Attempts to decrypt a ciphertext using AES128.\n///\n/// Returns `Option::some(plaintext)` on success, or `Option::none()` if decryption fails (e.g. due to malformed\n/// ciphertext or invalid PKCS#7 padding). Note that decryption with the wrong key will almost always return `None`\n/// because the decrypted garbage data will have invalid PKCS#7 padding.\n///\n/// Note that we accept ciphertext as a BoundedVec, not as an array. This is because this function is typically used\n/// when processing logs and at that point we don't have comptime information about the length of the ciphertext as\n/// the log is not specific to any individual note.\n// TODO(F-498): review naming consistency\npub unconstrained fn try_aes128_decrypt<let N: u32>(\n ciphertext: BoundedVec<u8, N>,\n iv: [u8; 16],\n sym_key: [u8; 16],\n) -> Option<BoundedVec<u8, N>> {\n aes128_decrypt_oracle(ciphertext, iv, sym_key)\n}\n\nmod test {\n use crate::{\n keys::ecdh_shared_secret::compute_app_siloed_shared_secret,\n messages::encryption::aes128::derive_aes_symmetric_key_and_iv_from_shared_secret,\n utils::{array::subarray::subarray, point::point_from_x_coord},\n };\n use crate::protocol::address::AztecAddress;\n use crate::test::helpers::test_environment::TestEnvironment;\n use super::try_aes128_decrypt;\n use std::aes128::aes128_encrypt;\n\n global CONTRACT_ADDRESS: AztecAddress = AztecAddress { inner: 42 };\n global TEST_PLAINTEXT_LENGTH: u32 = 10;\n global TEST_CIPHERTEXT_LENGTH: u32 = 16;\n global TEST_PADDING_LENGTH: u32 = TEST_CIPHERTEXT_LENGTH - TEST_PLAINTEXT_LENGTH;\n\n #[test]\n unconstrained fn aes_encrypt_then_decrypt() {\n let env = TestEnvironment::new();\n\n env.utility_context(|_| {\n let shared_secret_point = point_from_x_coord(1).unwrap();\n let s_app = compute_app_siloed_shared_secret(shared_secret_point, CONTRACT_ADDRESS);\n\n let (sym_key, iv) = derive_aes_symmetric_key_and_iv_from_shared_secret::<1>(s_app)[0];\n\n let plaintext: [u8; TEST_PLAINTEXT_LENGTH] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n let ciphertext: [u8; TEST_CIPHERTEXT_LENGTH] = aes128_encrypt(plaintext, iv, sym_key);\n\n let ciphertext_bvec = BoundedVec::<u8, TEST_CIPHERTEXT_LENGTH>::from_array(ciphertext);\n\n let received_plaintext = try_aes128_decrypt(ciphertext_bvec, iv, sym_key).unwrap();\n assert_eq(received_plaintext.len(), TEST_PLAINTEXT_LENGTH);\n assert_eq(received_plaintext.max_len(), TEST_CIPHERTEXT_LENGTH);\n assert_eq(subarray::<_, _, TEST_PLAINTEXT_LENGTH>(received_plaintext.storage(), 0), plaintext);\n assert_eq(\n subarray::<_, _, TEST_PADDING_LENGTH>(received_plaintext.storage(), TEST_PLAINTEXT_LENGTH),\n [0 as u8; TEST_PADDING_LENGTH],\n );\n })\n }\n\n #[test]\n unconstrained fn aes_encrypt_then_decrypt_with_bad_sym_key_is_caught() {\n let env = TestEnvironment::new();\n\n env.utility_context(|_| {\n // Decrypting with the wrong key results in garbage data with invalid PKCS#7 padding,\n // so the oracle returns None.\n let shared_secret_point = point_from_x_coord(1).unwrap();\n let s_app = compute_app_siloed_shared_secret(shared_secret_point, CONTRACT_ADDRESS);\n\n let (sym_key, iv) = derive_aes_symmetric_key_and_iv_from_shared_secret::<1>(s_app)[0];\n\n let plaintext: [u8; TEST_PLAINTEXT_LENGTH] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n let ciphertext: [u8; TEST_CIPHERTEXT_LENGTH] = aes128_encrypt(plaintext, iv, sym_key);\n\n let mut bad_sym_key = sym_key;\n bad_sym_key[0] = 0;\n\n let ciphertext_bvec = BoundedVec::<u8, TEST_CIPHERTEXT_LENGTH>::from_array(ciphertext);\n // Decryption with wrong key returns None because the garbage output has invalid PKCS#7 padding.\n let result = try_aes128_decrypt(ciphertext_bvec, iv, bad_sym_key);\n assert(result.is_none(), \"decryption with bad key should return None\");\n });\n }\n}\n"
3979
3983
  },
3980
3984
  "174": {
3981
3985
  "function_locations": [
@@ -4263,61 +4267,65 @@
4263
4267
  "name": "copy_oracle",
4264
4268
  "start": 3261
4265
4269
  },
4270
+ {
4271
+ "name": "test::setup",
4272
+ "start": 3884
4273
+ },
4266
4274
  {
4267
4275
  "name": "test::stores_and_loads",
4268
- "start": 3937
4276
+ "start": 4060
4269
4277
  },
4270
4278
  {
4271
4279
  "name": "test::store_overwrites",
4272
- "start": 4333
4280
+ "start": 4450
4273
4281
  },
4274
4282
  {
4275
4283
  "name": "test::loads_empty_slot",
4276
- "start": 4846
4284
+ "start": 4957
4277
4285
  },
4278
4286
  {
4279
4287
  "name": "test::deletes_stored_value",
4280
- "start": 5206
4288
+ "start": 5311
4281
4289
  },
4282
4290
  {
4283
4291
  "name": "test::deletes_empty_slot",
4284
- "start": 5720
4292
+ "start": 5819
4285
4293
  },
4286
4294
  {
4287
4295
  "name": "test::copies_non_overlapping_values",
4288
- "start": 6140
4296
+ "start": 6233
4289
4297
  },
4290
4298
  {
4291
4299
  "name": "test::copies_overlapping_values_with_src_ahead",
4292
- "start": 7019
4300
+ "start": 7106
4293
4301
  },
4294
4302
  {
4295
4303
  "name": "test::copies_overlapping_values_with_dst_ahead",
4296
- "start": 8285
4304
+ "start": 8366
4297
4305
  },
4298
4306
  {
4299
4307
  "name": "test::cannot_copy_empty_values",
4300
- "start": 9573
4308
+ "start": 9648
4301
4309
  },
4302
4310
  {
4303
4311
  "name": "test::cannot_store_other_contract",
4304
- "start": 9901
4312
+ "start": 9970
4305
4313
  },
4306
4314
  {
4307
4315
  "name": "test::cannot_load_other_contract",
4308
- "start": 10380
4316
+ "start": 10443
4309
4317
  },
4310
4318
  {
4311
4319
  "name": "test::cannot_delete_other_contract",
4312
- "start": 10834
4320
+ "start": 10891
4313
4321
  },
4314
4322
  {
4315
4323
  "name": "test::cannot_copy_other_contract",
4316
- "start": 11260
4324
+ "start": 11311
4317
4325
  }
4318
4326
  ],
4319
4327
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/oracle/capsules.nr",
4320
- "source": "use crate::protocol::{address::AztecAddress, traits::{Deserialize, Serialize}};\n\n/// Stores arbitrary information in a per-contract non-volatile database, which can later be retrieved with `load`. If\n/// data was already stored at this slot, it is overwritten.\n// TODO(F-498): review naming consistency\npub unconstrained fn store<T>(contract_address: AztecAddress, slot: Field, value: T, scope: AztecAddress)\nwhere\n T: Serialize,\n{\n let serialized = value.serialize();\n set_capsule_oracle(contract_address, slot, serialized, scope);\n}\n\n/// Returns data previously stored via `storeCapsule` in the per-contract non-volatile database. Returns\n/// Option::none() if nothing was stored at the given slot.\n// TODO(F-498): review naming consistency\npub unconstrained fn load<T>(contract_address: AztecAddress, slot: Field, scope: AztecAddress) -> Option<T>\nwhere\n T: Deserialize,\n{\n let serialized_option = get_capsule_oracle(contract_address, slot, <T as Deserialize>::N, scope);\n serialized_option.map(|arr| Deserialize::deserialize(arr))\n}\n\n/// Deletes data in the per-contract non-volatile database. Does nothing if no data was present.\npub unconstrained fn delete(contract_address: AztecAddress, slot: Field, scope: AztecAddress) {\n delete_oracle(contract_address, slot, scope);\n}\n\n/// Copies a number of contiguous entries in the per-contract non-volatile database. This allows for efficient data\n/// structures by avoiding repeated calls to `loadCapsule` and `storeCapsule`. Supports overlapping source and\n/// destination regions (which will result in the overlapped source values being overwritten). All copied slots must\n/// exist in the database (i.e. have been stored and not deleted)\npub unconstrained fn copy(\n contract_address: AztecAddress,\n src_slot: Field,\n dst_slot: Field,\n num_entries: u32,\n scope: AztecAddress,\n) {\n copy_oracle(contract_address, src_slot, dst_slot, num_entries, scope);\n}\n\n#[oracle(aztec_utl_setCapsule)]\nunconstrained fn set_capsule_oracle<let N: u32>(\n contract_address: AztecAddress,\n slot: Field,\n values: [Field; N],\n scope: AztecAddress,\n) {}\n\n/// We need to pass in `array_len` (the value of N) as a parameter to tell the oracle how many fields the response must\n/// have.\n///\n/// Note that the oracle returns an Option<[Field; N]> because we cannot return an Option<T> directly. That would\n/// require for the oracle resolver to know the shape of T (e.g. if T were a struct of 3 u32 values then the expected\n/// response shape would be 3 single items, whereas it were a struct containing `u32, [Field;10], u32` then the\n/// expected shape would be single, array, single.). Instead, we return the serialization and deserialize in Noir.\n#[oracle(aztec_utl_getCapsule)]\nunconstrained fn get_capsule_oracle<let N: u32>(\n contract_address: AztecAddress,\n slot: Field,\n array_len: u32,\n scope: AztecAddress,\n) -> Option<[Field; N]> {}\n\n#[oracle(aztec_utl_deleteCapsule)]\nunconstrained fn delete_oracle(contract_address: AztecAddress, slot: Field, scope: AztecAddress) {}\n\n#[oracle(aztec_utl_copyCapsule)]\nunconstrained fn copy_oracle(\n contract_address: AztecAddress,\n src_slot: Field,\n dst_slot: Field,\n num_entries: u32,\n scope: AztecAddress,\n) {}\n\nmod test {\n // These tests are sort of redundant since we already test the oracle implementation directly in TypeScript, but\n // they are cheap regardless and help ensure both that the TXE implementation works accordingly and that the Noir\n // oracles are hooked up correctly.\n\n use crate::{\n oracle::capsules::{copy, delete, load, store},\n test::{helpers::test_environment::TestEnvironment, mocks::MockStruct},\n };\n use crate::protocol::{address::AztecAddress, traits::{FromField, ToField}};\n\n global SLOT: Field = 1;\n global SCOPE: AztecAddress = AztecAddress { inner: 0xcafe };\n\n #[test]\n unconstrained fn stores_and_loads() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, SCOPE);\n\n assert_eq(load(contract_address, SLOT, SCOPE).unwrap(), value);\n });\n }\n\n #[test]\n unconstrained fn store_overwrites() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, SCOPE);\n\n let new_value = MockStruct::new(7, 8);\n store(contract_address, SLOT, new_value, SCOPE);\n\n assert_eq(load(contract_address, SLOT, SCOPE).unwrap(), new_value);\n });\n }\n\n #[test]\n unconstrained fn loads_empty_slot() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, SCOPE);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn deletes_stored_value() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, SCOPE);\n delete(contract_address, SLOT, SCOPE);\n\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, SCOPE);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn deletes_empty_slot() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n delete(contract_address, SLOT, SCOPE);\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, SCOPE);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn copies_non_overlapping_values() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 5;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], SCOPE);\n store(contract_address, src + 1, values[1], SCOPE);\n store(contract_address, src + 2, values[2], SCOPE);\n\n let dst = 10;\n copy(contract_address, src, dst, 3, SCOPE);\n\n assert_eq(load(contract_address, dst, SCOPE).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, SCOPE).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, SCOPE).unwrap(), values[2]);\n });\n }\n\n #[test]\n unconstrained fn copies_overlapping_values_with_src_ahead() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 1;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], SCOPE);\n store(contract_address, src + 1, values[1], SCOPE);\n store(contract_address, src + 2, values[2], SCOPE);\n\n let dst = 2;\n copy(contract_address, src, dst, 3, SCOPE);\n\n assert_eq(load(contract_address, dst, SCOPE).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, SCOPE).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, SCOPE).unwrap(), values[2]);\n\n // src[1] and src[2] should have been overwritten since they are also dst[0] and dst[1]\n assert_eq(load(contract_address, src, SCOPE).unwrap(), values[0]); // src[0] (unchanged)\n assert_eq(load(contract_address, src + 1, SCOPE).unwrap(), values[0]); // dst[0]\n assert_eq(load(contract_address, src + 2, SCOPE).unwrap(), values[1]); // dst[1]\n });\n }\n\n #[test]\n unconstrained fn copies_overlapping_values_with_dst_ahead() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 2;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], SCOPE);\n store(contract_address, src + 1, values[1], SCOPE);\n store(contract_address, src + 2, values[2], SCOPE);\n\n let dst = 1;\n copy(contract_address, src, dst, 3, SCOPE);\n\n assert_eq(load(contract_address, dst, SCOPE).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, SCOPE).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, SCOPE).unwrap(), values[2]);\n\n // src[0] and src[1] should have been overwritten since they are also dst[1] and dst[2]\n assert_eq(load(contract_address, src, SCOPE).unwrap(), values[1]); // dst[1]\n assert_eq(load(contract_address, src + 1, SCOPE).unwrap(), values[2]); // dst[2]\n assert_eq(load(contract_address, src + 2, SCOPE).unwrap(), values[2]); // src[2] (unchanged)\n });\n }\n\n #[test(should_fail_with = \"copy empty slot\")]\n unconstrained fn cannot_copy_empty_values() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n copy(contract_address, SLOT, SLOT, 1, SCOPE);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_store_other_contract() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n let value = MockStruct::new(5, 6);\n store(other_contract_address, SLOT, value, SCOPE);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_load_other_contract() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n let _: Option<MockStruct> = load(other_contract_address, SLOT, SCOPE);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_delete_other_contract() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n delete(other_contract_address, SLOT, SCOPE);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_copy_other_contract() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n copy(other_contract_address, SLOT, SLOT, 0, SCOPE);\n });\n }\n}\n"
4328
+ "source": "use crate::protocol::{address::AztecAddress, traits::{Deserialize, Serialize}};\n\n/// Stores arbitrary information in a per-contract non-volatile database, which can later be retrieved with `load`. If\n/// data was already stored at this slot, it is overwritten.\n// TODO(F-498): review naming consistency\npub unconstrained fn store<T>(contract_address: AztecAddress, slot: Field, value: T, scope: AztecAddress)\nwhere\n T: Serialize,\n{\n let serialized = value.serialize();\n set_capsule_oracle(contract_address, slot, serialized, scope);\n}\n\n/// Returns data previously stored via `storeCapsule` in the per-contract non-volatile database. Returns\n/// Option::none() if nothing was stored at the given slot.\n// TODO(F-498): review naming consistency\npub unconstrained fn load<T>(contract_address: AztecAddress, slot: Field, scope: AztecAddress) -> Option<T>\nwhere\n T: Deserialize,\n{\n let serialized_option = get_capsule_oracle(contract_address, slot, <T as Deserialize>::N, scope);\n serialized_option.map(|arr| Deserialize::deserialize(arr))\n}\n\n/// Deletes data in the per-contract non-volatile database. Does nothing if no data was present.\npub unconstrained fn delete(contract_address: AztecAddress, slot: Field, scope: AztecAddress) {\n delete_oracle(contract_address, slot, scope);\n}\n\n/// Copies a number of contiguous entries in the per-contract non-volatile database. This allows for efficient data\n/// structures by avoiding repeated calls to `loadCapsule` and `storeCapsule`. Supports overlapping source and\n/// destination regions (which will result in the overlapped source values being overwritten). All copied slots must\n/// exist in the database (i.e. have been stored and not deleted)\npub unconstrained fn copy(\n contract_address: AztecAddress,\n src_slot: Field,\n dst_slot: Field,\n num_entries: u32,\n scope: AztecAddress,\n) {\n copy_oracle(contract_address, src_slot, dst_slot, num_entries, scope);\n}\n\n#[oracle(aztec_utl_setCapsule)]\nunconstrained fn set_capsule_oracle<let N: u32>(\n contract_address: AztecAddress,\n slot: Field,\n values: [Field; N],\n scope: AztecAddress,\n) {}\n\n/// We need to pass in `array_len` (the value of N) as a parameter to tell the oracle how many fields the response must\n/// have.\n///\n/// Note that the oracle returns an Option<[Field; N]> because we cannot return an Option<T> directly. That would\n/// require for the oracle resolver to know the shape of T (e.g. if T were a struct of 3 u32 values then the expected\n/// response shape would be 3 single items, whereas it were a struct containing `u32, [Field;10], u32` then the\n/// expected shape would be single, array, single.). Instead, we return the serialization and deserialize in Noir.\n#[oracle(aztec_utl_getCapsule)]\nunconstrained fn get_capsule_oracle<let N: u32>(\n contract_address: AztecAddress,\n slot: Field,\n array_len: u32,\n scope: AztecAddress,\n) -> Option<[Field; N]> {}\n\n#[oracle(aztec_utl_deleteCapsule)]\nunconstrained fn delete_oracle(contract_address: AztecAddress, slot: Field, scope: AztecAddress) {}\n\n#[oracle(aztec_utl_copyCapsule)]\nunconstrained fn copy_oracle(\n contract_address: AztecAddress,\n src_slot: Field,\n dst_slot: Field,\n num_entries: u32,\n scope: AztecAddress,\n) {}\n\nmod test {\n // These tests are sort of redundant since we already test the oracle implementation directly in TypeScript, but\n // they are cheap regardless and help ensure both that the TXE implementation works accordingly and that the Noir\n // oracles are hooked up correctly.\n\n use crate::{\n oracle::capsules::{copy, delete, load, store},\n test::{helpers::test_environment::TestEnvironment, mocks::MockStruct},\n };\n use crate::protocol::{address::AztecAddress, traits::{FromField, ToField}};\n\n global SLOT: Field = 1;\n\n unconstrained fn setup() -> (TestEnvironment, AztecAddress) {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n (env, scope)\n }\n\n #[test]\n unconstrained fn stores_and_loads() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, scope);\n\n assert_eq(load(contract_address, SLOT, scope).unwrap(), value);\n });\n }\n\n #[test]\n unconstrained fn store_overwrites() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, scope);\n\n let new_value = MockStruct::new(7, 8);\n store(contract_address, SLOT, new_value, scope);\n\n assert_eq(load(contract_address, SLOT, scope).unwrap(), new_value);\n });\n }\n\n #[test]\n unconstrained fn loads_empty_slot() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, scope);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn deletes_stored_value() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let value = MockStruct::new(5, 6);\n store(contract_address, SLOT, value, scope);\n delete(contract_address, SLOT, scope);\n\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, scope);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn deletes_empty_slot() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n delete(contract_address, SLOT, scope);\n let loaded_value: Option<MockStruct> = load(contract_address, SLOT, scope);\n assert_eq(loaded_value, Option::none());\n });\n }\n\n #[test]\n unconstrained fn copies_non_overlapping_values() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 5;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], scope);\n store(contract_address, src + 1, values[1], scope);\n store(contract_address, src + 2, values[2], scope);\n\n let dst = 10;\n copy(contract_address, src, dst, 3, scope);\n\n assert_eq(load(contract_address, dst, scope).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, scope).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, scope).unwrap(), values[2]);\n });\n }\n\n #[test]\n unconstrained fn copies_overlapping_values_with_src_ahead() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 1;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], scope);\n store(contract_address, src + 1, values[1], scope);\n store(contract_address, src + 2, values[2], scope);\n\n let dst = 2;\n copy(contract_address, src, dst, 3, scope);\n\n assert_eq(load(contract_address, dst, scope).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, scope).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, scope).unwrap(), values[2]);\n\n // src[1] and src[2] should have been overwritten since they are also dst[0] and dst[1]\n assert_eq(load(contract_address, src, scope).unwrap(), values[0]); // src[0] (unchanged)\n assert_eq(load(contract_address, src + 1, scope).unwrap(), values[0]); // dst[0]\n assert_eq(load(contract_address, src + 2, scope).unwrap(), values[1]); // dst[1]\n });\n }\n\n #[test]\n unconstrained fn copies_overlapping_values_with_dst_ahead() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let src = 2;\n\n let values = [MockStruct::new(5, 6), MockStruct::new(7, 8), MockStruct::new(9, 10)];\n store(contract_address, src, values[0], scope);\n store(contract_address, src + 1, values[1], scope);\n store(contract_address, src + 2, values[2], scope);\n\n let dst = 1;\n copy(contract_address, src, dst, 3, scope);\n\n assert_eq(load(contract_address, dst, scope).unwrap(), values[0]);\n assert_eq(load(contract_address, dst + 1, scope).unwrap(), values[1]);\n assert_eq(load(contract_address, dst + 2, scope).unwrap(), values[2]);\n\n // src[0] and src[1] should have been overwritten since they are also dst[1] and dst[2]\n assert_eq(load(contract_address, src, scope).unwrap(), values[1]); // dst[1]\n assert_eq(load(contract_address, src + 1, scope).unwrap(), values[2]); // dst[2]\n assert_eq(load(contract_address, src + 2, scope).unwrap(), values[2]); // src[2] (unchanged)\n });\n }\n\n #[test(should_fail_with = \"copy empty slot\")]\n unconstrained fn cannot_copy_empty_values() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n copy(contract_address, SLOT, SLOT, 1, scope);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_store_other_contract() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n let value = MockStruct::new(5, 6);\n store(other_contract_address, SLOT, value, scope);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_load_other_contract() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n let _: Option<MockStruct> = load(other_contract_address, SLOT, scope);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_delete_other_contract() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n delete(other_contract_address, SLOT, scope);\n });\n }\n\n #[test(should_fail_with = \"not allowed to access\")]\n unconstrained fn cannot_copy_other_contract() {\n let (env, scope) = setup();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let other_contract_address = AztecAddress::from_field(contract_address.to_field() + 1);\n\n copy(other_contract_address, SLOT, SLOT, 0, scope);\n });\n }\n}\n"
4321
4329
  },
4322
4330
  "178": {
4323
4331
  "function_locations": [
@@ -4717,7 +4725,7 @@
4717
4725
  }
4718
4726
  ],
4719
4727
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/oracle/version.nr",
4720
- "source": "/// The ORACLE_VERSION constant is used to check that the oracle interface is in sync between PXE and Aztec.nr. We need\n/// to version the oracle interface to ensure that developers get a reasonable error message if they use incompatible\n/// versions of Aztec.nr and PXE. The TypeScript counterpart is in `oracle_version.ts`.\n///\n/// @dev Whenever a contract function or Noir test is run, the `aztec_utl_assertCompatibleOracleVersion` oracle is\n/// called and if the oracle version is incompatible an error is thrown.\npub global ORACLE_VERSION: Field = 21;\n\n/// Asserts that the version of the oracle is compatible with the version expected by the contract.\npub fn assert_compatible_oracle_version() {\n // Safety: This oracle call returns nothing: we only call it to check Aztec.nr and Oracle interface versions are\n // compatible. It is therefore always safe to call.\n unsafe {\n assert_compatible_oracle_version_wrapper();\n }\n}\n\nunconstrained fn assert_compatible_oracle_version_wrapper() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION);\n}\n\n#[oracle(aztec_utl_assertCompatibleOracleVersion)]\nunconstrained fn assert_compatible_oracle_version_oracle(version: Field) {}\n\nmod test {\n use super::{assert_compatible_oracle_version_oracle, ORACLE_VERSION};\n\n #[test]\n unconstrained fn compatible_oracle_version() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION);\n }\n\n #[test(should_fail_with = \"Incompatible aztec cli version:\")]\n unconstrained fn incompatible_oracle_version() {\n let arbitrary_incorrect_version = 318183437;\n assert_compatible_oracle_version_oracle(arbitrary_incorrect_version);\n }\n}\n"
4728
+ "source": "/// The ORACLE_VERSION constant is used to check that the oracle interface is in sync between PXE and Aztec.nr. We need\n/// to version the oracle interface to ensure that developers get a reasonable error message if they use incompatible\n/// versions of Aztec.nr and PXE. The TypeScript counterpart is in `oracle_version.ts`.\n///\n/// @dev Whenever a contract function or Noir test is run, the `aztec_utl_assertCompatibleOracleVersion` oracle is\n/// called and if the oracle version is incompatible an error is thrown.\npub global ORACLE_VERSION: Field = 22;\n\n/// Asserts that the version of the oracle is compatible with the version expected by the contract.\npub fn assert_compatible_oracle_version() {\n // Safety: This oracle call returns nothing: we only call it to check Aztec.nr and Oracle interface versions are\n // compatible. It is therefore always safe to call.\n unsafe {\n assert_compatible_oracle_version_wrapper();\n }\n}\n\nunconstrained fn assert_compatible_oracle_version_wrapper() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION);\n}\n\n#[oracle(aztec_utl_assertCompatibleOracleVersion)]\nunconstrained fn assert_compatible_oracle_version_oracle(version: Field) {}\n\nmod test {\n use super::{assert_compatible_oracle_version_oracle, ORACLE_VERSION};\n\n #[test]\n unconstrained fn compatible_oracle_version() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION);\n }\n\n #[test(should_fail_with = \"Incompatible aztec cli version:\")]\n unconstrained fn incompatible_oracle_version() {\n let arbitrary_incorrect_version = 318183437;\n assert_compatible_oracle_version_oracle(arbitrary_incorrect_version);\n }\n}\n"
4721
4729
  },
4722
4730
  "203": {
4723
4731
  "function_locations": [
@@ -6719,55 +6727,55 @@
6719
6727
  },
6720
6728
  {
6721
6729
  "name": "test::empty_array",
6722
- "start": 6902
6730
+ "start": 6789
6723
6731
  },
6724
6732
  {
6725
6733
  "name": "test::empty_array_read",
6726
- "start": 7324
6734
+ "start": 7263
6727
6735
  },
6728
6736
  {
6729
6737
  "name": "test::array_push",
6730
- "start": 7647
6738
+ "start": 7638
6731
6739
  },
6732
6740
  {
6733
6741
  "name": "test::read_past_len",
6734
- "start": 8113
6742
+ "start": 8156
6735
6743
  },
6736
6744
  {
6737
6745
  "name": "test::array_remove_last",
6738
- "start": 8464
6746
+ "start": 8559
6739
6747
  },
6740
6748
  {
6741
6749
  "name": "test::array_remove_some",
6742
- "start": 8850
6750
+ "start": 8997
6743
6751
  },
6744
6752
  {
6745
6753
  "name": "test::array_remove_all",
6746
- "start": 9530
6754
+ "start": 9729
6747
6755
  },
6748
6756
  {
6749
6757
  "name": "test::for_each_called_with_all_elements",
6750
- "start": 10045
6758
+ "start": 10296
6751
6759
  },
6752
6760
  {
6753
6761
  "name": "test::for_each_remove_some",
6754
- "start": 11086
6762
+ "start": 11389
6755
6763
  },
6756
6764
  {
6757
6765
  "name": "test::for_each_remove_all",
6758
- "start": 11726
6766
+ "start": 12081
6759
6767
  },
6760
6768
  {
6761
6769
  "name": "test::for_each_remove_all_no_copy",
6762
- "start": 12212
6770
+ "start": 12619
6763
6771
  },
6764
6772
  {
6765
6773
  "name": "test::different_scopes_are_isolated",
6766
- "start": 12924
6774
+ "start": 13383
6767
6775
  }
6768
6776
  ],
6769
6777
  "path": "/home/aztec-dev/aztec-packages/noir-projects/aztec-nr/aztec/src/capsules/mod.nr",
6770
- "source": "use crate::oracle::capsules;\nuse crate::protocol::{address::AztecAddress, traits::{Deserialize, Serialize}};\n\n/// A dynamically sized array backed by PXE's non-volatile database (called capsules). Values are persisted until\n/// deleted, so they can be e.g. stored during simulation of a transaction and later retrieved during witness\n/// generation. All values are scoped per contract address, so external contracts cannot access them.\npub struct CapsuleArray<T> {\n contract_address: AztecAddress,\n /// The base slot is where the array length is stored in capsules. Array elements are stored in consecutive slots\n /// after the base slot. For example, with base slot 5: the length is at slot 5, the first element (index 0) is at\n /// slot 6, the second element (index 1) is at slot 7, and so on.\n base_slot: Field,\n /// Scope for capsule isolation. Capsule operations are scoped to the given address, allowing multiple independent\n /// namespaces within the same contract.\n scope: AztecAddress,\n}\n\nimpl<T> CapsuleArray<T> {\n /// Returns a CapsuleArray scoped to a specific address.\n ///\n /// Array elements are stored in contiguous slots\n /// following the base slot, so there should be sufficient space between array base slots to accommodate elements.\n /// A reasonable strategy is to make the base slot a hash of a unique value.\n pub unconstrained fn at(contract_address: AztecAddress, base_slot: Field, scope: AztecAddress) -> Self {\n Self { contract_address, base_slot, scope }\n }\n\n /// Returns the number of elements stored in the array.\n pub unconstrained fn len(self) -> u32 {\n // An uninitialized array defaults to a length of 0.\n capsules::load(self.contract_address, self.base_slot, self.scope).unwrap_or(0) as u32\n }\n\n /// Stores a value at the end of the array.\n pub unconstrained fn push(self, value: T)\n where\n T: Serialize,\n {\n let current_length = self.len();\n\n // The slot corresponding to the index `current_length` is the first slot immediately after the end of the\n // array, which is where we want to place the new value.\n capsules::store(\n self.contract_address,\n self.slot_at(current_length),\n value,\n self.scope,\n );\n\n // Then we simply update the length.\n let new_length = current_length + 1;\n capsules::store(\n self.contract_address,\n self.base_slot,\n new_length,\n self.scope,\n );\n }\n\n /// Retrieves the value stored in the array at `index`. Throws if the index is out of bounds.\n pub unconstrained fn get(self, index: u32) -> T\n where\n T: Deserialize,\n {\n assert(index < self.len(), \"Attempted to read past the length of a CapsuleArray\");\n\n capsules::load(self.contract_address, self.slot_at(index), self.scope).unwrap()\n }\n\n /// Deletes the value stored in the array at `index`. Throws if the index is out of bounds.\n pub unconstrained fn remove(self, index: u32) {\n let current_length = self.len();\n assert(index < current_length, \"Attempted to delete past the length of a CapsuleArray\");\n\n // In order to be able to remove elements at arbitrary indices, we need to shift the entire contents of the\n // array past the removed element one slot backward so that we don't end up with a gap and preserve the\n // contiguous slots. We can skip this when deleting the last element however.\n if index != current_length - 1 {\n // The source and destination regions overlap, but `copy` supports this.\n capsules::copy(\n self.contract_address,\n self.slot_at(index + 1),\n self.slot_at(index),\n current_length - index - 1,\n self.scope,\n );\n }\n\n // We can now delete the last element (which has either been copied to the slot immediately before it, or was\n // the element we meant to delete in the first place) and update the length.\n capsules::delete(\n self.contract_address,\n self.slot_at(current_length - 1),\n self.scope,\n );\n capsules::store(\n self.contract_address,\n self.base_slot,\n current_length - 1,\n self.scope,\n );\n }\n\n /// Calls a function on each element of the array.\n ///\n /// The function `f` is called once with each array value and its corresponding index. The order in which values\n /// are processed is arbitrary.\n ///\n /// ## Array Mutation\n ///\n /// It is safe to delete the current element (and only the current element) from inside the callback via `remove`:\n /// ```noir\n /// array.for_each(|index, value| {\n /// if some_condition(value) {\n /// array.remove(index); // safe only for this index\n /// }\n /// }\n /// ```\n ///\n /// If all elements in the array need to iterated over and then removed, then using `for_each` results in optimal\n /// efficiency.\n ///\n /// It is **not** safe to push new elements into the array from inside the callback.\n pub unconstrained fn for_each<Env>(self, f: unconstrained fn[Env](u32, T) -> ())\n where\n T: Deserialize,\n {\n // Iterating over all elements is simple, but we want to do it in such a way that a) deleting the current\n // element is safe to do, and b) deleting *all* elements is optimally efficient. This is because CapsuleArrays\n // are typically used to hold pending tasks, so iterating them while clearing completed tasks (sometimes\n // unconditionally, resulting in a full clear) is a very common access pattern.\n //\n // The way we achieve this is by iterating backwards: each element can always be deleted since it won't change\n // any preceding (lower) indices, and if every element is deleted then every element will (in turn) be the last\n // element. This results in an optimal full clear since `remove` will be able to skip the `capsules::copy` call\n // to shift any elements past the deleted one (because there will be none).\n let mut i = self.len();\n while i > 0 {\n i -= 1;\n f(i, self.get(i));\n }\n }\n\n unconstrained fn slot_at(self, index: u32) -> Field {\n // Elements are stored immediately after the base slot, so we add 1 to it to compute the slot for the first\n // element.\n self.base_slot + 1 + index as Field\n }\n}\n\nmod test {\n use crate::protocol::address::AztecAddress;\n use crate::test::helpers::test_environment::TestEnvironment;\n use super::CapsuleArray;\n\n global SLOT: Field = 1230;\n global SCOPE: AztecAddress = AztecAddress { inner: 0xface };\n\n #[test]\n unconstrained fn empty_array() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array: CapsuleArray<Field> = CapsuleArray::at(contract_address, SLOT, SCOPE);\n assert_eq(array.len(), 0);\n });\n }\n\n #[test(should_fail_with = \"Attempted to read past the length of a CapsuleArray\")]\n unconstrained fn empty_array_read() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n let _: Field = array.get(0);\n });\n }\n\n #[test]\n unconstrained fn array_push() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n array.push(5);\n\n assert_eq(array.len(), 1);\n assert_eq(array.get(0), 5);\n });\n }\n\n #[test(should_fail_with = \"Attempted to read past the length of a CapsuleArray\")]\n unconstrained fn read_past_len() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n array.push(5);\n\n let _ = array.get(1);\n });\n }\n\n #[test]\n unconstrained fn array_remove_last() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(5);\n array.remove(0);\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn array_remove_some() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(7);\n array.push(8);\n array.push(9);\n\n assert_eq(array.len(), 3);\n assert_eq(array.get(0), 7);\n assert_eq(array.get(1), 8);\n assert_eq(array.get(2), 9);\n\n array.remove(1);\n\n assert_eq(array.len(), 2);\n assert_eq(array.get(0), 7);\n assert_eq(array.get(1), 9);\n });\n }\n\n #[test]\n unconstrained fn array_remove_all() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(7);\n array.push(8);\n array.push(9);\n\n array.remove(1);\n array.remove(1);\n array.remove(0);\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn for_each_called_with_all_elements() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n // We store all values that we were called with and check that all (value, index) tuples are present. Note\n // that we do not care about the order in which each tuple was passed to the closure.\n let called_with = &mut BoundedVec::<(u32, Field), 3>::new();\n array.for_each(|index, value| { called_with.push((index, value)); });\n\n assert_eq(called_with.len(), 3);\n assert(called_with.any(|(index, value)| (index == 0) & (value == 4)));\n assert(called_with.any(|(index, value)| (index == 1) & (value == 5)));\n assert(called_with.any(|(index, value)| (index == 2) & (value == 6)));\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_some() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n array.for_each(|index, _| {\n if index == 1 {\n array.remove(index);\n }\n });\n\n assert_eq(array.len(), 2);\n assert_eq(array.get(0), 4);\n assert_eq(array.get(1), 6);\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_all() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n array.for_each(|index, _| { array.remove(index); });\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_all_no_copy() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, SCOPE);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n // We test that the aztec_utl_copyCapsule was never called, which is the expensive operation we want to\n // avoid.\n let mock = std::test::OracleMock::mock(\"aztec_utl_copyCapsule\");\n\n array.for_each(|index, _| { array.remove(index); });\n\n assert_eq(mock.times_called(), 0);\n });\n }\n\n #[test]\n unconstrained fn different_scopes_are_isolated() {\n let env = TestEnvironment::new();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let scope_a = AztecAddress { inner: 0xaaa };\n let scope_b = AztecAddress { inner: 0xbbb };\n\n let array_a = CapsuleArray::at(contract_address, SLOT, scope_a);\n let array_b = CapsuleArray::at(contract_address, SLOT, scope_b);\n\n array_a.push(10);\n array_a.push(20);\n array_b.push(99);\n\n assert_eq(array_a.len(), 2);\n assert_eq(array_a.get(0), 10);\n assert_eq(array_a.get(1), 20);\n\n assert_eq(array_b.len(), 1);\n assert_eq(array_b.get(0), 99);\n });\n }\n}\n"
6778
+ "source": "use crate::oracle::capsules;\nuse crate::protocol::{address::AztecAddress, traits::{Deserialize, Serialize}};\n\n/// A dynamically sized array backed by PXE's non-volatile database (called capsules). Values are persisted until\n/// deleted, so they can be e.g. stored during simulation of a transaction and later retrieved during witness\n/// generation. All values are scoped per contract address, so external contracts cannot access them.\npub struct CapsuleArray<T> {\n contract_address: AztecAddress,\n /// The base slot is where the array length is stored in capsules. Array elements are stored in consecutive slots\n /// after the base slot. For example, with base slot 5: the length is at slot 5, the first element (index 0) is at\n /// slot 6, the second element (index 1) is at slot 7, and so on.\n base_slot: Field,\n /// Scope for capsule isolation. Capsule operations are scoped to the given address, allowing multiple independent\n /// namespaces within the same contract.\n scope: AztecAddress,\n}\n\nimpl<T> CapsuleArray<T> {\n /// Returns a CapsuleArray scoped to a specific address.\n ///\n /// Array elements are stored in contiguous slots\n /// following the base slot, so there should be sufficient space between array base slots to accommodate elements.\n /// A reasonable strategy is to make the base slot a hash of a unique value.\n pub unconstrained fn at(contract_address: AztecAddress, base_slot: Field, scope: AztecAddress) -> Self {\n Self { contract_address, base_slot, scope }\n }\n\n /// Returns the number of elements stored in the array.\n pub unconstrained fn len(self) -> u32 {\n // An uninitialized array defaults to a length of 0.\n capsules::load(self.contract_address, self.base_slot, self.scope).unwrap_or(0) as u32\n }\n\n /// Stores a value at the end of the array.\n pub unconstrained fn push(self, value: T)\n where\n T: Serialize,\n {\n let current_length = self.len();\n\n // The slot corresponding to the index `current_length` is the first slot immediately after the end of the\n // array, which is where we want to place the new value.\n capsules::store(\n self.contract_address,\n self.slot_at(current_length),\n value,\n self.scope,\n );\n\n // Then we simply update the length.\n let new_length = current_length + 1;\n capsules::store(\n self.contract_address,\n self.base_slot,\n new_length,\n self.scope,\n );\n }\n\n /// Retrieves the value stored in the array at `index`. Throws if the index is out of bounds.\n pub unconstrained fn get(self, index: u32) -> T\n where\n T: Deserialize,\n {\n assert(index < self.len(), \"Attempted to read past the length of a CapsuleArray\");\n\n capsules::load(self.contract_address, self.slot_at(index), self.scope).unwrap()\n }\n\n /// Deletes the value stored in the array at `index`. Throws if the index is out of bounds.\n pub unconstrained fn remove(self, index: u32) {\n let current_length = self.len();\n assert(index < current_length, \"Attempted to delete past the length of a CapsuleArray\");\n\n // In order to be able to remove elements at arbitrary indices, we need to shift the entire contents of the\n // array past the removed element one slot backward so that we don't end up with a gap and preserve the\n // contiguous slots. We can skip this when deleting the last element however.\n if index != current_length - 1 {\n // The source and destination regions overlap, but `copy` supports this.\n capsules::copy(\n self.contract_address,\n self.slot_at(index + 1),\n self.slot_at(index),\n current_length - index - 1,\n self.scope,\n );\n }\n\n // We can now delete the last element (which has either been copied to the slot immediately before it, or was\n // the element we meant to delete in the first place) and update the length.\n capsules::delete(\n self.contract_address,\n self.slot_at(current_length - 1),\n self.scope,\n );\n capsules::store(\n self.contract_address,\n self.base_slot,\n current_length - 1,\n self.scope,\n );\n }\n\n /// Calls a function on each element of the array.\n ///\n /// The function `f` is called once with each array value and its corresponding index. The order in which values\n /// are processed is arbitrary.\n ///\n /// ## Array Mutation\n ///\n /// It is safe to delete the current element (and only the current element) from inside the callback via `remove`:\n /// ```noir\n /// array.for_each(|index, value| {\n /// if some_condition(value) {\n /// array.remove(index); // safe only for this index\n /// }\n /// }\n /// ```\n ///\n /// If all elements in the array need to iterated over and then removed, then using `for_each` results in optimal\n /// efficiency.\n ///\n /// It is **not** safe to push new elements into the array from inside the callback.\n pub unconstrained fn for_each<Env>(self, f: unconstrained fn[Env](u32, T) -> ())\n where\n T: Deserialize,\n {\n // Iterating over all elements is simple, but we want to do it in such a way that a) deleting the current\n // element is safe to do, and b) deleting *all* elements is optimally efficient. This is because CapsuleArrays\n // are typically used to hold pending tasks, so iterating them while clearing completed tasks (sometimes\n // unconditionally, resulting in a full clear) is a very common access pattern.\n //\n // The way we achieve this is by iterating backwards: each element can always be deleted since it won't change\n // any preceding (lower) indices, and if every element is deleted then every element will (in turn) be the last\n // element. This results in an optimal full clear since `remove` will be able to skip the `capsules::copy` call\n // to shift any elements past the deleted one (because there will be none).\n let mut i = self.len();\n while i > 0 {\n i -= 1;\n f(i, self.get(i));\n }\n }\n\n unconstrained fn slot_at(self, index: u32) -> Field {\n // Elements are stored immediately after the base slot, so we add 1 to it to compute the slot for the first\n // element.\n self.base_slot + 1 + index as Field\n }\n}\n\nmod test {\n use crate::test::helpers::test_environment::TestEnvironment;\n use super::CapsuleArray;\n\n global SLOT: Field = 1230;\n\n #[test]\n unconstrained fn empty_array() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array: CapsuleArray<Field> = CapsuleArray::at(contract_address, SLOT, scope);\n assert_eq(array.len(), 0);\n });\n }\n\n #[test(should_fail_with = \"Attempted to read past the length of a CapsuleArray\")]\n unconstrained fn empty_array_read() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n let _: Field = array.get(0);\n });\n }\n\n #[test]\n unconstrained fn array_push() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n array.push(5);\n\n assert_eq(array.len(), 1);\n assert_eq(array.get(0), 5);\n });\n }\n\n #[test(should_fail_with = \"Attempted to read past the length of a CapsuleArray\")]\n unconstrained fn read_past_len() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n array.push(5);\n\n let _ = array.get(1);\n });\n }\n\n #[test]\n unconstrained fn array_remove_last() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(5);\n array.remove(0);\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn array_remove_some() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(7);\n array.push(8);\n array.push(9);\n\n assert_eq(array.len(), 3);\n assert_eq(array.get(0), 7);\n assert_eq(array.get(1), 8);\n assert_eq(array.get(2), 9);\n\n array.remove(1);\n\n assert_eq(array.len(), 2);\n assert_eq(array.get(0), 7);\n assert_eq(array.get(1), 9);\n });\n }\n\n #[test]\n unconstrained fn array_remove_all() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(7);\n array.push(8);\n array.push(9);\n\n array.remove(1);\n array.remove(1);\n array.remove(0);\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn for_each_called_with_all_elements() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n // We store all values that we were called with and check that all (value, index) tuples are present. Note\n // that we do not care about the order in which each tuple was passed to the closure.\n let called_with = &mut BoundedVec::<(u32, Field), 3>::new();\n array.for_each(|index, value| { called_with.push((index, value)); });\n\n assert_eq(called_with.len(), 3);\n assert(called_with.any(|(index, value)| (index == 0) & (value == 4)));\n assert(called_with.any(|(index, value)| (index == 1) & (value == 5)));\n assert(called_with.any(|(index, value)| (index == 2) & (value == 6)));\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_some() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n array.for_each(|index, _| {\n if index == 1 {\n array.remove(index);\n }\n });\n\n assert_eq(array.len(), 2);\n assert_eq(array.get(0), 4);\n assert_eq(array.get(1), 6);\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_all() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n array.for_each(|index, _| { array.remove(index); });\n\n assert_eq(array.len(), 0);\n });\n }\n\n #[test]\n unconstrained fn for_each_remove_all_no_copy() {\n let mut env = TestEnvironment::new();\n let scope = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n let array = CapsuleArray::at(contract_address, SLOT, scope);\n\n array.push(4);\n array.push(5);\n array.push(6);\n\n // We test that the aztec_utl_copyCapsule was never called, which is the expensive operation we want to\n // avoid.\n let mock = std::test::OracleMock::mock(\"aztec_utl_copyCapsule\");\n\n array.for_each(|index, _| { array.remove(index); });\n\n assert_eq(mock.times_called(), 0);\n });\n }\n\n #[test]\n unconstrained fn different_scopes_are_isolated() {\n let mut env = TestEnvironment::new();\n let scope_a = env.create_light_account();\n let scope_b = env.create_light_account();\n env.private_context(|context| {\n let contract_address = context.this_address();\n\n let array_a = CapsuleArray::at(contract_address, SLOT, scope_a);\n let array_b = CapsuleArray::at(contract_address, SLOT, scope_b);\n\n array_a.push(10);\n array_a.push(20);\n array_b.push(99);\n\n assert_eq(array_a.len(), 2);\n assert_eq(array_a.get(0), 10);\n assert_eq(array_a.get(1), 20);\n\n assert_eq(array_b.len(), 1);\n assert_eq(array_b.get(0), 99);\n });\n }\n}\n"
6771
6779
  },
6772
6780
  "6": {
6773
6781
  "function_locations": [