diff --git a/boxes/blank/src/contracts/target/blank-Blank.json b/boxes/blank/src/contracts/target/blank-Blank.json index b22620056b0..df045ffe5d9 100644 --- a/boxes/blank/src/contracts/target/blank-Blank.json +++ b/boxes/blank/src/contracts/target/blank-Blank.json @@ -1 +1 @@ -{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_commitments","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"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CsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_commitments","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"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","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file +{"noir_version":"0.24.0+78ef0134b82e76a73dadb6c7975def22290e3a1a","name":"Blank","functions":[{"name":"constructor","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265]},"bytecode":"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","debug_symbols":"3ZjbjhoxDED/ZZ4Rii9xbH6l6gNttxISYlcLqlQh/r3DxZmBjSbdQWKBJ4hke058i5Nts3z9Od8sXlfrZrZtAJrZt22zfpuv9sv1Zv6+aWZh0rysfrW/u0nze7F8aWZMu8kHMYh2EgSFLAohFmQRlU7CSNwZBkkly0AS3TYw2pn890kD+KDcdCtuhuTcnNLV3FzilggnJdEKO1ryD6D16ZUO9mPRvrlnUkjD9o3dvJlmUbNRm5V7gklXwkBIlD9AYRjnPzNRyZNLI3cWj8D6aMD2YMAYHg0YKsAMte6hXiQU8Mx8qfUFN4wRYFi4Wn+IV7JTIM7sqcKuwNmNkGIWlnBgoTti4atZupgCV8Kk7Nyq2Nkt5Su2IfXwtwHNwjGU7Kpv0cCGRaE17ImCEc9OsDF5FZ/Bf6bOC6HXSMoOrLpEbukSCKKZxqzvlD1L+ioWBLxk0ZuyIOYooehwsqRkLpwU6bJH2IOCU7gtuOXoE1OlPBnz6cYslTbE+fYSqdfBD2lF8CSbTMAZWfqb/CgqEZ1CRDuPHBrd5zsW4ZO4UAwdWXjYhdD1fOwPj2NdSM+ShSlPS735+1RqfMebjOKblASVTVLyJ4i2kDrDfHwjmBZnGsuvFr2TrZ0nDyf+FIqttn11cS1Uocvngr0ejNQrlmwUd4L0bi8ix8NgWr4iErubqXfNP0U8TMvXtJoSjFHCMUr0aSWelqfWmG8VMeFFVuyVZIxSeQCjkIusy9XUBrdd/Jm/L+Y/li/7l812ufn7dvy7+wc="},{"name":"getNumber","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"owner":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"struct","path":"easy_private_state::value_note::value_note::ValueNote","fields":[{"name":"value","type":{"kind":"field"}},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"randomness","type":{"kind":"field"}},{"name":"header","type":{"kind":"struct","path":"aztec::note::note_header::NoteHeader","fields":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"nonce","type":{"kind":"field"}},{"name":"storage_slot","type":{"kind":"field"}},{"name":"is_transient","type":{"kind":"boolean"}}]}}]},"visibility":"public"},"return_witnesses":[1,2,3,4,5,6,7]},"bytecode":"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","debug_symbols":"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uw5916HvOvRdh77r0Hcd+q5D33Xouw5916HvOvRdh77r0Hcd+q5D33XouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL4b0HcD+m5A3w3ouwF9N6DvBvTdgL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwl9N6HvJvTdhL6b0HcT+m5C303ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr5b0HcL+m5B3y3ouwV9t6DvFvTdgr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouw19t6HvNvTdhr7b0Hcb+m5D323ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb470HcH+u5A3x3ouwN9d6DvDvTdgb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwt9d6HvLvTdhb670HcX+u5C313ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996DvHvTdg7570HcP+u5B3z3ouwd996Dv3muXylj/JZfpj6/czVeuYW5gbmHuWO61S/2GnMGcw1zAXMIc7MvAvgzsy8C+DOzLwr4s7MvCvizsy8K+LOzLwr4s7MvCvizsy8G+HOzLwb4c7MvBvhzsy8G+HOzLwb4c6os/Hg+YM5hzmAuYS5grmGuYG5hbmIN9MdgXg30x2BeDfTHYF4N9MdgXg30x2BeDfXHYF4d9cdgXh31x2BeHfXHYF4d9cdgXh30J2JeAfQnYl4B9CdiXgH0J2JeAfQnYl4B9SdiXhH1J2JeEfUnYl4R9SdiXhH1J2JeEfSnYl4J9KdiXgn0p2JeCfSnYl4J9KdiXgn1p2JeGfWnYl4Z9adiXhn1p2JeGfWnYl4Z9GdiXgX0Z2JeBfRnYl4F9GdiXgX0Z2JeBfVnYl4V9WdiXhX1Z2JeFfVnYl4V9WdiXhX052JeDfTnYl4N9OdiXg3052JeDfTnYF+i7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvmvQdw36rkHfNei7Bn3XoO8a9F2DvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7Dn3Xoe869F2HvuvQdx36rkPfdei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6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vhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkDfDei7AX03oO8G9N2AvhvQdwP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8m9N2EvpvQdxP6bkLfTei7CX03oe8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkHfLei7BX23oO8W9N2CvlvQdwv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe829N2GvtvQdxv6bkPfbei7DX23oe8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kDfHei7A313oO8O9N2BvjvQdwf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8u9N2FvrvQdxf67kLfXei7C313oe8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQdw/67kHfPei7B333oO8e9N2DvnvQd4/5bj6Y7z5zBnMOcwFzCXMFcw1zA3MLc7AvBvtisC8G+2KwLwb7YrAvBvtisC8G+2KwLw774rAvDvvisC8O++KwLw774rAvDvvisC8B+xKwLwH7ErAvAfsSsC8B+xKwLwH7ErAvCfuSsC8J+5KwLwn7krAvCfuSsC8J+5KwLwX7UrAvBftSsC8F+1KwLwX7UrAvBftSsC8N+9KwLw37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"},{"name":"compute_note_hash_and_nullifier","function_type":"Unconstrained","is_internal":false,"abi":{"parameters":[{"name":"contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"},{"name":"nonce","type":{"kind":"field"},"visibility":"private"},{"name":"storage_slot","type":{"kind":"field"},"visibility":"private"},{"name":"note_type_id","type":{"kind":"field"},"visibility":"private"},{"name":"serialized_note","type":{"kind":"array","length":3,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"contract_address":[{"start":0,"end":1}],"nonce":[{"start":1,"end":2}],"note_type_id":[{"start":3,"end":4}],"serialized_note":[{"start":4,"end":7}],"storage_slot":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"array","length":4,"type":{"kind":"field"}},"visibility":"public"},"return_witnesses":[7,8,9,10]},"bytecode":"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","debug_symbols":"7d3djivHdQXgdznXRtBVtXf96FWCXCiJAxgwbMMSAgSG3j0tRDM6RgaaZMxDfjXsK0kD9unV1Tprszj8yL99+eOf/+37H//w5z/98OW7v305/qnGl+/++W9ffvjL93/6+Qc//Pj9X3/88t3xuy+//9O/n//86Xdf/uMPf/z9l++i/fS7//Ww3sovD+yRrw+d+cZDyxi/PLQev/6prfz0L7/7OUUSKTqRYhApJpFiCSnaQaQoRIpKpGhECqI7G9GdjejORnRnI7qzEd0ZRHcG0Z1BdGcQ3RlEdwbRnUF0ZxDdGUR3BtGdSXRnEt2ZRHcm0Z1JdGcS3ZlEdybRnUl0ZxLd2Ynu7ER3dqI7O9GdnejOTnRnJ7qzE93Zie7sRHcOojsH0Z2D6M5BdOcgunMQ3TmI7hxEdw6iOwfRnZPozkl05yS6cxLdOYnunER3TqI7J9Gdk+jOSXTnIrpzEd25iO5cRHcuojsX0Z2L6M5FdOciunMR3VkOojzLQbRnOYj6LAfRn+UgCrQcRIOWg6jQchAdWg6iRMthtGgxWrQYLVqMFi1GixajRYvRosVo0WK0aDFatBgtWo0WrUaLVqNFq9GiBjgqhjgqBjkqhjkqBjoqhjoqBjsqhjsqBjwqhjwqBj0qhj0qBj4qhj4qBj8qhj8qBkAqhkAqBkEqhkEqBkIqhkIqBkMqhkMqBkQqhkQqBkUqhkUqBkYqhkYqBkcqhkcqBkgqhkgqBkkqhkkqBkoqhkoqBksqhksqBkwqhkwqBk0qhk0qBk4qhk4qBk8qhk8qBlAqhlAqBlEqhlEqBlIqhlIqBlMqhlMqBlQqhlQqBlUqhlUqBlYqhlYqBlcqhlcqBlgqhlgqBlkqhlkqBloqhloqBlsqhlsqBlwqhlwqBl0qhl2qhl2qhl2qhl2qhl2qB9Gi1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBL1bBLFfmyJOTbkpCvS0K+Lwn5wiTDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLlXDLjXDLjXDLjXDLjXDLrWDaNFm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KVm2KUw7FIYdikMuxSGXYqDaNEw7FIYdikMuxSGXQrDLoVhl8KwS2HYpTDsUhh2KQy7FIZdCsMuhWGXwrBLYdilMOxSGHYpDLsUhl0Kwy6FYZfCsEth2KUw7FIYdikMuxSGXQrDLoVhl8KwS2HYpTDsUhh2KQy7FIZdCsMuhWGXwrBLYdilMOxSGHYpDLsUhl0Kwy6FYZfCsEth2KUw7FIYdikMuxSGXQrDLoVhl8KwS2HYpTDsUhh2KQy7FIZdCsMuhWGXwrBLYdilMOxSGHYpDLsUhl0Kwy6FYZfCsEth2KUw7FIYdikMuxSGXQrDLoVhl8KwS2HYpTDsUhh2KQy7FIZdCsMuhWGXwrBLYdilMOxSGHYpDLsUhl0Kwy6FYZfCsEtp2KU07FIadikNu5QH0aJp2KU07FIadikNu5SGXUrDLqVhl9KwS2nYpTTsUhp2KQ27lIZdSsMupWGX0rBLadilNOxSGnYpDbuUhl1Kwy6lYZfSsEtp2KU07FIadikNu5SGXUrDLqVhl9KwS2nYpTTsUhp2KQ27lIZdSsMupWGX0rBLadilNOxSGnYpDbuUhl1Kwy6lYZfSsEtp2KU07FIadikNu5SGXUrDLqVhl9KwS2nYpTTsUhp2KQ27lIZdSsMupWGX0rBLadilNOxSGnYpDbuUhl1Kwy6lYZfSsEtp2KU07FIadikNu5SGXUrDLqVhl9KwS2nYpTTsUhp2KQ27lIZdSsMupWGX0rBLadilNOxSGnYpDbuUhl1Kwy6lYZe6YZe6YZe6YZe6YZf6QbRoN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+xSN+zSMOzSMOzSMOzSMOzSOIgWHYZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdGoZdmoZdmoZdmoZdmoZdmgfRotOwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS9OwS8uwS8uwS8uwS8uwS+sgWnQZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdmkZdqkcBl46cxA9euYgivTMQTTpmYOo0jMH0aVnDqJMzxxEm545iDo9cyB9ajCmMwfSpwZkOnMgfWpQpjMH0qcGZjpzIH1qcKYzB9KnBmg6cyB9apCmMwfSpwZqOnMgfWqwpjMH0qcGbDpzIH1q0KYzB9KnBm46cyB9avCmMwfSpwZwOnMgfWoQpzMH0qcGcjpzIH1qMKczB9KnBnQ6cyB9alCnMwfSpwZ2OnMgfWpwpzMH0qcGeDpzIH1qkKczB9KnBno6cyB9arCnMwfSpwZ8OnMgfWrQpzMH0qcGfjpzIH1q8KczB9KnBoA6cyB9ahCoMwfSpwaCOnMgfWowqDMH0qcGhDpzIH1qUKgzB9KnBoY6cyB9anCoMwfSpwaIOnMgfWqQqDMH0qcGijpzIH1qsKgzB9KnBow6cyB9atCoMwfSpwaOOnP8Q32a/SXHOP7BHBPJsYgc5R/zUTfMUZAcFcnRkByB5EgkR0dyGH1aDqNPy4H0aUH6tCB9WpA+LUifFqRPC9KnBenTgvRpQfq0IH1akT6tSJ9WpE8r0qcV6dOK9GlF+rQifVqRPq1InzakTxvSpw3p04b0aUP6tCF92pA+bUifNqRPG9KngfRpIH0aSJ8G0qeB9GkgfRpInwbSp4H0aSB9mkifJtKnifRpIn2aSJ8m0qeJ9GkifZpInybSpx3p0470aUf6tCN92pE+7UifdqRPO9KnHenTjvTpQPp0IH06kD4dSJ8OpE8H0qcD6dOB9OlA+nQgfTqRPp1In06kTyfSpxPp04n06UT6dCJ9OpE+nUifLqRPF9KnC+nThfTpQvp0IX26kD5FfFRBfFRBfFRFfFRFfFRFfFRFfFQ9jD6tiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI+qiI9qiI9qiI9qiI9qiI9qh9GnDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRDfFRgfioQHxUID4qEB8Vh9GngfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjAvFRgfioQHxUID4qEB8ViI8KxEcF4qMC8VGB+KhAfFQgPioQHxWIjwrERwXiowLxUYH4qEB8VCA+KhAfFYiPCsRHBeKjEvFRifioRHxUIj4qD6NPE/FRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHJeKjEvFRifioRHxUIj4qER+ViI9KxEcl4qMS8VGJ+KhEfFQiPioRH5WIj0rERyXioxLxUYn4qER8VCI+KhEflYiPSsRHdcRHdcRHdcRHdcRH9cPo0474qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qI74qIH4qIH4qIH4qIH4qHEYfToQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQHzUQ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xKo/6d705h8oNZ90u3n7hXzSHeTtF/JJN4W3X8gn3efdfiHjWsjbLOST7sZuv5BPusG6/UI+6Z7p9gv5pNug2y/ktbO5zUKua2dzo4W8djY3WshrZ3Ojhbx2NjdayPhEC/nAj5FZn2lj88h1/Ez7mkeu42fa1jxyHT/TruaR6/iZNjWPW8fzj7vW8Sbr+Jm2NI9cx8+0o3nkOn6mDc0j1zGudbzJOl77mdus47Wfuc06XvuZ26zjtZ+5zTpe+5mbrGO5+7x+/fyWssp8Zx3X69Wu+DXFmK/pc+v0fev0Y+v0c+v0a+f09/9C8pumL1unr1unb1un33rW1q1nbd161tatZ23detbWrWdt23rWtq1nbdt61ratZ+39v4nypum3nrVt61nbtp61betZ27aetbH1rI2tZ21sPWtj61l7/6/6umn6rWdtbD1rY+tZG1vP2th61ubWsza3nrW59azNrWft/b+G5qbpt561ufWsza1nbW49a3PrWdu3nrV961nbt561fetZe/8vs7hp+q1nbd961vatZ23fetb2rWft2HrWjq1n7dh61o6tZ+39P5z7pum3nrVj61k7tp61Y+tZO7aetXPrWTu3nrVz61k7t5619/801Zum33rWzq1n7dx61s6tZ+3cetaurWft2nrWrq1n7dp61t7/8/1umn7rWbu2nrVr61m7tp61a+dZ24+dZ20/dp61/dh51vZj51nbj51nbT92nrX92HnW9mPnWduPnWdtP7aetWXrWVu2nrVl61lb7j1r13oJVMtxi++A7Hf/8KhvcAm5/yX0/S9h7H8Jc/9LWNtfwt0/WuobXELZ/xLq/pew/3S++8dNfYNL2H861/2nc91/Otf9p3Pdfzq3/adz2386t/2n8w08XevxsplvfcZvX0KW8stjsx5fBeovgW5A5G4cqGiBqhaoaYHizoEiXgJlvBko7x3o1882zzcDdS3Q0AJNLdDCAo1DC3Tvpm4vf3C2/magqgVqWqDQAqUWqGuBhhZoaoEWFmgeWiCtqafW1FNr6qk19dSaempNPbWmnlpTT62pl9bUS2vqpTX10pp6aU29tKZeWlMvramX1tQLa+pxYE09Dqypx4E19Tiwph4H1tTjwJp6HFhTj7ffYx399RcAX/1a7vUdquPt9za/e1T50FH1Q0e1Dx0VHzoqP3TUm/8r5GwvR603jxofOmp+6Kj1kaPefqPdu0eVDx1VP3TUm/9v5Hr5xXU/+ltHxYeOyg8d1T901PjQUfNDR62PHPX22zx6vh7V3zyqfOio+qGj2oeOig8dlR86qn/oqDf/3zh/gfJy1Hzrb8rb3xn07lHrI0e9/R057x5VPnRU/dBR7f931Pkf//n9X//w/b/+8fc/nAec//njf/3lf/71p/8G"},{"name":"setNumber","function_type":"Secret","is_internal":false,"abi":{"parameters":[{"name":"inputs","type":{"kind":"struct","path":"aztec::context::inputs::private_context_inputs::PrivateContextInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"private_global_variables","type":{"kind":"struct","path":"aztec::context::globals::private_global_variables::PrivateGlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]}}]},"visibility":"private"},{"name":"number","type":{"kind":"field"},"visibility":"private"},{"name":"owner","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]},"visibility":"private"}],"param_witnesses":{"inputs":[{"start":0,"end":36}],"number":[{"start":36,"end":37}],"owner":[{"start":37,"end":38}]},"return_type":{"abi_type":{"kind":"struct","path":"aztec::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs","fields":[{"name":"call_context","type":{"kind":"struct","path":"aztec::protocol_types::abis::call_context::CallContext","fields":[{"name":"msg_sender","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"storage_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"function_selector","type":{"kind":"struct","path":"aztec::protocol_types::abis::function_selector::FunctionSelector","fields":[{"name":"inner","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"is_delegate_call","type":{"kind":"boolean"}},{"name":"is_static_call","type":{"kind":"boolean"}},{"name":"is_contract_deployment","type":{"kind":"boolean"}},{"name":"start_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"args_hash","type":{"kind":"field"}},{"name":"return_values","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"max_non_revertible_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"read_requests","type":{"kind":"array","length":32,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"nullifier_key_validation_requests","type":{"kind":"array","length":1,"type":{"kind":"struct","path":"aztec::protocol_types::abis::nullifier_key_validation_request::NullifierKeyValidationRequest","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"secret_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_private_key::GrumpkinPrivateKey","fields":[{"name":"high","type":{"kind":"field"}},{"name":"low","type":{"kind":"field"}}]}}]}}},{"name":"new_note_hashes","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffect","fields":[{"name":"value","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"new_nullifiers","type":{"kind":"array","length":16,"type":{"kind":"struct","path":"aztec::protocol_types::abis::side_effect::SideEffectLinkedToNoteHash","fields":[{"name":"value","type":{"kind":"field"}},{"name":"note_hash","type":{"kind":"field"}},{"name":"counter","type":{"kind":"integer","sign":"unsigned","width":32}}]}}},{"name":"private_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"public_call_stack_hashes","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"new_l2_to_l1_msgs","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"end_side_effect_counter","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"encrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"unencrypted_logs_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"encrypted_log_preimages_length","type":{"kind":"field"}},{"name":"unencrypted_log_preimages_length","type":{"kind":"field"}},{"name":"historical_header","type":{"kind":"struct","path":"aztec::protocol_types::header::Header","fields":[{"name":"last_archive","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"body_hash","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"state","type":{"kind":"struct","path":"aztec::protocol_types::state_reference::StateReference","fields":[{"name":"l1_to_l2_message_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"partial","type":{"kind":"struct","path":"aztec::protocol_types::partial_state_reference::PartialStateReference","fields":[{"name":"note_hash_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"nullifier_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"contract_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}},{"name":"public_data_tree","type":{"kind":"struct","path":"aztec::protocol_types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot","fields":[{"name":"root","type":{"kind":"field"}},{"name":"next_available_leaf_index","type":{"kind":"integer","sign":"unsigned","width":32}}]}}]}}]}},{"name":"global_variables","type":{"kind":"struct","path":"aztec::protocol_types::abis::global_variables::GlobalVariables","fields":[{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}},{"name":"block_number","type":{"kind":"field"}},{"name":"timestamp","type":{"kind":"field"}},{"name":"coinbase","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"fee_recipient","type":{"kind":"struct","path":"aztec::protocol_types::address::AztecAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}}]}},{"name":"contract_deployment_data","type":{"kind":"struct","path":"aztec::protocol_types::contrakt::deployment_data::ContractDeploymentData","fields":[{"name":"public_key","type":{"kind":"struct","path":"aztec::protocol_types::grumpkin_point::GrumpkinPoint","fields":[{"name":"x","type":{"kind":"field"}},{"name":"y","type":{"kind":"field"}}]}},{"name":"initialization_hash","type":{"kind":"field"}},{"name":"contract_class_id","type":{"kind":"struct","path":"aztec::protocol_types::contract_class::ContractClassId","fields":[{"name":"inner","type":{"kind":"field"}}]}},{"name":"contract_address_salt","type":{"kind":"field"}},{"name":"portal_contract_address","type":{"kind":"struct","path":"aztec::protocol_types::address::EthAddress","fields":[{"name":"inner","type":{"kind":"field"}}]}}]}},{"name":"chain_id","type":{"kind":"field"}},{"name":"version","type":{"kind":"field"}}]},"visibility":"public"},"return_witnesses":[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308]},"bytecode":"H4sIAAAAAAAA/+1dCXxcxXmfXV2rY2X5li3ZfrIOH5KlXR22RIAs5j6SACGFQALIaG1EbIvIMuAkQBJCQm4IJJBAIISE3Af0btrmaJsW2gZo0zRt2oakLaRHmjTp3cbNfKv3ef8ajWRp/c3y3m80v9/seztv3sz//828b2a+NzPvjIRSbdqTo0NS+wrtA/hfGZ7z/yrjf7Xxv8a4v9b4nzb+LzP+Lzf+rzT+rw7/owspqFx4HMjsHBzM7+rPZweyo5n+kT3DQ5nBoT07h7PD2aHhobH+4YGB/PDg8K6RPSO7MiPZwYF8du/QyMDezLTrgrQyJ+gIWwowd2h/VPvO8Njl2bFH+y1hmaFctngqD5TLVjX9/LFLwPk2Nf0sqVBu7AIlVFcHM9lqSqRSWR0911XheT3ES4ZhTRDGuOu0bwzP9+WnLh49ODZx4Kzx/P4xZJa0sDUd5VhhxK+Hc75Wa0snFx4zJ+aymKa0ytkuiJMfLRYOpY0qh1x3KDSb0BPCcutWsuqUHT0yXCWrLfjZVVjOUxDvqHJTR2zybbLgdFphXRRmj4N0dyi5h8kV7x3yZZRRlgrhQqaZE3RxVBY1gLM3PPZx2uGRn9j+8DgQHge1bwjbM0ft7TC2t6ZssXXjOMSnAa4njDa4cE8YVgFhFZUzkimEVYZ/sE2vCsOqIawa8uawGkMuTYCF46XUTGWbC88zJ+hSgC8QTLcgEzXTmWUSwHk1cKuSx5N1xTOliuUmLb9qtXD5peBY40h+LnhSmnWO5JdSC5dfHciv1pH8XPCkdBscya9OLVx+DSC/ekfyc8GT0m10JL8GtXD5NYL80o7k54Kno3QLeJc5wsuDhqQw3pXyeIepHi1XC69HK6EerXBULg54FsplFfCTSpfSWA3yWW7IKQ3XV4HsVjuQXQLy5bT5/2pL3oID6YIc1hxHDmssWNaUWQ6IcQnvEt4lvNHDuyoCeCnvteJ5Z3fVG3mTm6+9XetYFm54TrcHzcBjpcEnDdexfjY74JiAfDlt/o8Yl/Au4V3Cu4R3Ce8S3iW8S3iX8C7hXcK7hHcJ7xJe3/FS3uvk8x6oN/ImlzD+B3C+zrEsHPEs2EPWA4+1Bp80XMfyXu+AYwLy5bT5P2JcwusObxquJwGPg7qXXcjzhHgSEcBTr+xzrNYZMqMwlinOoWoJz3EOVWt4jnOoNoTnOIdqY3iOc6g2qaJMOCwIz2shrC08r4OwzXDOx/bwHOeHdYTnaQjrDM8bIawrPF8GYVvC8yYI2xqeL4ewbeH5CgjbHp6vhLDu8HwNhPWE52shjOdYNkMYlw2WJZfNegjjsmmBMC6bVgjjstkAYVw2GyGMy2YThOFcGw7jsmmDMC4bLCsum3YI47LpgDAum04I47LpgjAumy0QxmWzFcK4bLZBGJfNdgjj9yTdEMa6rQfCuAy5rEh25yWK1/l+fKY4H3ymdljy67Hg4nPUI3xPoGT1COYVwH/OrwFwbI8InqQFD5d1Tg5PYc7DVnmew8SN63B1mDbj5/wqIU5lWAD8THA4Oa5T20A+3UY85JFTsn29Lkfy6TTkw/i7QD7H9IUhHw5H+WwF+Wwx4iGPnBLj0U/pdjiST7shH8bfAfLhOCsM+XA4yqcL5NNpxEMeOSU3dqF0NzuST5shH8a/GeTDcdYZ8uFwlE8HyKfdiIc8ckqMxyCuF5SWzyZDPlgOLB+OExjy4XCUz2aQT5sRD3nklBiPIUp3oyP5bDDkw/g3gnw4zhZDPhyO8glAPpuMeMgjp8R47KR0Wx3Jp8WQD+NvBflwnF5DPhyO8tkI8tlgxEMeOSXGY5ej8eswjl9ZPox/PciH4wwZ8llnkU8ryKfFiJeCeAkl2x/j/imvg+82cFVCnBcBD+wXY3+d42Jfn3ngOIHlhGMMXtOE4xNe34RjG17rhOMi7jNi35v75tjX5zEVjr14TIVjLx5T9UIYj6n6IIzHVIypVjmzm/SjLNkljP8BnKMthe/Dse56QxaEu0Ued6GerTcw8v8WwMhhKwCPK/tTlYHHrAMu864x8q4pY961Rt61Zcy73si7vox5p42802XMe5WR9yoj77lsna7wKAOPmgdPc8TwrIwYnlURw7MsYnjqIoanPmJ4KiOGpypieJZHDE85+iaLwdMYMTypiOGpjRieiojhWRcxPGsjhqcc78IXg2dNxPA0RQxPQ8TwpCOGpzpieGoihicRATxzze3g6/gemu0n+B4abbQcxvYznNvBNlmc28G2N5zbEaiiTDiM7XY4t4PfEeDcDrT58RHftXAY2wtxbge/s8K5HWxrxLkdW8NznNvB70txzga/T14FYSxLlD3LEu2LLEucd8GyRNskyxLnXbAs0a7JsgwgjGWJNlGWJc67YFmibFmWOO+CZYm2WJYlzrsw3zvjXAycd8F9cZx3wf1hli1x/WlF8Trfj3WW88E6u92S3zYLLj7H59TBO/zCc4p5BfAf3zUnDIwvNJ6aiOGpjhiedMTwNEQMT1PE8KyJGJ7VEcOzNmJ41kUMT0XE8NRGDE8qYngaI4ZnRcTwLI8YnqqI4amMGJ76iOGpixieZRHDsypieFZGDE9zxPAky4iHx6Octjmnm/J2MM+4ME+9U5xTdhdxYnuBOc+Y86uEOB2hsPmZ5XByPH7HecZbjXhueExvot9hlM1Wg0fSgicwMOXkMBXmzreLc50uM7YFcZmZ87krIU6vUWYcTm67IaMGNXsedUo5mcNdeJ5WAJYA/tvyltyLEdfUcvrUjxlKFvPtks93hk6jsrsVcOC6B45zerKIbSRZLCNz3h7afPF93gaQbU6QA+fFafN/zg/nsKK91Fzjibhtczlt6+M4Ps+zdLA+JYPlxGmb5ZSE8y0QzyzjAOKx/sEyPhfK+EshSUf1bwixJi2cUGcJ5lv4FAGu2Wk35JZUs9fs5EI8baooWxk80zo0UDPLiPNvgzLiOBcbOpTDyW03uFDd32zES8G59MdZsJ52GvkmgQ/Hy4V4NkFcGTzTcsV3SoGavVakEuJcYciVwxXItQ3kusWIl4LzhJJ9/tsAS8KSN9bZNoinjHtta60c9IHm7Z92WuQlmHc/vr9DmSkDjzJk6KiNGsB3mwvBg+t05J+L6b6gA56FcQG3h9J7VbdYyos5pNXs9j2l3K0d2GCUm7l+aAmvW7yEp9PAinMKOiOCkcPwPXuzIUfqZ90K/XwH/Z0Bwst9Ku7nMw4co3GcL1cUsd0G/XxzLI7zLlDmAcglJ8Mha7aBgZrZF2OMtrWyrtq3dgNPu0UWL2TeLIOcktXxgTynQh011wib5YtrhO8y+mq4RpjrKfbVOo14yCOnZNtWB32aAdQ5C1kjfJ8hnw0W+QQgnzKtEe7HPkIgLJ/FrBF+yJBPi0U+x1sj7GCsn8U5auzm6yviWNlFW4fz3haCx7aGWhpPyyLwYH/FxfxJtBktBA+u7+t2hGf9IvB0A54eR3i6F4GnB/DscISnZxF4GAP158w2lsL42dgEYVw/sf/MdQT3DONy2gxh5t5OacCLNh0OQ5ukbf20i2cwoeZeP437BjAXnCfM52zry6mZuisnh3MYbcPJMF1znTfqBUGbTdZR/S1w4j0AzL0ecI8EjvMktHMpCJfE5OpZpTT6gJNtLwi+/hTYrZ8Jz7Htwn0lnrVcZzefLmDZEd+sPN+CnY+/k8tlm7XkPQBYhfLOYt6J0HM+HF4J599lBQXxyLGcGTfpgYwlHp53Gfek4XrGwjsQ5o1fFQ/gP+dHdeabUL+etYzXJTEhb5RPK8iHr6PuwnY2p2bqfsbbJ4+3oJP4meR6y1jw+eU4PzB00g4HmBxxLZRNL3Bqt/Dk6z+EOvMj0DlcLlyudP2o5Tq7hfRPXgidhHlHQSf9bA6dZOqXheikVuOeKOqkn0D9Ogo6yUU/HnmjfLpBPnyd+8emnSqnZo55GK8DG5m1n2T23/FZrQ5tnq77SS7sgZQG6p8eC89je0SBbTcN66K4XNAu3Wq5zm6h/aSMPN8MPh9cthlL3qg7hPKe8WyyTuJ8OLwSzlt4ogjEI8dyZtykk3ZY4uF5t3FPGq7vsPAOhHnj8x/Af86P6kwT1K9Wy/wRSUzIG+XTDvLh6zw+RzuzCrFgH47xutrHkJ9DrreMBW2UHKfD0Eku+m6ubASUBuqfLgtPvr4N6kw36BwuFy5Xun6S5Tq7+XQSy85RfzODzweX7Q5L3qg7hPKe8WyyTuJ8OLwSzkdAJ2E/wxxfk07qtcTD83bjnrSyj1kd9E2zOO7gtHcYGKnO9EL9Ogl0kqt+Uq9FPmgf5OtsH8R3OyrEgvM+GK8De7F172vGwvnhs7rb0Eku+m6ubOOUBuqfHgtPvn421JlzQedwuXC50vXLLNfZzaeT8F2tg/5mxjYu77XkjbpDKO8ZzybrJM4H7Xd8finoJOxnsJwZN+mkPks8PN9k3INjkz4L70CYNz7/Afzn/KjOXAD167Iy9JP6LPLB9xPH+hzhkXjge5KcmjlnjPG66ifxM8n1lrHg88txrjZ0kgs9GYV+Uh7qzD7QOeY8I7p+g+U6u/l0Er4PLLdOwryjoJMOz6GTTP2yEJ20wbgnijrpOqhfN4BOcmXj7rPIpwfkw9f5/WhCzVwvlFMz+3CM18GcWWs/ibHgXHKOc0uZ+kku5gdTGqh/2i08+fptUGduB53D5YL7PN1juc5uof0kB2PgjM1W2GfJ29We972QLuoofM/A53eDTsKxD8uZceP7d4yH5z3GPWgv6bbwDoR54/MfwH/Oj+rMHVC/7ilDP6nbIp/55mfYbNybARvjddVPMudMMhZ8fjnOA4ZOcqEno9BPehjqzCOgc7hccC7A45br7ObTSTiPtNw6CfOOgk56bA6dZOqXheikzcY9UdRJj0L9ehx0kov1rcgb5YM2br6+BcLWGfHRXorzw1zoUVMnBvC/CzByGPYRHK85nbVG0VxzimuxtwCuoeOsgwiMMFd9s4SaqYcC+M/54ToIMy47Xv/RFh6TarbNMadcrdGbXptpzmfn/G3z2Z+EtkupmWPa7Rb+gREP+TUb/Mo1H932rofjPGO0zQ7mcg+4bJvxO1O2Pghf/xbozm9bbBQ4J+b5Em0YOLfTgY3fasPoseSNbahQ3lYbBudjs2E8B20z2gDMeZHYNmM8PLeN0W22Gwd2o6xpjwzgP+dHdeY7UL+eh7bEwZqcWW2zaYfDtjmAsE4jPr43wPbDhd0FxwyctvlOI61m62Ls30i3x7g2utkim2YDi7lmcqUjOc21Hwx+88dV3lVG3lVlzLvGyLumjHnP9T2wcuRdb+RdX8a800be6TLm/cLU82zhe5hrHKRL5YbfOCM3X38Bv2GxWhxPJlunivua7stPvXRiKn8oAbgY61oDa0LNxM3XGyAsCecVcF+lms2/2hKWsoTVWcIa1GzXCOfL4LwJzldCGsvDcxsPjmOWUznCjxeP8VK94rqCe/bz9dUQxuWyBsIqjPRqlQVPLjxmTswVHmwCMWjJJGnkNZDZOTiY39Wfzw5kRzP9I3uGhzKDQ3t2DmeHs0PDQ2P9wwMD+eHB4V0je0Z2ZUaygwP57N6hkYG9YWaSHdysXFoZl5y7BTkPCHLmh5orG3WOqcPWFx4z4ZHckCoqAZZPd3h9COLtDNOb66FSgrLoV7KyYLdLFTtR1Rb87Cos5ymIJ935xbxMLE0WnM4UBiYulWZ/KHjpdIeV3IPsivewfBk5VWiDgmmNKNmGbKEK7SQ1t0I7CeK9yBIvEV5/UXikHtTJaqaTlrlkPT7lBZL5qfPI/FSI9+J5ZP5ikHnOEq9fFRXv0RDXaZCGUrK65WRLuidaPkMJWT0gzfuUUKbSvHcm3Oi/CmGcuwVlKVjWWVfyM3VZ5sRctkawLE5XsrqMuFKagSrqloXotjPU3LrtDIh35iLTPWuedM+CeGeruXXm2aqoM89ZZP7nzpP/uRDvvHnyPw/yP1/NrbPPV0WdfQGkQS4XHjMn5go6+xwlr7tGYqCzL3DA+6SY6OyXCMpSsKyzkvIr18C7Ty6tDL69eGl4fFl4vDA8XhQeL1bFsRJaIwMpPIOZnYUBf+VMubFDax3HobYMvxqaCMOTeE8Yhl+NrKickcz0lzrDP/il06owjA0RTZAHfvG+SloWWhpoiWQ3n3Uc8VTK4ylYx9lKTNbxw/v3j+8dz0+enz9y4ej4JNo9GHalAds02JrXySUtYY5EnDUN8AH8R3Fy8efk8i5s0Fkjz2mQm3elipMeGH8NyJ3jsOF7GfBlVwHpkGsw5MLHGnn5FDbmqnUknzpDPoy/FuTDcTYY8qmzyKcG5JMy4iGPnBLjUdigs96RfBoM+eDHmlk+5oeDl4EMTPnUwrU6Ix7yyCnZSVRpR/JpNOTD+NMgH47Tbcin0SKfepBJgxEPP76MzRrnhc2V+QzjB5mxmVwO+XFY0pJvhcGr0EwafArNZHiOH9JmncF5OX2JppR8P4vsrGcq+T77KREfq5BN+CUOeJ8ak7HKywVlKVjWWUn5mTYI4kxj/4vD40WqaFu4RC3OZvEKNbfN4hUQ7xfC9I716cFJ1+lLVLSfucFQHko23RkvVi9VxYbG0fhtAMdvZrnaxm/YyCRgTFeD9xjpNUEY88OxycGJqfG9R3h4MkazeBY65jDPKyxhDKvKSA/p8TXnbZ4yyEilfalyo6ulbdlofz5RvX+ZIC62ZVOagZqtP6nTTHqwMzxuU0W9+Eo1t/58JcS7PEzPnEHmoj4ITqLJWOCWlPae4f492Xx2ZGgsM9qvC3JsYHAIjQ+uZNHhQBbSGDtjgHGbclOnpHFerty0x1eo4oDJUXu8C9tjc1bpQttjJ/bEwWkDhgujHg4+q+awE1db+hTVRp/CkYFu3lUDnB9h5YHzdH/m9Mn86NTs3gzfYOvhIEFytmnHqCyrLfdz/IQlHXIkzJSBBSsWX4ttT+gKFY+eEPZeTrQn9Col3xOiNANVvumpki2g7dXGq7W/Uvur1MxvMbELlJimHCzlrRiuCXGgvbOOtPeAI617zOJBzjT74ysNNlUnlOwzkIJ0E5BPCoqOz3GdD66z4nLG1w3Vlnh4Xmnck4br1RbegTDvudaocX5VEIZvV3FKt4t6FsW3q6xH9NvVCw/v2T9+jX61etrBsQtHJ6fGR/efNjY2mT90yKaMKgwCc7XYx3vPinYNfDdh9gxstg4UKFZKZ62+OUYmjUxj4yvDI63wvlrNHktfHV6/KjzSi4xRA6PZOp9oiyrYGmVH5dIqzFkxxwVKybfGgtrU6VgvLnYOlzJ4dUzK6kol2ztYshv5ZzfCBpN1/h7tr1Ezd/tkFyixHvQo9urN1b0Ltc3gC/kkhB1rxCHsWCMOeYr3tAczQylV5COWbjhvHXfEcjCqGXbU2+xfGtUUdwdRyo9RDU+aoVFNyrA3usRm6quUga1OFe3O+QPjU2cevGbyyPXatnjBxD7srGOdUYZskQs5bDvRfFhluRflZw4YbG6uwQzx4glMgZJ7VklX2nZWQBfAuW0imyCerCOehfYZdzMxJ+al4To+1w4m1WVx0iGnjTjMvAUXdxfk0HgcOTRasDSWWQ44Ma/BwFpvXOdj0uCCfQiOH8uJeTuV/AS104QnqEnzpol5ux3w3i3Mm530xLwxQVkKlnV2d8TrDU8uk643eeWm3ki/GpPkvDcmnBOCnPfFhHNSkPO1MeFcIch5PCacKwU5XxcTzlVKjvNrVDw4Vwty3h8TzpKbMxyICeetgpwPxoRzlyDnCQ85X+8h59d6yHnSQ86HYsJ5TJDzVEw4S7bPh2PCWbJu3+Ah5xs95HyTh5yPeMj5dR5yfr2HnN/gIeebPeR8i4ecb/WQ8xs95PwmDzm/2UPOt3nI+S0ecr7dQ85v9ZDz2zzkfIeHnN/uIed3eMj5nR5yfpeHnN/tIef3eMj5vR5yvtNDznd5yPl9HnK+20PO93jI+f0ecv6Ah5zv9ZDzfR5y/qCHnD/kIef7PeT8gIecP+wh5wc95PyQh5w/4iHnhz3k/FEPOT/iIeePecj54x5yftRDzp/wkPMnPeT8KQ85f9pDzp/xkPNnPeT8OQ85f95Dzl/wkPMXPeT8mIecH/eQ8y/GhPPLBDn/Ukw4XyjI+ZdjwvkiQc6/EhPOFwty/tWYcL5ckPOvxYSz5Gejfj0mnCXbqt/wkPOXPOT8mx5y/i0POf+2h5y/7CHnr3jI+asecv6ah5x/x0POv+sh59/zkPPXPeT8+x5y/gMPOT/hIecnPeT8hx5y/iMPOf+xh5y/4SHnpzzk/LSHnJ/xkPOfeMj5Tz3k/E0POf+Zh5y/5SHnP48J50sEOX87Jpzzgpz/IiacTxfk/Jcx4Sz5PH/HQ85/5SHnv/aQ8994yPm7HnJ+1kPO3/OQ8/c95Py3HnL+Ow85/72HnJ/zkPPzHnL+gYec/8FDzv/oIed/8pDzP3vI+Ycecv4XDzn/yEPOP/aQ8796yPknHnL+qYec/81Dzv/uIef/8JDzf3rI+b885PzfHnL+Hw85/6+HnP/PQ84/85DzUQ85/7+HnFXCP84JDzknPeRc4SHnSg85V3nIudpDzjUeck55yLnWQ851HnKu95Bzg4ec0x5ybvSQ8zIPOTd5yHl5TDi/SpDzCg/LeaWHnFd5yHm1h5zXeMh5rYecm2PCOSXIeV1MONcKcl4fE851gpxbYsK5XpBza0w4Nwhy3hATzmlBzhtjwrlRkPOmmHBeJsg5iAnnJkHObTHhvFyQ8+aYcF4hyLk9JpxXCnLuiAnnVYKcO2PCebUg566YcF4jyHlLTDivFeS8NSacmwU5b4sJ53WCnLfHhPN6Qc7dMeHcIsi5JyacWwU574gJ5w2CnHtjwnmjIOe+mHDeJMg5ExPOgSDnbEw4twly7o8J582CnAdiwrldkPOgIGedlKoI0+oC/olQBnStUvsq7au1r9Ge3kPRexl6T0F2e7Jjk12X7Jxk9yM7GNmFyE5CdgMaR9O4ksZZNO6gfjj1S6mfRv0WasepXSM9T3ov0J6eC6onJLcO7TsB21Phca/2+7S/Vvtx7a/T/jXa79f+gPYHtZ/Q/nrtX6v9pPaHtJ/S/rD2N2h/o/Y3aX9E+9dp/3rt36D9zdrfov2t2r9R+zdp/2btb9P+Ldrfrv1btX+b9ndo/3bt36H9O7V/l/bv1v492r9X+zu1v0v792l/t/b3aP9+7T+g/b3a36f9B7X/kPb3a/+A9h/W/kHtH9L+I9o/rP1HtX9E+49p/3HtH9X+E9p/UvtPaf9p7T+j/We1/5z2n9f+C9p/UfvHtKfvw9P30un74fQ9bfq+NH1vmb4/TN/jpe/T0vda6ful9D1P+r4lfe/xK9p/VfuvaU/fi6Pvp9H3xL6uPX1vir6/RN8jou/z0Pdq6Pst9D2Tb4Rl9bT29D0E+j4A7ZdP+8fTfuq0vzjtt037T9N+zLQ/Me3XS/vX0n6utL8p7ff5rPbf0/772tN+gbR/Hu0n95z2tN8Y7b9F+1HR/ky0XxHt30P72dD+LrTfyY+1p/0waH8I2i+B9g+g9fS0vpzWW9P6Y1qPS+tTab0mrV+k9Xy0vo3We9HDQOuBaH0MrReh9RO0noDm19N8c5p/TfORaX4uzVel+Zs0n5Hm99F8N5r/RfOhaH4QzZeh+SM0n4LmF9D7dnr/TO9j6f0kva+j91f0Pofeb5C9n+zfZA8m+yjZC8l+RvYksq+QvYHG3zQepfEZjVeo/079WerfUX+HHnJqD6l9IH1J+qNNFd2q8HhyeHz51MTk6L58cGj/xFSQCQ7q39H9+yduzI/1BnjtUHDg8KGp4NDU6ORUsHdy4kCQ7aX7u8N0WsPj6NRU/sD1U8HURDA6NhbcOD51bTBxQ35yr06Tru9eZPxzFhGf9NjqMB6VHbl14f/TJidHjwTjB8fyNwUTh6eCib3BnonDB8cO4U11pdy0vJSbmku5aVMpN3WVctOOUm4aLOWm9mQp8Eq56aJSbrq8lJvuLOWme0u56cFSbnqilJueL+WmqooSbmov5abTSrnpqlJuurmUm+4v5aYnSrnp6cXcNBxG4psXdVNrKTe1l3LT9oXepH4Okl0jVbHLAQA=","debug_symbols":"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"}],"events":[],"file_map":{"3":{"source":"struct BoundedVec {\n storage: [T; MaxLen],\n // TODO: change this to return a u64 as Noir now\n // uses u64 for indexing\n len: Field,\n empty_value: T,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn len(self) -> Field {\n self.len\n }\n\n pub fn max_len(_self: BoundedVec) -> Field {\n MaxLen\n }\n\n // This is a intermediate method, while we don't have an\n // .extend method\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n pub fn extend_from_array(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len as u64 <= MaxLen as u64, \"extend_from_bounded_vec out of bounds\");\n\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field);\n }\n }\n self.len = new_len;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = self.empty_value;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}","path":"std/collections/bounded_vec.nr"},"31":{"source":"struct Option {\n _is_some: bool,\n _value: T,\n}\n\nimpl Option {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::unsafe::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n fn expect(self, message: fmtstr) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map(self, f: fn[Env](T) -> U) -> Option {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then(self, f: fn[Env](T) -> Option) -> Option {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option> into a Option.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option>) -> Option {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n","path":"std/option.nr"},"43":{"source":"contract Blank {\n use dep::aztec::{\n protocol_types::address::AztecAddress,\n state_vars::{singleton::Singleton, map::Map},\n context::{PrivateContext, PublicContext, Context},\n note::{\n utils as note_utils,\n note_interface::NoteInterface,\n note_header::NoteHeader,\n },\n };\n\n use dep::value_note::value_note::{ValueNote, VALUE_NOTE_LEN};\n\n struct Storage {\n numbers: Map>,\n }\n \n #[aztec(private)]\n fn constructor(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).initialize(&mut new_number, true);\n }\n\n #[aztec(private)]\n fn setNumber(number: Field, owner: AztecAddress) {\n let numbers = storage.numbers;\n let mut new_number = ValueNote::new(number, owner);\n numbers.at(owner).replace(&mut new_number, true);\n }\n\n unconstrained fn getNumber(owner: AztecAddress) -> pub ValueNote {\n let numbers = storage.numbers;\n numbers.at(owner).view_note()\n }\n\n unconstrained fn compute_note_hash_and_nullifier(\n contract_address: AztecAddress,\n nonce: Field,\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; VALUE_NOTE_LEN]\n ) -> pub [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n note_utils::compute_note_hash_and_nullifier(ValueNote::deserialize_content, note_header, serialized_note)\n }\n}\n","path":"/Users/zpedro/Documents/GitHub/aztec-packages/boxes/blank/src/contracts/src/main.nr"},"44":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n log: [Field; N]\n) {\n let _ = oracle::logs::emit_encrypted_log(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n log\n );\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(context: &mut PublicContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(context: &mut PrivateContext, log: T) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/log.nr"},"48":{"source":"use dep::std::option::Option;\nuse dep::protocol_types::{\n constants::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n },\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_consumption,\n};\nuse crate::oracle;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note: Note\n) where Note: NoteInterface {\n let header = note.get_header();\n let contract_address = context.this_address();\n assert(header.contract_address.eq(contract_address));\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(fields: [Field; N], selects: BoundedVec, N>) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n\n // Values are computed ahead of time because circuits evaluate all branches\n let isEqual = fields[select.field_index] == select.value;\n let isLt = fields[select.field_index].lt(select.value);\n\n if (select.comparator == Comparator.EQ) {\n assert(isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.NEQ) {\n assert(!isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LT) {\n assert(isLt, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.LTE) {\n assert(isLt | isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GT) {\n assert(!isLt & !isEqual, \"Mismatch return note field.\");\n } else if (select.comparator == Comparator.GTE) {\n assert(!isLt, \"Mismatch return note field.\");\n }\n }\n}\n\nfn check_notes_order(\n fields_0: [Field; N],\n fields_1: [Field; N],\n sorts: BoundedVec, N>\n) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field\n) -> Note where Note: NoteInterface {\n let note = get_note_internal(storage_slot);\n\n check_note_header(*context, storage_slot, note);\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let opt_notes = get_notes_internal(storage_slot, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let fields = note.serialize_content();\n check_note_header(*context, storage_slot, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_consumption(note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n }\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(storage_slot: Field) -> Note where Note: NoteInterface {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n 0,\n [],\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n NoteStatus.ACTIVE,\n placeholder_note,\n placeholder_fields,\n placeholder_note_length\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n options: NoteGetterOptions\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n options: NoteViewerOptions\n) -> [Option; MAX_NOTES_PER_PAGE] where Note: NoteInterface {\n let (num_selects, select_by, select_values, select_comparators, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n let placeholder_note_length = [0; N];\n oracle::notes::get_notes(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n options.status,\n placeholder_opt_notes,\n placeholder_fields,\n placeholder_note_length\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>\n) -> (u8, [u8; N], [Field; N], [u3; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n let mut select_comparators = [0; N];\n\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n select_comparators[num_selects] = select.unwrap_unchecked().comparator;\n num_selects += 1;\n };\n }\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n }\n\n (num_selects, select_by, select_values, select_comparators, sort_by, sort_order)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/note_getter.nr"},"49":{"source":"use crate::context::{PrivateContext, PublicContext};\nuse crate::note::{\n note_header::NoteHeader, note_interface::NoteInterface,\n utils::{compute_note_hash_for_insertion, compute_note_hash_for_consumption}\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n broadcast: bool\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n // As `is_transient` is true, this will compute the inner note hsah\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n // TODO: Strong typing required because of https://github.com/noir-lang/noir/issues/4088\n let serialized_note: [Field; N] = Note::serialize_content(*note);\n assert(\n notify_created_note(\n storage_slot,\n Note::get_note_type_id(),\n serialized_note,\n inner_note_hash\n )\n == 0\n );\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n Note::broadcast(*note, context, storage_slot);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note\n) where Note: NoteInterface {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(note, header);\n let inner_note_hash = compute_note_hash_for_insertion(*note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(context: &mut PrivateContext, note: Note) where Note: NoteInterface {\n let mut nullifier = 0;\n let mut consumed_note_hash: Field = 0;\n nullifier = note.compute_nullifier(context);\n\n // We also need the note hash corresponding to the \"nullifier\"\n let header = note.get_header();\n // `consumed_note_hash` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // note hash) in which case `consumed_note_hash` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note hash computed in `compute_nullifier`?\n consumed_note_hash = compute_note_hash_for_consumption(note);\n }\n assert(notify_nullified_note(nullifier, consumed_note_hash) == 0);\n\n context.push_new_nullifier(nullifier, consumed_note_hash)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr"},"50":{"source":"use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interface::NoteInterface}};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH\n},\n hash::pedersen_hash, utils::arr_copy_slice\n};\n\nfn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\nfn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n\nfn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n let note_hash = note.compute_note_content_hash();\n\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([header.storage_slot, note_hash], 0)\n}\n\nfn compute_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let inner_note_hash = compute_inner_note_hash(note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\nfn compute_unique_siloed_note_hash(note_with_header: Note) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n\n let siloed_note_hash = compute_siloed_note_hash(note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_siloed_nullifier(\n note_with_header: Note,\n context: &mut PrivateContext\n) -> Field where Note: NoteInterface {\n let header = note_with_header.get_header();\n let inner_nullifier = note_with_header.compute_nullifier(context);\n\n let input = [header.contract_address.to_field(), inner_nullifier];\n pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER)\n}\n\npub fn compute_note_hash_for_insertion(note: Note) -> Field where Note: NoteInterface {\n compute_inner_note_hash(note)\n}\n\npub fn compute_note_hash_for_consumption(note: Note) -> Field where Note: NoteInterface {\n let header = note.get_header();\n // There are 3 cases for reading a note intended for consumption:\n // 1. The note was inserted in this transaction, and is transient.\n // 2. The note was inserted in a previous transaction, and was inserted in public\n // 3. The note was inserted in a previous transaction, and was inserted in private\n\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note)\n }\n}\n\npub fn compute_note_hash_and_nullifier(\n deserialize_content: fn([Field; N]) -> T,\n note_header: NoteHeader,\n serialized_note: [Field; S]\n) -> [Field; 4] where T: NoteInterface {\n let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n T::set_header((&mut note), note_header);\n\n let inner_note_hash = compute_inner_note_hash(note);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let inner_nullifier = note.compute_nullifier_without_context();\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/note/utils.nr"},"60":{"source":"use crate::{\n context::inputs::PrivateContextInputs, key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments, call_private_function::call_private_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address,\n header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}\n}\n};\nuse dep::protocol_types::{\n abis::{\n call_context::CallContext, function_data::FunctionData, function_selector::FunctionSelector,\n nullifier_key_validation_request::NullifierKeyValidationRequest,\n private_call_stack_item::PrivateCallStackItem,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_call_stack_item::PublicCallStackItem,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash}\n},\n address::{AztecAddress, EthAddress},\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH\n},\n contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},\n grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header, utils::reader::Reader\n};\nuse dep::std::option::Option;\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n max_non_revertible_side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n nullifier_key_validation_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n // Header of a block whose state is used during private execution (not the block the transaction is included in).\n historical_header: Header,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n\n nullifier_key: Option,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n max_non_revertible_side_effect_counter: 0,\n args_hash,\n return_values: BoundedVec::new(0),\n read_requests: BoundedVec::new(SideEffect::empty()),\n nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()),\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n historical_header: inputs.historical_header,\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n nullifier_key: Option::none()\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n // Returns the header of a block whose state is used during private execution (not the block the transaction is\n // included in).\n pub fn get_header(self) -> Header {\n self.historical_header\n }\n\n // Returns the header of an arbitrary block whose block number is less than or equal to the block number\n // of historical header.\n pub fn get_header_at(self, block_number: u32) -> Header {\n get_header_at(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter,\n read_requests: self.read_requests.storage,\n nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash,\n unencrypted_logs_hash,\n encrypted_log_preimages_length,\n unencrypted_log_preimages_length,\n historical_header: self.historical_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version\n };\n priv_circuit_pub_inputs\n }\n\n pub fn capture_max_non_revertible_side_effect_counter(&mut self) {\n assert(\n self.max_non_revertible_side_effect_counter == 0, \"Already captured the non-revertible side effect counter\"\n );\n self.max_non_revertible_side_effect_counter = self.side_effect_counter;\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect { value: read_request, counter: self.side_effect_counter };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash { value: nullifier, note_hash: nullified_commitment, counter: self.side_effect_counter };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinPrivateKey {\n let key_pair = if self.nullifier_key.is_none() {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key);\n let request = NullifierKeyValidationRequest { public_key: key_pair.public_key, secret_key: key_pair.secret_key };\n self.nullifier_key_validation_requests.push(request);\n self.nullifier_key = Option::some(key_pair);\n key_pair\n } else {\n let key_pair = self.nullifier_key.unwrap_unchecked();\n // If MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL is larger than 1, need to update the way the key pair is cached.\n assert(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL == 1);\n assert(\n key_pair.account == account, \"Cannot query nullifier key for more than one account per call\"\n );\n key_pair\n };\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) {\n // docs:end:context_message_portal\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n // docs:end:context_consume_l1_to_l2_message\n let nullifier = process_l1_to_l2_message(\n self.historical_header.state.l1_to_l2_message_tree.root,\n self.this_address(),\n self.this_portal_address(),\n self.chain_id(),\n self.version(),\n msg_key,\n content,\n secret\n );\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let item = call_private_function_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address,\n function_selector,\n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n // Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and\n // there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: reader.read_struct(FunctionData::deserialize),\n public_inputs: PublicCircuitPublicInputs {\n call_context: reader.read_struct(CallContext::deserialize),\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n historical_header: Header::empty(),\n prover_address: AztecAddress::zero()\n },\n is_execution_request: true\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n\n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(\n item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)\n );\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context/private_context.nr"},"66":{"source":"use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\n\nuse dep::protocol_types::{\n address::AztecAddress,\n utils::arr_copy_slice,\n};\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _note_type_id: Field,\n _serialized_note: [Field; N],\n _inner_note_hash: Field\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n note_type_id: Field,\n serialized_note: [Field; N],\n inner_note_hash: Field\n) -> Field {\n notify_created_note_oracle(storage_slot, note_type_id, serialized_note, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(_nullifier: Field, _inner_note_hash: Field) -> Field {}\n\nunconstrained pub fn notify_nullified_note(nullifier: Field, inner_note_hash: Field) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _select_comparators: [u3; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _status: u2,\n _return_size: u32,\n _placeholder_fields: [Field; S]\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n select_comparators: [u3; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_fields: [Field; S]\n) -> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n return_size,\n placeholder_fields\n )\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n select_comparators: [u3; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n status: u2,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter\n) -> [Option; S] where Note: NoteInterface {\n let fields = get_notes_oracle_wrapper(\n storage_slot,\n num_selects,\n select_by,\n select_values,\n select_comparators,\n sort_by,\n sort_order,\n limit,\n offset,\n status,\n placeholder_fields\n );\n let num_notes = fields[0] as u32;\n let contract_address = AztecAddress::from_field(fields[1]);\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let serialized_note = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = Note::deserialize_content(serialized_note);\n // TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed\n Note::set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n }\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(_inner_nullifier: Field) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/notes.nr"},"69":{"source":"use dep::protocol_types::{address::{AztecAddress, PartialAddress, PublicKeysHash}, grumpkin_point::GrumpkinPoint};\n\n#[oracle(getPublicKeyAndPartialAddress)]\nfn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {}\n\nunconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] {\n get_public_key_and_partial_address_oracle(address)\n}\n\npub fn get_public_key(address: AztecAddress) -> GrumpkinPoint {\n let result = get_public_key_and_partial_address_internal(address);\n let pub_key = GrumpkinPoint::new(result[0], result[1]);\n let partial_address = PartialAddress::from_field(result[2]);\n\n let calculated_address = AztecAddress::compute(PublicKeysHash::compute(pub_key), partial_address);\n assert(calculated_address.eq(address));\n\n pub_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/get_public_key.nr"},"73":{"source":"use dep::protocol_types::{address::AztecAddress, constants::NUM_FIELDS_PER_SHA256, grumpkin_point::GrumpkinPoint};\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: AztecAddress,\n _storage_slot: Field,\n _note_type_id: Field,\n _encryption_pub_key: GrumpkinPoint,\n _preimage: [Field; N]\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: AztecAddress,\n storage_slot: Field,\n note_type_id: Field,\n encryption_pub_key: GrumpkinPoint,\n preimage: [Field; N]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [\n emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n note_type_id,\n encryption_pub_key,\n preimage\n ), 0\n ]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(\n _contract_address: AztecAddress,\n _event_selector: Field,\n _message: T\n) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(\n contract_address: AztecAddress,\n event_selector: Field,\n message: T\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/logs.nr"},"75":{"source":"#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/rand.nr"},"78":{"source":"use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint, grumpkin_private_key::GrumpkinPrivateKey};\n\nstruct NullifierKeyPair {\n account: AztecAddress,\n public_key: GrumpkinPoint,\n secret_key: GrumpkinPrivateKey,\n}\n\n#[oracle(getNullifierKeyPair)]\nfn get_nullifier_key_pair_oracle(_account: AztecAddress) -> [Field; 4] {}\n\nunconstrained fn get_nullifier_key_pair_internal(account: AztecAddress) -> NullifierKeyPair {\n let result = get_nullifier_key_pair_oracle(account);\n NullifierKeyPair {\n account,\n public_key: GrumpkinPoint { x: result[0], y: result[1] },\n secret_key: GrumpkinPrivateKey { high: result[2], low: result[3] }\n }\n}\n\npub fn get_nullifier_key_pair(account: AztecAddress) -> NullifierKeyPair {\n get_nullifier_key_pair_internal(account)\n}\n\npub fn get_nullifier_secret_key(account: AztecAddress) -> GrumpkinPrivateKey {\n get_nullifier_key_pair_internal(account).secret_key\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/oracle/nullifier_key.nr"},"85":{"source":"mod globals;\nmod inputs;\n\nmod private_context;\nmod public_context;\nmod avm;\n\nuse private_context::PrivateContext;\nuse public_context::PublicContext;\nuse avm::AVMContext;\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context { private: Option::some(context), public: Option::none() }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context { public: Option::some(context), private: Option::none() }\n }\n\n pub fn none() -> Context {\n Context { public: Option::none(), private: Option::none() }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/context.nr"},"97":{"source":"use dep::std::option::Option;\n\nuse dep::protocol_types::{address::AztecAddress, constants::{GENERATOR_INDEX__INITIALIZATION_NULLIFIER}, hash::pedersen_hash};\n\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, destroy_note}, note_getter::{get_note, view_notes},\n note_interface::NoteInterface, note_viewer_options::NoteViewerOptions\n};\nuse crate::oracle::{nullifier_key::get_nullifier_secret_key, notes::check_nullifier_exists};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:struct\nstruct Singleton {\n context: Option<&mut PrivateContext>,\n storage_slot: Field\n}\n// docs:end:struct\n\nimpl Storage for Singleton {}\n\nimpl Singleton {\n // docs:start:new\n pub fn new(context: Context, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self { context: context.private, storage_slot }\n }\n // docs:end:new\n\n // The following computation is leaky, in that it doesn't hide the storage slot that has been initialized, nor does it hide the contract address of this contract.\n // When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.\n // For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.\n // Under such circumstances, such application developers might wish to _not_ use this state variable type.\n // This is especially dangerous for initial assignment to elements of a `Map` type (for example), because the storage slot often also identifies an actor. e.g. \n // the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.\n // Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy. \n // For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.\n pub fn compute_initialization_nullifier(self) -> Field {\n pedersen_hash(\n [self.storage_slot],\n GENERATOR_INDEX__INITIALIZATION_NULLIFIER\n )\n }\n\n // docs:start:is_initialized\n unconstrained pub fn is_initialized(self) -> bool {\n let nullifier = self.compute_initialization_nullifier();\n check_nullifier_exists(nullifier)\n }\n // docs:end:is_initialized\n\n // docs:start:initialize\n pub fn initialize(self, note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n\n // Nullify the storage slot.\n let nullifier = self.compute_initialization_nullifier();\n context.push_new_nullifier(nullifier, 0);\n\n create_note(context, self.storage_slot, note, broadcast);\n }\n // docs:end:initialize\n\n // docs:start:replace\n pub fn replace(self, new_note: &mut Note, broadcast: bool) where Note: NoteInterface {\n let context = self.context.unwrap();\n let prev_note = get_note(context, self.storage_slot);\n\n // Nullify previous note.\n destroy_note(context, prev_note);\n\n // Add replacement note.\n create_note(context, self.storage_slot, new_note, broadcast);\n }\n // docs:end:replace\n\n // docs:start:get_note\n pub fn get_note(self, broadcast: bool) -> Note where Note: NoteInterface {\n let context = self.context.unwrap();\n let mut note = get_note(context, self.storage_slot);\n\n // Nullify current note to make sure it's reading the latest note.\n destroy_note(context, note);\n\n // Add the same note again.\n // Because a nonce is added to every note in the kernel, its nullifier will be different.\n create_note(context, self.storage_slot, &mut note, broadcast);\n\n note\n }\n // docs:end:get_note\n\n // docs:start:view_note\n unconstrained pub fn view_note(self) -> Note where Note: NoteInterface {\n let options = NoteViewerOptions::new().set_limit(1);\n view_notes(self.storage_slot, options)[0].unwrap()\n }\n // docs:end:view_note\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr"},"99":{"source":"use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\nuse dep::protocol_types::{hash::pedersen_hash, traits::{ToField}};\nuse crate::state_vars::storage::Storage;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Storage for Map {}\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map { context, storage_slot, state_var_constructor }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: K) -> V where K: ToField {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = pedersen_hash([self.storage_slot, key.to_field()], 0);\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/state_vars/map.nr"},"105":{"source":"use dep::protocol_types::{hash::hash_args, traits::Hash};\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hash for Hasher {\n fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nimpl Hasher {\n pub fn new() -> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/aztec/src/hasher.nr"},"142":{"source":"use crate::{\n constants::{GENERATOR_INDEX__CONTRACT_ADDRESS, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONSTRUCTOR},\n hash::pedersen_hash, contract_class::ContractClassId, utils, grumpkin_point::GrumpkinPoint\n};\nuse dep::std::cmp::Eq;\nuse crate::traits::{Empty, ToField, Serialize, Deserialize};\nuse crate::type_serialization::{ETH_ADDRESS_SERIALIZED_LEN, AZTEC_ADDRESS_SERIALIZED_LEN};\n\n// Aztec address\nstruct AztecAddress {\n inner : Field\n}\n\nimpl Eq for AztecAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for AztecAddress {\n fn serialize(self: Self) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize for AztecAddress {\n fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> Self {\n AztecAddress::from_field(fields[0])\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute_from_public_key(\n pub_key: GrumpkinPoint,\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> AztecAddress {\n AztecAddress::compute(\n PublicKeysHash::compute(pub_key),\n PartialAddress::compute(\n contract_class_id,\n salt,\n initialization_hash,\n portal_contract_address\n )\n )\n }\n\n pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress {\n AztecAddress::from_field(\n pedersen_hash(\n [pub_keys_hash.to_field(), partial_address.to_field()],\n GENERATOR_INDEX__CONTRACT_ADDRESS\n )\n )\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\nstruct EthAddress{\n inner : Field\n}\n\nimpl Eq for EthAddress {\n fn eq(self, other : Self) -> bool {\n self.to_field() == other.to_field()\n }\n}\n\nimpl Empty for EthAddress {\n fn empty() -> Self {\n Self {\n inner : 0\n }\n }\n}\n\nimpl ToField for EthAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize for EthAddress {\n fn serialize(self: Self) -> [Field; ETH_ADDRESS_SERIALIZED_LEN] {\n [self.inner]\n }\n}\n\nimpl Deserialize for EthAddress {\n fn deserialize(fields: [Field; ETH_ADDRESS_SERIALIZED_LEN]) -> Self {\n Self {\n inner: fields[0]\n }\n }\n}\n\nimpl EthAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n\n pub fn conditional_assign(predicate: bool, lhs: Self, rhs: Self) -> Self {\n let result = utils::conditional_assign(predicate, rhs.to_field(), lhs.to_field());\n Self { inner: result }\n }\n}\n\n// Partial address\nstruct PartialAddress {\n inner : Field\n}\n\nimpl ToField for PartialAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl PartialAddress {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(\n contract_class_id: ContractClassId,\n salt: Field,\n initialization_hash: Field,\n portal_contract_address: EthAddress\n ) -> Self {\n PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)\n )\n }\n\n pub fn compute_from_salted_initialization_hash(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash\n ) -> Self {\n PartialAddress::from_field(\n pedersen_hash(\n [\n contract_class_id.to_field(),\n salted_initialization_hash.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Salted initialization hash. Used in the computation of a partial address.\nstruct SaltedInitializationHash {\n inner: Field\n}\n\nimpl ToField for SaltedInitializationHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl SaltedInitializationHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {\n SaltedInitializationHash::from_field(\n pedersen_hash(\n [\n salt,\n initialization_hash,\n portal_contract_address.to_field()\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n// Public keys hash. Used in the computation of an address.\nstruct PublicKeysHash {\n inner: Field\n}\n\nimpl ToField for PublicKeysHash {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl Serialize<1> for PublicKeysHash {\n fn serialize(self: Self) -> [Field; 1] {\n [self.to_field()]\n }\n}\n\nimpl Deserialize<1> for PublicKeysHash {\n fn deserialize(fields: [Field; 1]) -> Self {\n PublicKeysHash::from_field(fields[0])\n }\n}\n\nimpl PublicKeysHash {\n pub fn from_field(field: Field) -> Self {\n Self { inner: field }\n }\n\n pub fn compute(public_key: GrumpkinPoint) -> Self {\n PublicKeysHash::from_field(\n pedersen_hash(\n [\n public_key.x,\n public_key.y\n ],\n GENERATOR_INDEX__PARTIAL_ADDRESS\n )\n )\n }\n\n pub fn to_field(self) -> Field {\n self.inner\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\npub fn compute_initialization_hash(selector: Field, args_hash: Field) -> Field {\n pedersen_hash(\n [\n selector,\n args_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/address.nr"},"166":{"source":"// general util packages/modules are usually bad practice\n// because there is no criteria for what we should not put in here.\n// Reducing the size of this package would be welcome.\n\nmod arrays;\nmod field;\nmod reader;\nmod uint256;\n\n// if predicate == true then return lhs, else return rhs\npub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field {\n if predicate { lhs } else { rhs }\n}\n\npub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/utils.nr"},"167":{"source":"use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashes(\n first_nullifier: Field,\n siloed_note_hashes: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashes = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashes[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashes[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashes\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr"},"183":{"source":"use dep::aztec::{\n protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}},\n note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},\n oracle::{rand::rand, nullifier_key::get_nullifier_secret_key, get_public_key::get_public_key},\n log::emit_encrypted_log, hash::pedersen_hash, context::PrivateContext\n};\n\nglobal VALUE_NOTE_LEN: Field = 3; // 3 plus a header.\n\n// docs:start:value-note-def\nstruct ValueNote {\n value: Field,\n owner: AztecAddress,\n randomness: Field,\n header: NoteHeader,\n}\n// docs:end:value-note-def\n\nimpl NoteInterface for ValueNote {\n fn serialize_content(self) -> [Field; VALUE_NOTE_LEN] {\n [self.value, self.owner.to_field(), self.randomness]\n }\n\n fn deserialize_content(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self {\n ValueNote {\n value: serialized_note[0],\n owner: AztecAddress::from_field(serialized_note[1]),\n randomness: serialized_note[2],\n header: NoteHeader::empty(),\n }\n }\n\n fn compute_note_content_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash(self.serialize_content(),0)\n }\n\n // docs:start:nullifier\n\n fn compute_nullifier(self, context: &mut PrivateContext) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = context.request_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n // docs:end:nullifier\n\n fn compute_nullifier_without_context(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_consumption(self);\n let secret = get_nullifier_secret_key(self.owner);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen_hash([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ],0)\n }\n\n fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n fn get_header(self) -> NoteHeader {\n self.header\n }\n\n // Broadcasts the note as an encrypted log on L1.\n fn broadcast(self, context: &mut PrivateContext, slot: Field) {\n let encryption_pub_key = get_public_key(self.owner);\n emit_encrypted_log(\n context,\n (*context).this_address(),\n slot,\n Self::get_note_type_id(),\n encryption_pub_key,\n self.serialize_content(),\n );\n }\n\n fn get_note_type_id() -> Field {\n // TODO(#4519): autogenerate\n // python -c \"print(int(''.join(str(ord(c)) for c in 'ValueNote')))\"\n 869710811710178111116101\n }\n}\n\nimpl ValueNote {\n pub fn new(value: Field, owner: AztecAddress) -> Self {\n let randomness = rand();\n let header = NoteHeader::empty();\n ValueNote { value, owner, randomness, header }\n }\n}\n","path":"/Users/zpedro/nargo/github.com/AztecProtocol/aztec-packages/master/noir-projects/aztec-nr/value-note/src/value_note.nr"}}} \ No newline at end of file diff --git a/docs/docs/developers/contracts/writing_contracts/functions/context.md b/docs/docs/developers/contracts/writing_contracts/functions/context.md index 99b692ffe25..e1a18f4f0f5 100644 --- a/docs/docs/developers/contracts/writing_contracts/functions/context.md +++ b/docs/docs/developers/contracts/writing_contracts/functions/context.md @@ -15,7 +15,7 @@ On this page, you'll learn - The details and functionalities of the private context in Aztec.nr - Difference between the private and public contexts and their unified APIs - Components of the private context, such as inputs, block header, and contract deployment data -- Elements like return values, read requests, new commitments, and nullifiers in transaction processing +- Elements like return values, read requests, new note hashes, and nullifiers in transaction processing - Differences between the private and public contexts, especially the unique features and variables in the public context ## Two contexts, one API @@ -105,18 +105,18 @@ The return values are a set of values that are returned from an applications exe -### New Commitments +### New Note Hashes -New commitments contains an array of all of the commitments created in the current execution context. +New note hashes contains an array of all of the note hashes created in the current execution context. ### New Nullifiers New nullifiers contains an array of the new nullifiers emitted from the current execution context. -### Nullified Commitments +### Nullified Note Hashes -Nullified commitments is an optimization for introduced to help reduce state growth. There are often cases where commitments are created and nullified within the same transaction. -In these cases there is no reason that these commitments should take up space on the node's commitment/nullifier trees. Keeping track of nullified commitments allows us to "cancel out" and prove these cases. +Nullified note hashes is an optimization for introduced to help reduce state growth. There are often cases where note hashes are created and nullified within the same transaction. +In these cases there is no reason that these note hashes should take up space on the node's commitment/nullifier trees. Keeping track of nullified note hashes allows us to "cancel out" and prove these cases. ### Private Call Stack diff --git a/docs/docs/developers/debugging/sandbox-errors.md b/docs/docs/developers/debugging/sandbox-errors.md index e107e71e693..9fc8f60cd0e 100644 --- a/docs/docs/developers/debugging/sandbox-errors.md +++ b/docs/docs/developers/debugging/sandbox-errors.md @@ -22,9 +22,9 @@ Remember that for each function call (i.e. each item in the call stack), there i Cannot call contract at address(0x0) privately. This error may also happen when you deploy a new contract and the contract data hash is inconsistent to the expected contract address. -#### 2005 - PRIVATE_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL +#### 2005 - PRIVATE_KERNEL\_\_NEW_NOTE_HASHES_PROHIBITED_IN_STATIC_CALL -For static calls, new commitments aren't allowed +For static calls, new note hashes aren't allowed #### 2006 - PRIVATE_KERNEL\_\_NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL @@ -67,13 +67,13 @@ For a non transient read, we fetch the merkle root from the membership witnesses #### 2019 - PRIVATE_KERNEL\_\_TRANSIENT_READ_REQUEST_NO_MATCH -A pending commitment is the one that is not yet added to note hash tree. -A transient read is when we try to "read" a pending commitment. -This error happens when you try to read a pending commitment that doesn't exist. +A pending note hash is the one that is not yet added to note hash tree. +A transient read is when we try to "read" a pending note hash. +This error happens when you try to read a pending note hash that doesn't exist. #### 2021 - PRIVATE_KERNEL\_\_UNRESOLVED_NON_TRANSIENT_READ_REQUEST -For a transient read request we skip merkle membership checks since pending commitments aren't inserted into the note hash tree yet. +For a transient read request we skip merkle membership checks since pending note hashes aren't inserted into the note hash tree yet. But for non transient reads, we do a merkle membership check. Reads are done at the kernel circuit. So this checks that there are no already unresolved reads from a previous kernel iteration (other than non transient ones). #### 3001 - PUBLIC_KERNEL\_\_UNSUPPORTED_OP @@ -120,13 +120,13 @@ For static calls, no contract storage change requests are allowed. Same as [3022](#3022---public_kernel__public_call_stack_contract_storage_updates_prohibited_for_static_call), no contract changes are allowed for static calls. -#### 3026 - PUBLIC_KERNEL\_\_NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL +#### 3026 - PUBLIC_KERNEL\_\_NOTE_HASHES_PROHIBITED_IN_STATIC_CALL -For static calls, no new commitments or nullifiers can be added to the state. +For static calls, no new note hashes or nullifiers can be added to the state. #### 3027 - PUBLIC_KERNEL\_\_NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL -For static calls, no new commitments or nullifiers can be added to the state. +For static calls, no new note hashes or nullifiers can be added to the state. ### Rollup circuit errors @@ -148,7 +148,7 @@ Some scary bugs like `4003 - BASE__INVALID_NULLIFIER_SUBTREE` and `4004 - BASE__ Circuits work by having a fixed size array. As such, we have limits on how many UTXOs can be created (aka "commitments") or destroyed/nullified (aka "nullifiers") in a transaction. Similarly we have limits on many reads or writes you can do, how many contracts you can create in a transaction. This error typically says that you have reached the current limits of what you can do in a transaction. Some examples when you may hit this error are: -- too many new commitments in one tx +- too many new note hashes in one tx - too many new nullifiers in one tx - Note: Nullifiers may be created even outside the context of your Aztec.nr code. Eg, when creating a contract, we add a nullifier for its address to prevent same address from ever occurring. Similarly, we add a nullifier for your transaction hash too. - too many private function calls in one tx (i.e. call stack size exceeded) @@ -170,7 +170,7 @@ Users may create a proof against a historical state in Aztec. The rollup circuit - using invalid historical contracts data tree state - using invalid historical L1 to L2 message data tree state - inserting a subtree into the greater tree - - we make a smaller merkle tree of all the new commitments/nullifiers etc that were created in a transaction or in a rollup and add it to the bigger state tree. Before inserting, we do a merkle membership check to ensure that the index to insert at is indeed an empty subtree (otherwise we would be overwriting state). This can happen when `next_available_leaf_index` in the state tree's snapshot is wrong (it is fetched by the sequencer from the archiver). The error message should reveal which tree is causing this issue + - we make a smaller merkle tree of all the new note hashes/nullifiers etc that were created in a transaction or in a rollup and add it to the bigger state tree. Before inserting, we do a merkle membership check to ensure that the index to insert at is indeed an empty subtree (otherwise we would be overwriting state). This can happen when `next_available_leaf_index` in the state tree's snapshot is wrong (it is fetched by the sequencer from the archiver). The error message should reveal which tree is causing this issue - nullifier tree related errors - The nullifier tree uses an [Indexed Merkle Tree](../../learn/concepts/storage/trees/indexed_merkle_tree.md). It requires additional data from the archiver to know which is the nullifier in the tree that is just below the current nullifier before it can perform batch insertion. If the low nullifier is wrong, or the nullifier is in incorrect range, you may receive this error. --- diff --git a/docs/docs/developers/limitations/main.md b/docs/docs/developers/limitations/main.md index 971690e07e0..1c0854c06ed 100644 --- a/docs/docs/developers/limitations/main.md +++ b/docs/docs/developers/limitations/main.md @@ -38,7 +38,7 @@ Help shape and define: - The initial `msg_sender` is 0, which can be problematic for some contracts, see [function visibility](../contracts/writing_contracts/functions/visibility.md). - Unencrypted logs don't link to the contract that emitted it, so essentially just a `debug_log`` that you can match values against. - A note that is created and nullified in the same transaction will still emit an encrypted log. -- A limited amount of new commitments, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). +- A limited amount of new note hashes, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). ## Limitations diff --git a/docs/docs/developers/privacy/main.md b/docs/docs/developers/privacy/main.md index d7d2997df55..066aeb570f9 100644 --- a/docs/docs/developers/privacy/main.md +++ b/docs/docs/developers/privacy/main.md @@ -78,7 +78,7 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi - All unencrypted logs (topics and arguments). - The roots of all trees which have been read from. - The _number_ of ['side effects'](): - - \# new commitments + - \# new note hashes - \# new nullifiers - \# bytes of encrypted logs - \# public function calls @@ -91,7 +91,7 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi #### Standardizing Fingerprints -If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new commitments, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. +If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new note hashes, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. ### Data queries diff --git a/docs/docs/learn/concepts/circuits/rollup_circuits/main.md b/docs/docs/learn/concepts/circuits/rollup_circuits/main.md index d5ac8be56c8..871a7ead96a 100644 --- a/docs/docs/learn/concepts/circuits/rollup_circuits/main.md +++ b/docs/docs/learn/concepts/circuits/rollup_circuits/main.md @@ -25,7 +25,7 @@ For both transactions, it: - Updates the public data tree in line with the requested state transitions. - Checks that the nullifiers haven't previously been inserted into the [indexed nullifier tree](../../storage/trees/indexed_merkle_tree.md#primer-on-nullifier-trees). - Batch-inserts new nullifiers into the nullifier tree. -- Batch-inserts new commitments into the note hash tree +- Batch-inserts new note hashes into the note hash tree - Batch-inserts any new contract deployments into the contract tree. - Hashes all the new nullifiers, commitments, public state transitions, and new contract deployments, to prevent exponential growth in public inputs with each later layer of recursion. - Verifies the input kernel proof. diff --git a/docs/docs/learn/concepts/communication/public_private_calls/main.md b/docs/docs/learn/concepts/communication/public_private_calls/main.md index 15ae6df1c8b..eca7d2ccb54 100644 --- a/docs/docs/learn/concepts/communication/public_private_calls/main.md +++ b/docs/docs/learn/concepts/communication/public_private_calls/main.md @@ -32,7 +32,7 @@ This works perfectly well when everything is public and a single builder is awar To avoid this issue, we permit the use of historical data as long as the data has not been nullified previously. Note, that because this must include nullifiers that were inserted after the proof generation, but before execution we need to nullify (and insert the data again) to prove that it was not nullified. Without emitting the nullifier we would need our proof to point to the current head of the nullifier tree to have the same effect, e.g., back to the race conditions we were trying to avoid. -In this model, instead of informing the builder of our intentions, we construct the proof $\pi$ and then provide them with the transaction results (new commitments and nullifiers, contract deployments and cross-chain messages) in addition to $\pi$. The builder will then be responsible for inserting these new commitments and nullifiers into the state. They will be aware of the intermediates and can discard transactions that try to produce existing nullifiers (double spend), as doing so would invalidate the rollup proof. +In this model, instead of informing the builder of our intentions, we construct the proof $\pi$ and then provide them with the transaction results (new note hashes and nullifiers, contract deployments and cross-chain messages) in addition to $\pi$. The builder will then be responsible for inserting these new note hashes and nullifiers into the state. They will be aware of the intermediates and can discard transactions that try to produce existing nullifiers (double spend), as doing so would invalidate the rollup proof. On the left-hand side of the diagram below, we see the fully public world where storage is shared, while on the right-hand side, we see the private world where all reads are historical. @@ -56,11 +56,11 @@ Be mindful that if part of a transaction is reverting, say the public part of a To summarize: -- _Private_ function calls are fully "prepared" and proven by the user, which provides the kernel proof along with new commitments and nullifiers to the sequencer. +- _Private_ function calls are fully "prepared" and proven by the user, which provides the kernel proof along with new note hashes and nullifiers to the sequencer. - _Public_ functions altering public state (updatable storage) must be executed at the current "head" of the chain, which only the sequencer can ensure, so these must be executed separately to the _private_ functions. - _Private_ and _public_ functions within an Aztec transaction are therefore ordered such that first _private_ functions are executed, and then _public_. -A more comprehensive overview of the interplay between private and public functions and their ability to manipulate data is presented below. It is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new commitments, potentially as part of transferring funds from the public domain to the secret domain). +A more comprehensive overview of the interplay between private and public functions and their ability to manipulate data is presented below. It is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new note hashes, potentially as part of transferring funds from the public domain to the secret domain). diff --git a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md index 64ced6272fd..1e0d44ae666 100644 --- a/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md +++ b/docs/docs/learn/concepts/communication/public_private_calls/slow_updates_tree.md @@ -41,7 +41,7 @@ graph TD; CurrentM --> Value1[Current Value 1] CurrentM --> Value2[Current Value 2] CurrentM --> ValueN[Current Value n] - Pending --> PendingM[Pending Commitment 1] + Pending --> PendingM[Pending Note Hash 1] PendingM --> PValue1[Pending Value 1] PendingM --> PValue2[Pending Value 2] PendingM --> PValueN[Pending Value n] diff --git a/docs/docs/learn/concepts/storage/storage_slots.md b/docs/docs/learn/concepts/storage/storage_slots.md index 3aff76c895d..9afb68ae05d 100644 --- a/docs/docs/learn/concepts/storage/storage_slots.md +++ b/docs/docs/learn/concepts/storage/storage_slots.md @@ -39,8 +39,7 @@ If we include the storage slot, as part of the note whose commitment is stored i Similarly to how we siloed the public storage slots, we can silo our private storage by hashing the logical storage slot together with the note content. ```rust -note_hash = H(...note_content); -commitment = H(logical_storage_slot, note_hash); +note_hash = H(logical_storage_slot, note_content_hash); ``` This siloing (there will be more) is done in the application circuit, since it is not necessary for security of the network (but only the application). @@ -53,7 +52,7 @@ When reading the values for these notes, the application circuit can then constr To ensure that one contract cannot insert storage that other contracts would believe is theirs, we do a second siloing by hashing the `commitment` with the contract address. ```rust -siloed_commitment = H(contract_address, commitment); +siloed_note_hash = H(contract_address, note_hash); ``` By doing this address-siloing at the kernel circuit we *force* the inserted commitments to include and not lie about the `contract_address`. diff --git a/docs/docs/misc/roadmap/engineering_roadmap.md b/docs/docs/misc/roadmap/engineering_roadmap.md index 4b5163f90ad..2e232a2c023 100644 --- a/docs/docs/misc/roadmap/engineering_roadmap.md +++ b/docs/docs/misc/roadmap/engineering_roadmap.md @@ -52,7 +52,7 @@ The engineering roadmap is long. There are no timings assigned here. In a loose - Just emit the initially-enqueued public function request data? (The 'inputs' of the tx); - I.e. contract address, function selector, args, call_context. - OR, Just emit the final state transitions? (The 'outputs' of the tx) - - I.e. the leaf indices and new values of the public data tree; and the new commitments/nullifiers of the note hash tree; and logs; and l2->L1 messages. + - I.e. the leaf indices and new values of the public data tree; and the new note hashes/nullifiers of the note hash tree; and logs; and l2->L1 messages. ## Proper specs @@ -177,7 +177,7 @@ Some example features: - This would give much more flexibility over the sizes of various arrays that a circuit can output. Without it, if one array of an app circuit needs to be size 2000, but other arrays aren't used, we'd use a kernel where every array is size 2048, meaning a huge amount of unnecessary loops of computation for those empty arrays. - Improvements - We can definitely change how call stacks are processed within a kernel, to reduce hashing. - - Squash pending commitments/nullifiers in every kernel iteration, to enable a deeper nested call depth. + - Squash pending note hashes/nullifiers in every kernel iteration, to enable a deeper nested call depth. - Topology of a rollup - Revisit the current topology: - We can make the rollup trees 'wonky' (rather than balanced), meaning a sequencer doesn't need to prove a load of pointless 'padding' proofs? @@ -195,7 +195,7 @@ We often pack data in circuit A, and then unpack it again in circuit B. Also, for logs in particular, we allow arbitrary-sized logs. But this requires sha256 packing inside an app circuit (which is slow) (and sha256 unpacking in Solidity (which is relatively cheap)). Perhaps we also use the bus ideas for logs, to give _some_ variability in log length, but up to an upper bound. -Also, we do a lot of sha256-compressing in our kernel and rollup circuits for data which must be checked on-chain, but grows exponentially with every round of iteration. E.g.: new contract deployment data, new nullifiers, new commitments, public state transition data, etc. This might be unavoidable. Maybe all we can do is use polynomial commitments when the EIP-4844 work is done. But maybe we can use the bus for this stuff too. +Also, we do a lot of sha256-compressing in our kernel and rollup circuits for data which must be checked on-chain, but grows exponentially with every round of iteration. E.g.: new contract deployment data, new nullifiers, new note hashes, public state transition data, etc. This might be unavoidable. Maybe all we can do is use polynomial commitments when the EIP-4844 work is done. But maybe we can use the bus for this stuff too. ### Write proper circuits diff --git a/l1-contracts/slither_output.md b/l1-contracts/slither_output.md index 81c96c9ab12..b9669bc5038 100644 --- a/l1-contracts/slither_output.md +++ b/l1-contracts/slither_output.md @@ -10,7 +10,7 @@ Summary - [dead-code](#dead-code) (13 results) (Informational) - [solc-version](#solc-version) (1 results) (Informational) - [low-level-calls](#low-level-calls) (1 results) (Informational) - - [similar-names](#similar-names) (2 results) (Informational) + - [similar-names](#similar-names) (3 results) (Informational) - [unused-state](#unused-state) (2 results) (Informational) - [constable-states](#constable-states) (1 results) (Optimization) - [pess-multiple-storage-read](#pess-multiple-storage-read) (2 results) (Optimization) @@ -353,12 +353,18 @@ src/core/messagebridge/Inbox.sol#L148-L153 Impact: Informational Confidence: Medium - [ ] ID-41 +Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L123) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L116) + +src/core/libraries/ConstantsGen.sol#L123 + + + - [ ] ID-42 Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L104) src/core/libraries/ConstantsGen.sol#L103 - - [ ] ID-42 + - [ ] ID-43 Variable [Rollup.AVAILABILITY_ORACLE](src/core/Rollup.sol#L30) is too similar to [Rollup.constructor(IRegistry,IAvailabilityOracle)._availabilityOracle](src/core/Rollup.sol#L39) src/core/Rollup.sol#L30 @@ -367,13 +373,13 @@ src/core/Rollup.sol#L30 ## unused-state Impact: Informational Confidence: High - - [ ] ID-43 + - [ ] ID-44 [Decoder.END_TREES_BLOCK_HEADER_OFFSET](src/core/libraries/decoders/Decoder.sol#L103-L104) is never used in [Decoder](src/core/libraries/decoders/Decoder.sol#L72-L418) src/core/libraries/decoders/Decoder.sol#L103-L104 - - [ ] ID-44 + - [ ] ID-45 [Decoder.BLOCK_HEADER_OFFSET](src/core/libraries/decoders/Decoder.sol#L107-L108) is never used in [Decoder](src/core/libraries/decoders/Decoder.sol#L72-L418) src/core/libraries/decoders/Decoder.sol#L107-L108 @@ -382,7 +388,7 @@ src/core/libraries/decoders/Decoder.sol#L107-L108 ## constable-states Impact: Optimization Confidence: High - - [ ] ID-45 + - [ ] ID-46 [Rollup.lastWarpedBlockTs](src/core/Rollup.sol#L37) should be constant src/core/Rollup.sol#L37 @@ -391,13 +397,13 @@ src/core/Rollup.sol#L37 ## pess-multiple-storage-read Impact: Optimization Confidence: High - - [ ] ID-46 + - [ ] ID-47 In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72) variable [FrontierMerkle.DEPTH](src/core/messagebridge/frontier_tree/Frontier.sol#L8) is read multiple times src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72 - - [ ] ID-47 + - [ ] ID-48 In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72) variable [FrontierMerkle.frontier](src/core/messagebridge/frontier_tree/Frontier.sol#L13) is read multiple times src/core/messagebridge/frontier_tree/Frontier.sol#L39-L72 diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index f8a7ae2576e..6f1202c6c09 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -16,7 +16,7 @@ library Constants { uint256 internal constant ARGS_LENGTH = 16; uint256 internal constant RETURN_VALUES_LENGTH = 4; - uint256 internal constant MAX_NEW_COMMITMENTS_PER_CALL = 16; + uint256 internal constant MAX_NEW_NOTE_HASHES_PER_CALL = 16; uint256 internal constant MAX_NEW_NULLIFIERS_PER_CALL = 16; uint256 internal constant MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL = 4; uint256 internal constant MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL = 4; @@ -25,9 +25,9 @@ library Constants { uint256 internal constant MAX_PUBLIC_DATA_READS_PER_CALL = 16; uint256 internal constant MAX_READ_REQUESTS_PER_CALL = 32; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; - uint256 internal constant MAX_NEW_COMMITMENTS_PER_TX = 64; - uint256 internal constant MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; - uint256 internal constant MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; + uint256 internal constant MAX_NEW_NOTE_HASHES_PER_TX = 64; + uint256 internal constant MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; + uint256 internal constant MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX = 64; uint256 internal constant MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; uint256 internal constant MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; @@ -113,7 +113,7 @@ library Constants { uint256 internal constant TX_CONTEXT_DATA_LENGTH = 11; uint256 internal constant TX_REQUEST_LENGTH = 17; uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674; - uint256 internal constant COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; + uint256 internal constant NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; uint256 internal constant CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; diff --git a/l1-contracts/src/core/libraries/decoders/Decoder.sol b/l1-contracts/src/core/libraries/decoders/Decoder.sol index 39efa07f04d..437a6c6c92a 100644 --- a/l1-contracts/src/core/libraries/decoders/Decoder.sol +++ b/l1-contracts/src/core/libraries/decoders/Decoder.sol @@ -50,8 +50,8 @@ import {Hash} from "../Hash.sol"; * | 0x0208 | 0x04 | endL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex * | 0x020c | 0x20 | endArchiveSnapshot.root * | 0x022c | 0x04 | endArchiveSnapshot.nextAvailableLeafIndex - * | 0x0230 | 0x04 | len(newCommitments) (denoted a) - * | 0x0234 | a * 0x20 | newCommitments + * | 0x0230 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x0234 | a * 0x20 | newNoteHashes * | 0x0234 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x0238 + a * 0x20 | b * 0x20 | newNullifiers * | 0x0238 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) @@ -156,7 +156,7 @@ library Decoder { /** * @notice Computes consumables for the block * @param _body - The L2 block body. - * @return diffRoot - The root of the diff tree (new commitments, nullifiers etc) + * @return diffRoot - The root of the diff tree (new note hashes, nullifiers etc) * @return l1ToL2MsgsHash - The hash of the L1 to L2 messages * @return l2ToL1Msgs - The L2 to L1 messages of the block * @return l1ToL2Msgs - The L1 to L2 messages of the block @@ -174,7 +174,7 @@ library Decoder { // Commitments uint256 count = read4(_body, offset); - vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_COMMITMENTS_PER_TX); + vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_NOTE_HASHES_PER_TX); offset += 0x4; offsets.commitment = offset; offset += count * 0x20; @@ -226,7 +226,7 @@ library Decoder { /* * Compute the leaf to insert. * Leaf_i = ( - * newCommitmentsKernel, + * newNoteHashesKernel, * newNullifiersKernel, * newPublicDataWritesKernel, * newL2ToL1MsgsKernel, @@ -253,7 +253,7 @@ library Decoder { // Insertions are split into multiple `bytes.concat` to work around stack too deep. vars.baseLeaf = bytes.concat( bytes.concat( - slice(_body, offsets.commitment, Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP), + slice(_body, offsets.commitment, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.nullifier, Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.publicData, Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.l2ToL1Msgs, Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP), @@ -267,7 +267,7 @@ library Decoder { bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); - offsets.commitment += Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP; + offsets.commitment += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; offsets.nullifier += Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP; offsets.publicData += Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP; offsets.l2ToL1Msgs += Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol index 3c632b234b9..80e254a6b68 100644 --- a/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol @@ -21,8 +21,8 @@ import {Hash} from "../Hash.sol"; * * | byte start | num bytes | name * | --- | --- | --- - * | 0x00 | 0x04 | len(newCommitments) (denoted a) - * | 0x04 | a * 0x20 | newCommitments + * | 0x00 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x04 | a * 0x20 | newNoteHashes * | 0x04 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x08 + a * 0x20 | b * 0x20 | newNullifiers * | 0x08 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) @@ -63,7 +63,7 @@ library MessagesDecoder { uint256 offset = 0; - // Commitments + // Note hashes uint256 count = read4(_body, offset); offset += 0x4 + count * 0x20; diff --git a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol index 93bb8d922d4..a593024d418 100644 --- a/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol +++ b/l1-contracts/src/core/libraries/decoders/TxsDecoder.sol @@ -21,8 +21,8 @@ import {Hash} from "../Hash.sol"; * * | byte start | num bytes | name * | --- | --- | --- - * | 0x00 | 0x04 | len(newCommitments) (denoted a) - * | 0x04 | a * 0x20 | newCommitments + * | 0x00 | 0x04 | len(newNoteHashes) (denoted a) + * | 0x04 | a * 0x20 | newNoteHashes * | 0x04 + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) * | 0x08 + a * 0x20 | b * 0x20 | newNullifiers * | 0x08 + a * 0x20 + b * 0x20 | 0x04 | len(newPublicDataWrites) (denoted c) @@ -42,7 +42,7 @@ import {Hash} from "../Hash.sol"; */ library TxsDecoder { struct ArrayOffsets { - uint256 commitment; + uint256 noteHash; uint256 nullifier; uint256 publicData; uint256 l2ToL1Msgs; @@ -66,7 +66,7 @@ library TxsDecoder { /** * @notice Computes consumables for the block * @param _body - The L2 block calldata. - * @return diffRoot - The root of the diff tree (new commitments, nullifiers etc) + * @return diffRoot - The root of the diff tree (new note hashes, nullifiers etc) */ function decode(bytes calldata _body) internal pure returns (bytes32) { ArrayOffsets memory offsets; @@ -77,8 +77,8 @@ library TxsDecoder { // Commitments uint256 count = read4(_body, offset); - vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_COMMITMENTS_PER_TX); - offsets.commitment = 0x4; + vars.baseLeaves = new bytes32[](count / Constants.MAX_NEW_NOTE_HASHES_PER_TX); + offsets.noteHash = 0x4; offset += 0x4 + count * 0x20; offsets.nullifier = offset + 0x4; // + 0x4 to offset by next read4 @@ -128,7 +128,7 @@ library TxsDecoder { /* * Compute the leaf to insert. * Leaf_i = ( - * newCommitmentsKernel, + * newNoteHashesKernel, * newNullifiersKernel, * newPublicDataWritesKernel, * newL2ToL1MsgsKernel, @@ -155,7 +155,7 @@ library TxsDecoder { // Insertions are split into multiple `bytes.concat` to work around stack too deep. vars.baseLeaf = bytes.concat( bytes.concat( - slice(_body, offsets.commitment, Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP), + slice(_body, offsets.noteHash, Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.nullifier, Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.publicData, Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP), slice(_body, offsets.l2ToL1Msgs, Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP), @@ -169,7 +169,7 @@ library TxsDecoder { bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash) ); - offsets.commitment += Constants.COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP; + offsets.noteHash += Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP; offsets.nullifier += Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP; offsets.publicData += Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP; offsets.l2ToL1Msgs += Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP; diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 6e019069b59..3a5d178af07 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -20,7 +20,7 @@ use dep::protocol_types::{ }, address::{AztecAddress, EthAddress}, constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, @@ -49,7 +49,7 @@ struct PrivateContext { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack_hashes : BoundedVec, @@ -83,7 +83,7 @@ impl PrivateContext { return_values: BoundedVec::new(0), read_requests: BoundedVec::new(SideEffect::empty()), nullifier_key_validation_requests: BoundedVec::new(NullifierKeyValidationRequest::empty()), - new_commitments: BoundedVec::new(SideEffect::empty()), + new_note_hashes: BoundedVec::new(SideEffect::empty()), new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()), historical_header: inputs.historical_header, private_call_stack_hashes: BoundedVec::new(0), @@ -151,7 +151,7 @@ impl PrivateContext { min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack_hashes: self.private_call_stack_hashes.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, @@ -181,7 +181,7 @@ impl PrivateContext { pub fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; - self.new_commitments.push(side_effect); + self.new_note_hashes.push(side_effect); self.side_effect_counter = self.side_effect_counter + 1; } @@ -444,7 +444,7 @@ impl PrivateContext { contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL], new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL], unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256], diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 272b574b00a..9b82f578464 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -12,7 +12,7 @@ use dep::protocol_types::{ }, address::{AztecAddress, EthAddress}, constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH @@ -32,7 +32,7 @@ struct PublicContext { contract_storage_reads: BoundedVec, public_call_stack_hashes: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, @@ -58,7 +58,7 @@ impl PublicContext { contract_storage_update_requests: BoundedVec::new(empty_storage_update), contract_storage_reads: BoundedVec::new(empty_storage_read), public_call_stack_hashes: BoundedVec::new(0), - new_commitments: BoundedVec::new(SideEffect::empty()), + new_note_hashes: BoundedVec::new(SideEffect::empty()), new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()), new_l2_to_l1_msgs: BoundedVec::new(L2ToL1Message::empty()), unencrypted_logs_hash: BoundedVec::new(0), @@ -122,7 +122,7 @@ impl PublicContext { contract_storage_update_requests: self.contract_storage_update_requests.storage, contract_storage_reads: self.contract_storage_reads.storage, return_values: self.return_values.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, @@ -136,7 +136,7 @@ impl PublicContext { pub fn push_new_note_hash(&mut self, note_hash: Field) { let side_effect = SideEffect { value: note_hash, counter: self.side_effect_counter }; - self.new_commitments.push(side_effect); + self.new_note_hashes.push(side_effect); self.side_effect_counter = self.side_effect_counter + 1; } diff --git a/noir-projects/aztec-nr/aztec/src/note/utils.nr b/noir-projects/aztec-nr/aztec/src/note/utils.nr index 8aa346dc16a..41af73a6ed7 100644 --- a/noir-projects/aztec-nr/aztec/src/note/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/note/utils.nr @@ -2,21 +2,18 @@ use crate::{context::PrivateContext, note::{note_header::NoteHeader, note_interf use dep::protocol_types::{ address::AztecAddress, - constants::{ - GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_COMMITMENT, - GENERATOR_INDEX__SILOED_COMMITMENT -}, + constants::{GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__UNIQUE_NOTE_HASH, GENERATOR_INDEX__SILOED_NOTE_HASH}, hash::pedersen_hash, utils::arr_copy_slice }; fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field { let inputs = [contract_address.to_field(), inner_note_hash]; - pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT) + pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH) } fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field { let inputs = [nonce, siloed_note_hash]; - pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT) + pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH) } fn compute_inner_note_hash(note: Note) -> Field where Note: NoteInterface { diff --git a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr index 69b504d2c6d..894fccf454c 100644 --- a/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_commitments_contract/src/main.nr @@ -23,7 +23,7 @@ contract PendingCommitments { #[aztec(private)] fn constructor() {} - // Confirm can access pending commitments by creating / inserting a note and then + // Confirm can access pending note hashes by creating / inserting a note and then // getting / reading that note all in the same contract function // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" #[aztec(private)] @@ -107,7 +107,7 @@ contract PendingCommitments { assert(maybe_notes[1].is_none()); } - // Test pending commitments with note insertion done in a nested call + // Test pending note hashes with note insertion done in a nested call // and "read" / get of that pending note/commitment in another nested call // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" #[aztec(private)] @@ -244,7 +244,7 @@ contract PendingCommitments { [owner.to_field()] ); } - // Confirm cannot get/read a pending commitment in a nested call + // Confirm cannot get/read a pending note hash in a nested call // that is created/inserted later in execution but in the parent. // NOTE: This test is especially important in an end-to-end context because the parent call // (and therefore the insertion) will be processed in an earlier kernel iteration, but the diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index ba8476925e9..3a9adffd96b 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -13,7 +13,7 @@ use dep::types::{ address::{AztecAddress, EthAddress, PartialAddress, compute_initialization_hash}, contract_class_id::ContractClassId, contrakt::contract_deployment_data::ContractDeploymentData, constants::{ - MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL }, @@ -22,7 +22,7 @@ use dep::types::{ compute_constructor_hash, compute_l2_to_l1_hash, compute_logs_hash, compute_new_contract_address_hash, contract_tree_root_from_siblings, function_tree_root_from_siblings, pedersen_hash, private_functions_root_from_siblings, - read_request_root_from_siblings, silo_commitment, silo_nullifier, + read_request_root_from_siblings, silo_note_hash, silo_nullifier, stdlib_recursion_verification_key_compress_native_vk }, utils::{arrays::{array_length, array_to_bounded_vec, validate_array}}, @@ -31,13 +31,13 @@ use dep::types::{ pub fn validate_arrays(app_public_inputs: PrivateCircuitPublicInputs) { // Each of the following arrays is expected to be zero-padded. - // In addition, some of the following arrays (new_commitments, etc...) are passed + // In addition, some of the following arrays (new_note_hashes, etc...) are passed // to extend_from_array_to_array() routines which rely on the passed arrays to be well-formed. validate_array(app_public_inputs.return_values); validate_array(app_public_inputs.read_requests); validate_array(app_public_inputs.nullifier_key_validation_requests); - validate_array(app_public_inputs.new_commitments); + validate_array(app_public_inputs.new_note_hashes); validate_array(app_public_inputs.new_nullifiers); validate_array(app_public_inputs.private_call_stack_hashes); validate_array(app_public_inputs.public_call_stack_hashes); @@ -63,11 +63,11 @@ pub fn validate_read_requests( let read_request = read_requests[rr_idx].value; let witness = read_request_membership_witnesses[rr_idx]; - // A pending commitment is the one that is not yet added to note hash tree - // A "transient read" is when we try to "read" a pending commitment within a transaction + // A pending note hash is the one that is not yet added to note hash tree + // A "transient read" is when we try to "read" a pending note hash within a transaction // between function calls, as opposed to reading the outputs of a previous transaction // which is a "pending read". - // A transient read is when we try to "read" a pending commitment + // A transient read is when we try to "read" a pending note hash // We determine if it is a transient read depending on the leaf index from the membership witness // Note that the Merkle membership proof would be null and void in case of an transient read // but we use the leaf index as a placeholder to detect a 'pending note read'. @@ -95,7 +95,7 @@ pub fn initialize_end_values( public_inputs.end.read_requests = array_to_bounded_vec(start.read_requests); public_inputs.end.nullifier_key_validation_requests = array_to_bounded_vec(start.nullifier_key_validation_requests); - public_inputs.end.new_commitments = array_to_bounded_vec(start.new_commitments); + public_inputs.end.new_note_hashes = array_to_bounded_vec(start.new_note_hashes); public_inputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); public_inputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); @@ -117,7 +117,7 @@ fn perform_static_call_checks(private_call: PrivateCallData) { if is_static_call { // No state changes are allowed for static calls: assert( - is_empty_array(public_inputs.new_commitments), "new_commitments must be empty for static calls" + is_empty_array(public_inputs.new_note_hashes), "new_note_hashes must be empty for static calls" ); assert( is_empty_array(public_inputs.new_nullifiers), "new_nullifiers must be empty for static calls" @@ -180,7 +180,7 @@ pub fn update_end_values( let nullifier_key_validation_requests = private_call_public_inputs.nullifier_key_validation_requests; - let new_commitments = private_call_public_inputs.new_commitments; + let new_note_hashes = private_call_public_inputs.new_note_hashes; let new_nullifiers = private_call_public_inputs.new_nullifiers; let storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; @@ -193,7 +193,7 @@ pub fn update_end_values( let witness = read_request_membership_witnesses[i]; if witness.is_transient & (read_request != 0) { // only forward transient to public inputs siloed_read_requests.push( - SideEffect { counter: read_requests[i].counter, value: silo_commitment(storage_contract_address, read_request) } + SideEffect { counter: read_requests[i].counter, value: silo_note_hash(storage_contract_address, read_request) } ) } } @@ -217,7 +217,7 @@ pub fn update_end_values( let siloed_note_hash = if new_nullifier.note_hash == 0 { 0 } else { - silo_commitment(storage_contract_address, new_nullifier.note_hash) + silo_note_hash(storage_contract_address, new_nullifier.note_hash) }; siloed_new_nullifiers.push( SideEffectLinkedToNoteHash { @@ -230,17 +230,17 @@ pub fn update_end_values( } public_inputs.end.new_nullifiers.extend_from_bounded_vec(siloed_new_nullifiers); - // commitments - let mut siloed_new_commitments: BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - siloed_new_commitments.push( - SideEffect { value: silo_commitment(storage_contract_address, new_commitment), counter: new_commitments[i].counter } + // note hashes + let mut siloed_new_note_hashes: BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + siloed_new_note_hashes.push( + SideEffect { value: silo_note_hash(storage_contract_address, new_note_hash), counter: new_note_hashes[i].counter } ); } } - public_inputs.end.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + public_inputs.end.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); // Call stacks // Private call stack. diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr index 5758d7550b5..066072019e1 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr @@ -277,7 +277,7 @@ mod tests { fn input_validation_malformed_arrays_commitments() { let mut builder = PrivateKernelInitInputsBuilder::new_constructor(); - builder.private_call.public_inputs.new_commitments.extend_from_array( + builder.private_call.public_inputs.new_note_hashes.extend_from_array( [ SideEffect { value: 0, counter: 0 }, SideEffect { value: 9123, counter: 1 } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index d91407955f9..d4234a022fd 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -85,7 +85,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { mod tests { use crate::private_kernel_inner::PrivateKernelInnerCircuitPrivateInputs; - use dep::types::constants::{MAX_READ_REQUESTS_PER_CALL, MAX_NEW_COMMITMENTS_PER_TX}; + use dep::types::constants::{MAX_READ_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX}; use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, @@ -455,7 +455,7 @@ mod tests { fn input_validation_malformed_arrays_commitments() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.private_call.public_inputs.new_commitments.extend_from_array( + builder.private_call.public_inputs.new_note_hashes.extend_from_array( [ SideEffect { value: 0, counter: 0 }, SideEffect { value: 9123, counter: 1 } @@ -516,17 +516,17 @@ mod tests { let mut builder = PrivateKernelInnerInputsBuilder::new(); // The current call stack has 1 commitment; - builder.private_call.public_inputs.new_commitments.push(SideEffect { value: 4321, counter: 0 }); + builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 4321, counter: 0 }); - // Mock the previous new commitments to be full, therefore no more commitments can be added. - let mut full_new_commitments = [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_TX]; - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { - full_new_commitments[i] = SideEffect { + // Mock the previous new note hashes to be full, therefore no more commitments can be added. + let mut full_new_note_hashes = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + full_new_note_hashes[i] = SideEffect { value: i + 1, counter: i as u32, }; } - builder.previous_kernel.end.new_commitments.extend_from_array(full_new_commitments); + builder.previous_kernel.end.new_note_hashes.extend_from_array(full_new_note_hashes); builder.failed(); } @@ -728,11 +728,11 @@ mod tests { assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); } - #[test(should_fail_with="new_commitments must be empty for static calls")] - fn creating_new_commitments_on_static_call_fails() { + #[test(should_fail_with="new_note_hashes must be empty for static calls")] + fn creating_new_note_hashes_on_static_call_fails() { let mut builder = PrivateKernelInnerInputsBuilder::new().is_static_call(); - builder.private_call.public_inputs.new_commitments.push(SideEffect { value: 1, counter: 0 }); + builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 1, counter: 0 }); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 1569820df9a..eaa0fc06353 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -8,19 +8,19 @@ use dep::types::{ side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, constants::{ - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_READ_REQUESTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX }, grumpkin_private_key::GrumpkinPrivateKey, - hash::{compute_commitment_nonce, compute_unique_siloed_commitment}, + hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, utils::{arrays::{array_length, array_eq}}, traits::{Empty, is_empty} }; struct PrivateKernelTailCircuitPrivateInputs { previous_kernel: PrivateKernelInnerData, - sorted_new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], - sorted_new_commitments_indexes: [u32; MAX_NEW_COMMITMENTS_PER_TX], + sorted_new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_new_note_hashes_indexes: [u32; MAX_NEW_NOTE_HASHES_PER_TX], read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], sorted_new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_TX], @@ -58,7 +58,7 @@ impl PrivateKernelTailCircuitPrivateInputs { } fn match_reads_to_commitments(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - let new_commitments = public_inputs.end.new_commitments; + let new_note_hashes = public_inputs.end.new_note_hashes; let read_requests = public_inputs.end.read_requests; // match reads to commitments from the previous call(s) @@ -67,12 +67,10 @@ impl PrivateKernelTailCircuitPrivateInputs { let read_commitment_hint = self.read_commitment_hints[rr_idx] as u64; if (read_request.value != 0) { - let commitment = new_commitments.get_unchecked(read_commitment_hint as Field); - assert_eq( - read_request.value, commitment.value, "Hinted commitment does not match read request" - ); + let hash = new_note_hashes.get_unchecked(read_commitment_hint as Field); + assert_eq(read_request.value, hash.value, "Hinted hash does not match read request"); assert( - read_request.counter > commitment.counter, "Read request counter must be greater than commitment counter" + read_request.counter > hash.counter, "Read request counter must be greater than hash counter" ); } } @@ -105,48 +103,48 @@ impl PrivateKernelTailCircuitPrivateInputs { fn sort_arrays(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( - public_inputs.end.new_commitments.storage, - self.sorted_new_commitments, - self.sorted_new_commitments_indexes + public_inputs.end.new_note_hashes.storage, + self.sorted_new_note_hashes, + self.sorted_new_note_hashes_indexes ); PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( public_inputs.end.new_nullifiers.storage, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes ); - public_inputs.end.new_commitments.storage = self.sorted_new_commitments; + public_inputs.end.new_note_hashes.storage = self.sorted_new_note_hashes; public_inputs.end.new_nullifiers.storage = self.sorted_new_nullifiers; } - fn match_nullifiers_to_commitments_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { + fn match_nullifiers_to_note_hashes_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // Match nullifiers/nullified_commitments to commitments from the previous call(s) - let mut new_commitments = public_inputs.end.new_commitments.storage; + let mut new_note_hashes = public_inputs.end.new_note_hashes.storage; let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { let nullifier = new_nullifiers[n_idx]; // TODO - should not be able to squash the first nullifier. - let nullified_commitment = nullifier.note_hash; + let nullified_note_hash = nullifier.note_hash; let hint_pos = self.nullifier_commitment_hints[n_idx] as u64; // Nullified_commitment of value `0` implies non-transient (persistable) - // nullifier in which case no attempt will be made to match it to a commitment. - // Non-empty nullified_commitment implies transient nullifier which MUST be matched to a commitment below! - // 0-valued nullified_commitment is empty and will be ignored - if nullified_commitment != 0 { + // nullifier in which case no attempt will be made to match it to a hash. + // Non-empty nullified_note_hash implies transient nullifier which MUST be matched to a hash below! + // 0-valued nullified_note_hash is empty and will be ignored + if nullified_note_hash != 0 { assert( - hint_pos < MAX_NEW_COMMITMENTS_PER_TX as u64, "New nullifier is transient but hint is invalid" + hint_pos < MAX_NEW_NOTE_HASHES_PER_TX as u64, "New nullifier is transient but hint is invalid" ); - let commitment = new_commitments[hint_pos]; - assert_eq(nullified_commitment, commitment.value, "Hinted commitment does not match"); + let hash = new_note_hashes[hint_pos]; + assert_eq(nullified_note_hash, hash.value, "Hinted hash does not match"); assert( - nullifier.counter > commitment.counter, "Nullifier counter must be greater than commitment counter" + nullifier.counter > hash.counter, "Nullifier counter must be greater than hash counter" ); // match found! - // squash both the nullifier and the commitment + // squash both the nullifier and the hash // (set to 0 here and then rearrange array after loop) - new_commitments[hint_pos] = SideEffect::empty(); + new_note_hashes[hint_pos] = SideEffect::empty(); new_nullifiers[n_idx as u64] = SideEffectLinkedToNoteHash::empty(); } // non-transient (persistable) nullifiers are just kept in new_nullifiers array and forwarded @@ -155,15 +153,15 @@ impl PrivateKernelTailCircuitPrivateInputs { // Move all zero-ed (removed) entries of these arrays to the end and preserve ordering of other entries - let mut new_commitments_vec = BoundedVec::new(SideEffect::empty()); + let mut new_note_hashes_vec = BoundedVec::new(SideEffect::empty()); - for c_idx in 0..MAX_NEW_COMMITMENTS_PER_TX { - if new_commitments[c_idx].value != 0 { - new_commitments_vec.push(new_commitments[c_idx]); + for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { + if new_note_hashes[c_idx].value != 0 { + new_note_hashes_vec.push(new_note_hashes[c_idx]); } } - public_inputs.end.new_commitments = new_commitments_vec; + public_inputs.end.new_note_hashes = new_note_hashes_vec; let mut new_nullifiers_vec = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); @@ -176,27 +174,27 @@ impl PrivateKernelTailCircuitPrivateInputs { public_inputs.end.new_nullifiers = new_nullifiers_vec; } - fn apply_commitment_nonces(public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { + fn apply_note_hash_nonces(public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // tx hash let first_nullifier = public_inputs.end.new_nullifiers.get(0); - let mut unique_commitments = public_inputs.end.new_commitments.storage; - - for c_idx in 0..MAX_NEW_COMMITMENTS_PER_TX { - // Apply nonce to all non-zero/non-empty commitments - // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_commitments array - let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); - let commitment = unique_commitments[c_idx]; - if commitment.value != 0 { - let unique_commitment = compute_unique_siloed_commitment(nonce, commitment.value); - unique_commitments[c_idx] = SideEffect{ - value: unique_commitment, - counter: commitment.counter + let mut siloed_note_hashes = public_inputs.end.new_note_hashes.storage; + + for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { + // Apply nonce to all non-zero/non-empty note hashes + // Nonce is the hash of the first (0th) nullifier and the note hash's index into new_note_hashes array + let nonce = compute_note_hash_nonce(first_nullifier.value, c_idx); + let hash = siloed_note_hashes[c_idx]; + if hash.value != 0 { + let unique_note_hash = compute_unique_siloed_note_hash(nonce, hash.value); + siloed_note_hashes[c_idx] = SideEffect{ + value: unique_note_hash, + counter: hash.counter }; } } - public_inputs.end.new_commitments.storage = unique_commitments; + public_inputs.end.new_note_hashes.storage = siloed_note_hashes; } pub fn native_private_kernel_circuit_ordering(self) -> PrivateKernelTailCircuitPublicInputs { @@ -216,9 +214,9 @@ impl PrivateKernelTailCircuitPrivateInputs { self.match_reads_to_commitments(&mut public_inputs); - self.match_nullifiers_to_commitments_and_squash(&mut public_inputs); + self.match_nullifiers_to_note_hashes_and_squash(&mut public_inputs); - PrivateKernelTailCircuitPrivateInputs::apply_commitment_nonces(&mut public_inputs); + PrivateKernelTailCircuitPrivateInputs::apply_note_hash_nonces(&mut public_inputs); public_inputs.to_tail() } @@ -228,15 +226,15 @@ mod tests { use dep::std::cmp::Eq; use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; use dep::types::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX + MAX_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX }; use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, - hash::compute_unique_siloed_commitments, tests::kernel_data_builder::PreviousKernelDataBuilder, + hash::compute_unique_siloed_note_hashes, tests::kernel_data_builder::PreviousKernelDataBuilder, utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array} }; @@ -255,28 +253,28 @@ mod tests { } } - pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { - self.previous_kernel.end.new_commitments.storage + pub fn get_new_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { + self.previous_kernel.end.new_note_hashes.storage } pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { self.previous_kernel.end.new_nullifiers.storage } - pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { - self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) + pub fn get_unique_siloed_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { + self.compute_unique_siloed_note_hashes(self.previous_kernel.end.new_note_hashes.storage) } // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // commitments for the given commitments. - pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { + pub fn compute_unique_siloed_note_hashes(self, commitments: [SideEffect; N]) -> [SideEffect; N] { let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); - compute_unique_siloed_commitments(first_nullifier.value, commitments) + compute_unique_siloed_note_hashes(first_nullifier.value, commitments) } pub fn append_transient_commitments(&mut self, num_commitments: Field) { - // All new commitments aggregated in the previous kernel are transient commitments. - self.previous_kernel.append_new_commitments(num_commitments); + // All new note hashes aggregated in the previous kernel are transient commitments. + self.previous_kernel.append_new_note_hashes(num_commitments); } pub fn add_transient_read(&mut self, commitment_index: Field) { @@ -289,7 +287,7 @@ mod tests { } pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { - self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; + self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_note_hashes.get(commitment_index).value; self.nullifier_commitment_hints[nullifier_index] = commitment_index; } @@ -321,10 +319,10 @@ mod tests { } pub fn execute(&mut self) -> PrivateKernelTailCircuitPublicInputs { - let (sorted_new_commitments, sorted_new_commitments_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); + let (sorted_new_note_hashes, sorted_new_note_hashes_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_note_hashes()); let mut sorted_read_commitment_hints = [0; MAX_READ_REQUESTS_PER_TX]; for i in 0..sorted_read_commitment_hints.len() { - sorted_read_commitment_hints[i] = sorted_new_commitments_indexes[self.read_commitment_hints[i]] as Field; + sorted_read_commitment_hints[i] = sorted_new_note_hashes_indexes[self.read_commitment_hints[i]] as Field; } let (sorted_new_nullifiers, sorted_new_nullifiers_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_nullifiers()); let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; @@ -334,8 +332,8 @@ mod tests { let kernel = PrivateKernelTailCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_inner_data(), - sorted_new_commitments, - sorted_new_commitments_indexes, + sorted_new_note_hashes, + sorted_new_note_hashes_indexes, read_commitment_hints: sorted_read_commitment_hints, sorted_new_nullifiers, sorted_new_nullifiers_indexes, @@ -365,40 +363,40 @@ mod tests { builder.append_transient_commitments(1); builder.add_transient_read(0); - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); let public_inputs = builder.execute(); - assert(array_length(public_inputs.end.new_commitments) == 1); - assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); + assert(array_length(public_inputs.end.new_note_hashes) == 1); + assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_note_hashes[0])); } #[test] unconstrained fn native_matching_some_read_requests_to_commitments_works() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); - // prepare for the split: first MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX are added to end_non_revertible_accumulted_data + builder.append_transient_commitments(MAX_NEW_NOTE_HASHES_PER_TX); + // prepare for the split: first MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX are added to end_non_revertible_accumulted_data // neeed to take the counter of the side effect at the given index because - builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_commitments.get(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX).counter; - // Read the commitment at index 1; + builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_note_hashes.get(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX).counter; + // Read the hash at index 1; builder.add_transient_read(1); - // Read the commitment at index 3; + // Read the hash at index 3; builder.add_transient_read(3); - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_commitments), MAX_REVERTIBLE_COMMITMENTS_PER_TX); - for i in 0..MAX_REVERTIBLE_COMMITMENTS_PER_TX { + assert_eq(array_length(public_inputs.end.new_note_hashes), MAX_REVERTIBLE_NOTE_HASHES_PER_TX); + for i in 0..MAX_REVERTIBLE_NOTE_HASHES_PER_TX { assert( - public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX + i]) + public_inputs.end.new_note_hashes[i].eq(unique_siloed_note_hashes[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) ); } } - #[test(should_fail_with="Hinted commitment does not match read request")] + #[test(should_fail_with="Hinted hash does not match read request")] unconstrained fn native_read_request_unknown_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.add_transient_read(0); - // Tweak the read request so that it does not match the commitment at index 0; + // Tweak the read request so that it does not match the hash at index 0; let read_request = builder.previous_kernel.end.read_requests.pop(); builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); builder.failed(); @@ -409,11 +407,11 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); // The nullifier at index 1 is chopped. assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[2]])); @@ -431,17 +429,17 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); - let new_commitments = builder.get_new_commitments(); - // The 0th commitment will be chopped. - let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); + let new_note_hashes = builder.get_new_note_hashes(); + // The 0th hash will be chopped. + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes([new_note_hashes[1]]); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); assert( array_eq( - public_inputs.end.new_commitments, - [unique_siloed_commitments[0]] + public_inputs.end.new_note_hashes, + [unique_siloed_note_hashes[0]] ) ); // The nullifier at index 1 is chopped. @@ -461,15 +459,15 @@ mod tests { builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; + // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; + // The nullifier at index 2 is nullifying the hash at index 0; builder.nullify_transient_commitment(2, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); // app logic will be completely empty after squashing - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); assert(is_empty_array(public_inputs.end.new_nullifiers)); // and the 0th nullifier will be moved to the non-revertible array @@ -485,29 +483,29 @@ mod tests { unconstrained fn ordering_of_commitments_and_nullifiers() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - let mut sorted_new_commitments = [SideEffect::empty(); 10]; + let mut sorted_new_note_hashes = [SideEffect::empty(); 10]; let mut sorted_new_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; for i in 0..10 { - sorted_new_commitments[i] = SideEffect { value: (i + 1) as Field, counter: builder.previous_kernel.next_sideffect_counter() }; + sorted_new_note_hashes[i] = SideEffect { value: (i + 1) as Field, counter: builder.previous_kernel.next_sideffect_counter() }; sorted_new_nullifiers[i] = SideEffectLinkedToNoteHash { value: (i + 11) as Field, counter: builder.previous_kernel.next_sideffect_counter(), note_hash: 0 }; } for i in 0..10 { - builder.previous_kernel.end.new_commitments.push(sorted_new_commitments[9 - i]); + builder.previous_kernel.end.new_note_hashes.push(sorted_new_note_hashes[9 - i]); builder.previous_kernel.end.new_nullifiers.push(sorted_new_nullifiers[9 - i]); } let public_inputs = builder.execute(); - let sorted_unique_commitments = compute_unique_siloed_commitments( + let sorted_unique_note_hashes = compute_unique_siloed_note_hashes( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, - sorted_new_commitments + sorted_new_note_hashes ); for i in 0..10 { - assert(public_inputs.end.new_commitments[i].eq(sorted_unique_commitments[i])); + assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashes[i])); assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); } } @@ -518,7 +516,7 @@ mod tests { builder.append_transient_commitments(2); builder.append_nullifiers(2); let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_commitments), 2); + assert_eq(array_length(public_inputs.end.new_note_hashes), 2); assert_eq(array_length(public_inputs.end.new_nullifiers), 2); assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } @@ -530,7 +528,7 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_nullifiers(2); let public_inputs = builder.execute(); - assert(array_length(public_inputs.end.new_commitments) == 0); + assert(array_length(public_inputs.end.new_note_hashes) == 0); assert(array_length(public_inputs.end.new_nullifiers) == 2); assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } @@ -540,23 +538,23 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.append_nullifiers(1); - // The nullifier at index 1 is nullifying the commitment at index 0; + // The nullifier at index 1 is nullifying the hash at index 0; builder.nullify_transient_commitment(1, 0); // Change the hint to be out of bounds. - builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; + builder.nullifier_commitment_hints[1] = MAX_NEW_NOTE_HASHES_PER_TX; builder.failed(); } - #[test(should_fail_with="Hinted commitment does not match")] + #[test(should_fail_with="Hinted hash does not match")] unconstrained fn wrong_nullifier_commitment_hint_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(2); builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; + // The nullifier at index 1 is nullifying the hash at index 1; builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; + // The nullifier at index 2 is nullifying the hash at index 0; builder.nullify_transient_commitment(2, 0); - // Tweak the hint to be for the commitment at index 1. + // Tweak the hint to be for the hash at index 1. builder.nullifier_commitment_hints[2] = 1; builder.failed(); } @@ -608,32 +606,32 @@ mod tests { let mut builder = PrivateKernelOrderingInputsBuilder::new(); // expect 2 non-revertible commitments - builder.previous_kernel.append_new_commitments(2); + builder.previous_kernel.append_new_note_hashes(2); builder.previous_kernel.capture_min_revertible_side_effect_counter(); // expect 2 revertible commitments - builder.previous_kernel.append_new_commitments(2); + builder.previous_kernel.append_new_note_hashes(2); - let new_commitments = builder.previous_kernel.end.new_commitments.storage; + let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; let public_inputs = builder.execute(); - let unique_commitments = compute_unique_siloed_commitments( + let siloed_note_hashes = compute_unique_siloed_note_hashes( // tx nullifier is part of non revertible accumulated data public_inputs.end_non_revertible.new_nullifiers[0].value, - new_commitments + new_note_hashes ); assert( array_eq( - public_inputs.end_non_revertible.new_commitments, - [unique_commitments[0], unique_commitments[1]] + public_inputs.end_non_revertible.new_note_hashes, + [siloed_note_hashes[0], siloed_note_hashes[1]] ) ); assert( array_eq( - public_inputs.end.new_commitments, - [unique_commitments[2], unique_commitments[3]] + public_inputs.end.new_note_hashes, + [siloed_note_hashes[2], siloed_note_hashes[3]] ) ); } @@ -642,8 +640,8 @@ mod tests { unconstrained fn split_side_effect_squashing() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); - // add one commitment in non-revertible part - builder.previous_kernel.append_new_commitments(1); + // add one hash in non-revertible part + builder.previous_kernel.append_new_note_hashes(1); builder.previous_kernel.capture_min_revertible_side_effect_counter(); // nullify it in revertible part @@ -653,8 +651,8 @@ mod tests { let public_inputs = builder.execute(); assert(!is_empty_array(public_inputs.end_non_revertible.new_nullifiers)); - assert(is_empty_array(public_inputs.end_non_revertible.new_commitments)); - assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end_non_revertible.new_note_hashes)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); assert(is_empty_array(public_inputs.end.new_nullifiers)); } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr index 61828e9f813..a6842068219 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr @@ -11,13 +11,13 @@ use dep::types::{ address::AztecAddress, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, constants::{ - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_CALL, NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX }, - hash::{silo_commitment, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, + hash::{silo_note_hash, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, utils::{arrays::{array_length, array_to_bounded_vec}}, traits::{is_empty, is_empty_array} }; use crate::hash::{compute_public_data_tree_index, compute_public_data_tree_value}; @@ -53,7 +53,7 @@ pub fn initialize_end_values( // functions within this circuit: let start = previous_kernel.public_inputs.end; - circuit_outputs.end.new_commitments = array_to_bounded_vec(start.new_commitments); + circuit_outputs.end.new_note_hashes = array_to_bounded_vec(start.new_note_hashes); circuit_outputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); circuit_outputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); @@ -70,7 +70,7 @@ pub fn initialize_end_values( circuit_outputs.end.new_contracts = array_to_bounded_vec(previous_kernel.public_inputs.end.new_contracts); let start_non_revertible = previous_kernel.public_inputs.end_non_revertible; - circuit_outputs.end_non_revertible.new_commitments = array_to_bounded_vec(start_non_revertible.new_commitments); + circuit_outputs.end_non_revertible.new_note_hashes = array_to_bounded_vec(start_non_revertible.new_note_hashes); circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers); circuit_outputs.end_non_revertible.public_call_stack = array_to_bounded_vec(start_non_revertible.public_call_stack); @@ -82,8 +82,8 @@ fn perform_static_call_checks(public_call: PublicCallData) { let public_inputs = public_call.call_stack_item.public_inputs; if public_inputs.call_context.is_static_call { // No state changes are allowed for static calls: - let new_commitments_length = array_length(public_inputs.new_commitments); - assert(new_commitments_length == 0, "new_commitments must be empty for static calls"); + let new_note_hashes_length = array_length(public_inputs.new_note_hashes); + assert(new_note_hashes_length == 0, "new_note_hashes must be empty for static calls"); let new_nullifiers_length = array_length(public_inputs.new_nullifiers); assert(new_nullifiers_length == 0, "new_nullifiers must be empty for static calls"); @@ -148,7 +148,7 @@ pub fn update_public_end_non_revertible_values( circuit_outputs.end_non_revertible.public_call_stack.extend_from_bounded_vec(public_call_requests); propagate_new_nullifiers_non_revertible(public_call, circuit_outputs); - propagate_new_commitments_non_revertible(public_call, circuit_outputs); + propagate_new_note_hashes_non_revertible(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_update_requests(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_reads(public_call, circuit_outputs); // TODO(fees) propagate the following to non-revertible @@ -168,7 +168,7 @@ pub fn update_public_end_values(public_call: PublicCallData, circuit_outputs: &m circuit_outputs.end.public_call_stack.extend_from_bounded_vec(public_call_requests); propagate_new_nullifiers(public_call, circuit_outputs); - propagate_new_commitments(public_call, circuit_outputs); + propagate_new_note_hashes(public_call, circuit_outputs); propagate_new_l2_to_l1_messages(public_call, circuit_outputs); @@ -268,44 +268,44 @@ fn propagate_valid_non_revertible_public_data_reads( circuit_outputs.end_non_revertible.public_data_reads.extend_from_bounded_vec(public_data_reads); } -fn propagate_new_commitments_non_revertible( +fn propagate_new_note_hashes_non_revertible( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder ) { let public_call_public_inputs = public_call.call_stack_item.public_inputs; - let new_commitments = public_call.call_stack_item.public_inputs.new_commitments; + let new_note_hashes = public_call.call_stack_item.public_inputs.new_note_hashes; let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; - let mut siloed_new_commitments : BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - let siloed_new_commitment = silo_commitment(storage_contract_address, new_commitment); - siloed_new_commitments.push(SideEffect { value: siloed_new_commitment, counter: new_commitments[i].counter }); + let mut siloed_new_note_hashes : BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + let siloed_new_note_hash = silo_note_hash(storage_contract_address, new_note_hash); + siloed_new_note_hashes.push(SideEffect { value: siloed_new_note_hash, counter: new_note_hashes[i].counter }); } } - circuit_outputs.end_non_revertible.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + circuit_outputs.end_non_revertible.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); } -fn propagate_new_commitments( +fn propagate_new_note_hashes( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder ) { let public_call_public_inputs = public_call.call_stack_item.public_inputs; - let new_commitments = public_call.call_stack_item.public_inputs.new_commitments; + let new_note_hashes = public_call.call_stack_item.public_inputs.new_note_hashes; let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; - let mut siloed_new_commitments : BoundedVec = BoundedVec::new(SideEffect::empty()); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - let new_commitment = new_commitments[i].value; - if new_commitment != 0 { - let siloed_new_commitment = silo_commitment(storage_contract_address, new_commitment); - siloed_new_commitments.push(SideEffect { value: siloed_new_commitment, counter: new_commitments[i].counter }); + let mut siloed_new_note_hashes : BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + let new_note_hash = new_note_hashes[i].value; + if new_note_hash != 0 { + let siloed_new_note_hash = silo_note_hash(storage_contract_address, new_note_hash); + siloed_new_note_hashes.push(SideEffect { value: siloed_new_note_hash, counter: new_note_hashes[i].counter }); } } - circuit_outputs.end.new_commitments.extend_from_bounded_vec(siloed_new_commitments); + circuit_outputs.end.new_note_hashes.extend_from_bounded_vec(siloed_new_note_hashes); } fn propagate_new_nullifiers_non_revertible( diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr index 9a656d26859..8fb3ddf3c57 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -66,7 +66,7 @@ mod tests { side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, - hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_commitment, silo_nullifier}, + hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_note_hash, silo_nullifier}, messaging::l2_to_l1_message::L2ToL1Message, tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::array_eq} @@ -168,23 +168,23 @@ mod tests { fn circuit_outputs_should_be_correctly_populated_with_previous_commitments() { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); let contract_address = builder.public_call.contract_address; - // Setup 2 new commitments on the previous kernel. - builder.previous_kernel.append_new_commitments(2); - let previous = builder.previous_kernel.end.new_commitments.storage; - // Setup 2 new commitments on the current public inputs. + // Setup 2 new note hashes on the previous kernel. + builder.previous_kernel.append_new_note_hashes(2); + let previous = builder.previous_kernel.end.new_note_hashes.storage; + // Setup 2 new note hashes on the current public inputs. let current = [ SideEffect { value: previous[1].value + 1, counter: 3 }, SideEffect { value: previous[1].value + 2, counter: 4 } ]; - builder.public_call.public_inputs.new_commitments.extend_from_array(current); - let siloed = current.map(|c: SideEffect| silo_commitment(contract_address, c.value)); - let new_commitments = [ + builder.public_call.public_inputs.new_note_hashes.extend_from_array(current); + let siloed = current.map(|c: SideEffect| silo_note_hash(contract_address, c.value)); + let new_note_hashes = [ previous[0], previous[1], SideEffect { value: siloed[0], counter: 3 }, SideEffect { value: siloed[1], counter: 4 } ]; let public_inputs = builder.execute(); - assert(array_eq(public_inputs.end.new_commitments, new_commitments)); + assert(array_eq(public_inputs.end.new_note_hashes, new_note_hashes)); } #[test] @@ -232,7 +232,7 @@ mod tests { // Setup 2 new nullifiers on the previous kernel. builder.previous_kernel.append_new_nullifiers_from_public(2); let previous = builder.previous_kernel.end.new_nullifiers.storage; - // Setup 2 new commitments on the current public inputs. + // Setup 2 new note hashes on the current public inputs. let current = [ SideEffectLinkedToNoteHash { value: previous[1].value + 1, note_hash: 0, counter: 4 }, SideEffectLinkedToNoteHash { value: previous[1].value + 2, note_hash: 0, counter: 5 } @@ -326,11 +326,11 @@ mod tests { builder.failed(); } - #[test(should_fail_with="new_commitments must be empty for static calls")] - fn public_kernel_fails_creating_new_commitments_on_static_call() { + #[test(should_fail_with="new_note_hashes must be empty for static calls")] + fn public_kernel_fails_creating_new_note_hashes_on_static_call() { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); builder.public_call.public_inputs.call_context.is_static_call = true; - builder.public_call.public_inputs.new_commitments.push(SideEffect { value: 1, counter: 0 }); + builder.public_call.public_inputs.new_note_hashes.push(SideEffect { value: 1, counter: 0 }); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index d6f86134c40..9d9433400ce 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -21,13 +21,13 @@ use dep::types::{ NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, NUM_FIELDS_PER_SHA256, - MAX_NEW_COMMITMENTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, NUM_ENCRYPTED_LOGS_HASHES_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_HEIGHT, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX }, mocked::{AggregationObject, Proof}, partial_state_reference::PartialStateReference, @@ -164,7 +164,7 @@ impl BaseRollupInputs { // TODO(Kev): This should say calculate_commitments_subtree_root // Cpp code says calculate_commitments_subtree, so I'm leaving it as is for now fn calculate_commitments_subtree(self, combined: CombinedAccumulatedData) -> Field { - calculate_subtree(combined.new_commitments.map(|c: SideEffect| c.value)) + calculate_subtree(combined.new_note_hashes.map(|c: SideEffect| c.value)) } fn check_nullifier_tree_non_membership_and_insert_to_tree(self, combined: CombinedAccumulatedData) -> AppendOnlyTreeSnapshot { @@ -256,7 +256,7 @@ impl BaseRollupInputs { fn components_compute_kernel_calldata_hash(combined: CombinedAccumulatedData) -> [Field; NUM_FIELDS_PER_SHA256] { // Compute calldata hashes // Consist of - // MAX_NEW_COMMITMENTS_PER_TX fields for commitments + // MAX_NEW_NOTE_HASHES_PER_TX fields for commitments // MAX_NEW_NULLIFIERS_PER_TX fields for nullifiers // 32 public data update requests -> 64 fields // 2 l2 -> l1 messages -> 2 fields @@ -265,7 +265,7 @@ impl BaseRollupInputs { // 1 unencrypted logs hashes -> 2 fields --> 2 sha256 hashes --> 64 bytes let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - let new_commitments = combined.new_commitments; + let new_note_hashes = combined.new_note_hashes; let new_nullifiers = combined.new_nullifiers; let public_data_update_requests = combined.public_data_update_requests; let newL2ToL1msgs = combined.new_l2_to_l1_msgs; @@ -274,10 +274,10 @@ impl BaseRollupInputs { let mut offset = 0; - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { - calldata_hash_inputs[offset + j] = new_commitments[j].value; + for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { + calldata_hash_inputs[offset + j] = new_note_hashes[j].value; } - offset += MAX_NEW_COMMITMENTS_PER_TX ; + offset += MAX_NEW_NOTE_HASHES_PER_TX ; for j in 0..MAX_NEW_NULLIFIERS_PER_TX { calldata_hash_inputs[offset + j] = new_nullifiers[j].value; @@ -493,7 +493,7 @@ fn validate_public_data_reads( #[test] fn consistent_not_hash_subtree_width() { assert_eq( - MAX_NEW_COMMITMENTS_PER_TX, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT), "note hash subtree width is incorrect" + MAX_NEW_NOTE_HASHES_PER_TX, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT), "note hash subtree width is incorrect" ); } @@ -501,7 +501,7 @@ global CALLDATA_HASH_INPUT_SIZE = 201; #[test] fn consistent_calldata_hash_input_size() { - let expected_size = MAX_NEW_COMMITMENTS_PER_TX + let expected_size = MAX_NEW_NOTE_HASHES_PER_TX + MAX_NEW_NULLIFIERS_PER_TX + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + MAX_NEW_L2_TO_L1_MSGS_PER_TX @@ -574,7 +574,7 @@ mod tests { constants::{ CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_TREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, ARCHIVE_HEIGHT, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NOTE_HASH_TREE_HEIGHT, NOTE_HASH_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, @@ -697,7 +697,7 @@ mod tests { struct BaseRollupInputsBuilder { kernel_data: PreviousKernelDataBuilder, - pre_existing_notes: [Field; MAX_NEW_COMMITMENTS_PER_TX], + pre_existing_notes: [Field; MAX_NEW_NOTE_HASHES_PER_TX], pre_existing_nullifiers: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], pre_existing_contracts: [Field; 2], pre_existing_public_data: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], @@ -1018,17 +1018,17 @@ mod tests { } #[test] - unconstrained fn new_commitments_tree() { + unconstrained fn new_note_hashes_tree() { let mut builder = BaseRollupInputsBuilder::new(); - let new_commitments = [27, 28, 29, 30, 31, 32]; - let mut new_commitments_vec = builder.kernel_data.end.new_commitments; - for i in 0..new_commitments.len() { - new_commitments_vec.push(SideEffect { value: new_commitments[i], counter: 0 }); + let new_note_hashes = [27, 28, 29, 30, 31, 32]; + let mut new_note_hashes_vec = builder.kernel_data.end.new_note_hashes; + for i in 0..new_note_hashes.len() { + new_note_hashes_vec.push(SideEffect { value: new_note_hashes[i], counter: 0 }); } - builder.kernel_data.end.new_commitments = new_commitments_vec; + builder.kernel_data.end.new_note_hashes = new_note_hashes_vec; let mut expected_commitments_tree = NonEmptyMerkleTree::new( - [0; MAX_NEW_COMMITMENTS_PER_TX * 2], + [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT - 1], [0; NOTE_HASH_SUBTREE_HEIGHT + 1] @@ -1037,19 +1037,19 @@ mod tests { let outputs = builder.execute(); let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), - next_available_leaf_index: MAX_NEW_COMMITMENTS_PER_TX as u32 + next_available_leaf_index: MAX_NEW_NOTE_HASHES_PER_TX as u32 }; assert(outputs.start.note_hash_tree.eq(expected_start_note_hash_tree_snapshot)); - for i in 0..new_commitments.len() { + for i in 0..new_note_hashes.len() { expected_commitments_tree.update_leaf( - (i as u64) + (MAX_NEW_COMMITMENTS_PER_TX as u64), - new_commitments[i] + (i as u64) + (MAX_NEW_NOTE_HASHES_PER_TX as u64), + new_note_hashes[i] ); } let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), - next_available_leaf_index: (MAX_NEW_COMMITMENTS_PER_TX * 2) as u32 + next_available_leaf_index: (MAX_NEW_NOTE_HASHES_PER_TX * 2) as u32 }; assert(outputs.end.note_hash_tree.eq(expected_end_note_hash_tree_snapshot)); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr index 372a3f77eb6..fea3f3bde43 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr @@ -10,13 +10,13 @@ use crate::{ } }; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; struct AccumulatedNonRevertibleDataBuilder { - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, public_call_stack: BoundedVec, public_data_update_requests: BoundedVec, @@ -26,14 +26,14 @@ struct AccumulatedNonRevertibleDataBuilder { impl AccumulatedNonRevertibleDataBuilder { pub fn to_private(self) -> PrivateAccumulatedNonRevertibleData { PrivateAccumulatedNonRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack: self.public_call_stack.storage } } pub fn to_public(self) -> PublicAccumulatedNonRevertibleData { PublicAccumulatedNonRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, public_call_stack: self.public_call_stack.storage, public_data_update_requests: self.public_data_update_requests.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr index 8ee73738459..656c8e259c4 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr @@ -13,7 +13,7 @@ use crate::{ use crate::constants::{ MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, - NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; @@ -22,7 +22,7 @@ struct AccumulatedRevertibleDataBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack: BoundedVec, @@ -46,7 +46,7 @@ struct AccumulatedRevertibleDataBuilder { impl AccumulatedRevertibleDataBuilder { pub fn to_private(self) -> PrivateAccumulatedRevertibleData { PrivateAccumulatedRevertibleData { - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, public_call_stack: self.public_call_stack.storage, @@ -62,7 +62,7 @@ impl AccumulatedRevertibleDataBuilder { pub fn to_public(self) -> PublicAccumulatedRevertibleData { PublicAccumulatedRevertibleData { read_requests: self.read_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index 330e003ceb9..0fcd4d9ad58 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -11,12 +11,12 @@ use crate::{ } }; use crate::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, + MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -31,7 +31,7 @@ struct CombinedAccumulatedData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], @@ -66,7 +66,7 @@ impl CombinedAccumulatedData { CombinedAccumulatedData { read_requests: revertible.read_requests, nullifier_key_validation_requests: revertible.nullifier_key_validation_requests, - new_commitments: array_concat(non_revertible.new_commitments, revertible.new_commitments), + new_note_hashes: array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes), new_nullifiers: array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers), private_call_stack: revertible.private_call_stack, public_call_stack: array_concat( @@ -154,8 +154,8 @@ mod tests { } ]; - builder.new_commitments.extend_from_array(non_revertible_commitments); - builder.new_commitments.extend_from_array(revertible_commitments); + builder.new_note_hashes.extend_from_array(non_revertible_commitments); + builder.new_note_hashes.extend_from_array(revertible_commitments); builder.new_nullifiers.extend_from_array(non_revertible_nullifiers); builder.new_nullifiers.extend_from_array(revertible_nullifiers); @@ -165,11 +165,11 @@ mod tests { let (non_revertible, revertible) = builder.split(7); - assert(array_eq(non_revertible.new_commitments, non_revertible_commitments)); + assert(array_eq(non_revertible.new_note_hashes, non_revertible_commitments)); assert(array_eq(non_revertible.new_nullifiers, non_revertible_nullifiers)); assert(array_eq(non_revertible.public_call_stack, non_revertible_public_stack)); - assert(array_eq(revertible.new_commitments, revertible_commitments)); + assert(array_eq(revertible.new_note_hashes, revertible_commitments)); assert(array_eq(revertible.new_nullifiers, revertible_nullifiers)); assert(array_eq(revertible.public_call_stack, revertible_public_call_stack)); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr index 69fc1ccffba..39595d5a945 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr @@ -16,12 +16,12 @@ use crate::{ } }; use crate::constants::{ - MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, + MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -36,7 +36,7 @@ struct CombinedAccumulatedDataBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack: BoundedVec, @@ -66,7 +66,7 @@ impl CombinedAccumulatedDataBuilder { CombinedAccumulatedDataBuilder { read_requests: array_to_bounded_vec(revertible.read_requests), nullifier_key_validation_requests: array_to_bounded_vec(revertible.nullifier_key_validation_requests), - new_commitments: array_to_bounded_vec(array_concat(non_revertible.new_commitments, revertible.new_commitments)), + new_note_hashes: array_to_bounded_vec(array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes)), new_nullifiers: array_to_bounded_vec(array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers)), private_call_stack: array_to_bounded_vec(revertible.private_call_stack), public_call_stack: array_to_bounded_vec( @@ -100,7 +100,7 @@ impl CombinedAccumulatedDataBuilder { CombinedAccumulatedData { read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack: self.private_call_stack.storage, public_call_stack: self.public_call_stack.storage, @@ -117,7 +117,7 @@ impl CombinedAccumulatedDataBuilder { pub fn to_private_accumulated_revertible_data(self) -> PrivateAccumulatedRevertibleData { PrivateAccumulatedRevertibleData { - new_commitments: array_cp(self.new_commitments.storage), + new_note_hashes: array_cp(self.new_note_hashes.storage), new_nullifiers: array_cp(self.new_nullifiers.storage), private_call_stack: self.private_call_stack.storage, public_call_stack: array_cp(self.public_call_stack.storage), @@ -134,7 +134,7 @@ impl CombinedAccumulatedDataBuilder { PublicAccumulatedRevertibleData { read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: array_cp(self.new_commitments.storage), + new_note_hashes: array_cp(self.new_note_hashes.storage), new_nullifiers: array_cp(self.new_nullifiers.storage), private_call_stack: self.private_call_stack.storage, public_call_stack: array_cp(self.public_call_stack.storage), @@ -156,15 +156,15 @@ impl CombinedAccumulatedDataBuilder { let mut non_revertible_builder: AccumulatedNonRevertibleDataBuilder = unsafe::zeroed(); let mut revertible_builder: AccumulatedRevertibleDataBuilder = unsafe::zeroed(); - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { - let commitment = self.new_commitments.storage[i]; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + let commitment = self.new_note_hashes.storage[i]; // TODO(fees) we shouldn't need to check is_empty here, - // but we do because new_commitments is bounded to MAX_REVERTIBLE_COMMITMENTS_PER_TX + // but we do because new_note_hashes is bounded to MAX_REVERTIBLE_NOTE_HASHES_PER_TX if !is_empty(commitment) { if commitment.counter < min_revertible_side_effect_counter { - non_revertible_builder.new_commitments.push(commitment); + non_revertible_builder.new_note_hashes.push(commitment); } else { - revertible_builder.new_commitments.push(commitment); + revertible_builder.new_note_hashes.push(commitment); } } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr index 8b61a1030f2..017df083bb3 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr @@ -1,11 +1,11 @@ use crate::{abis::{call_request::CallRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX }; struct PrivateAccumulatedNonRevertibleData { - new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr index 739121715fb..16d6028d74f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr @@ -5,13 +5,13 @@ use crate::{ } }; use crate::constants::{ - MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_FIELDS_PER_SHA256, MAX_NEW_CONTRACTS_PER_TX }; struct PrivateAccumulatedRevertibleData { - new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr index bc0f8c5b98c..4df61024f02 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr @@ -6,7 +6,7 @@ use crate::{ } }; use crate::constants::{ - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; @@ -17,7 +17,7 @@ use crate::traits::is_empty; use crate::utils::arrays::{array_cp, array_concat, array_to_bounded_vec}; struct PublicAccumulatedNonRevertibleData { - new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], public_data_update_requests: [PublicDataUpdateRequest; MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr index 44b803e38b5..e1c2fb8440a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr @@ -8,7 +8,7 @@ use crate::{ }; use crate::constants::{ MAX_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_FIELDS_PER_SHA256, MAX_NEW_CONTRACTS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX @@ -18,7 +18,7 @@ struct PublicAccumulatedRevertibleData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], - new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_PER_TX], + new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr index 38d6777a31b..68781ba8e8e 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr @@ -45,9 +45,9 @@ struct ArchiveRootMembershipWitness{ struct ReadRequestMembershipWitness { leaf_index: Field, sibling_path: [Field; NOTE_HASH_TREE_HEIGHT], - // whether or not the read request corresponds to a pending commitment + // whether or not the read request corresponds to a pending note hash // In case we change the default to true, we have to adapt is_empty() method // hint to point kernel to the commitment this rr corresponds to is_transient: bool, - hint_to_commitment: Field, + hint_to_note_hash: Field, } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 064b4d1977e..afff569ec71 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -5,7 +5,7 @@ use crate::{ }, constants::{ MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS @@ -26,7 +26,7 @@ struct PrivateCircuitPublicInputs { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_CALL], nullifier_key_validation_requests: [NullifierKeyValidationRequest; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_CALL], private_call_stack_hashes: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], @@ -60,7 +60,7 @@ impl Eq for PrivateCircuitPublicInputs { (self.return_values == other.return_values) & (self.read_requests == other.read_requests) & (self.nullifier_key_validation_requests == other.nullifier_key_validation_requests) & - (self.new_commitments == other.new_commitments) & + (self.new_note_hashes == other.new_note_hashes) & (self.new_nullifiers == other.new_nullifiers) & (self.private_call_stack_hashes == other.private_call_stack_hashes) & (self.public_call_stack_hashes == other.public_call_stack_hashes) & @@ -92,8 +92,8 @@ impl Serialize for PrivateCircuitPublicInp for i in 0..MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL{ fields.extend_from_array(self.nullifier_key_validation_requests[i].serialize()); } - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL{ - fields.extend_from_array(self.new_commitments[i].serialize()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL{ + fields.extend_from_array(self.new_note_hashes[i].serialize()); } for i in 0..MAX_NEW_NULLIFIERS_PER_CALL{ fields.extend_from_array(self.new_nullifiers[i].serialize()); @@ -130,7 +130,7 @@ impl Deserialize for PrivateCircuitPublicI min_revertible_side_effect_counter: reader.read() as u32, read_requests: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]), nullifier_key_validation_requests: reader.read_struct_array(NullifierKeyValidationRequest::deserialize, [NullifierKeyValidationRequest::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL]), - new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), + new_note_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]), new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialize, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr index 1fe1f24f3b6..6ea95afbd7e 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_call_stack_item.nr @@ -61,7 +61,7 @@ mod tests { let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, is_private: false, is_constructor: false }; let mut public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed(); - public_inputs.new_commitments[0] = SideEffect{ + public_inputs.new_note_hashes[0] = SideEffect{ value: 1, counter: 0, }; @@ -78,7 +78,7 @@ mod tests { let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, is_private: false, is_constructor: false }; let mut public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed(); - public_inputs.new_commitments[0] = SideEffect{ + public_inputs.new_note_hashes[0] = SideEffect{ value: 1, counter: 0, }; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr index 87229aecac6..afbfe068e8b 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr @@ -2,7 +2,7 @@ use crate::{ abis::{call_context::CallContext, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}, address::AztecAddress, constants::{ - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH @@ -23,7 +23,7 @@ struct PublicCircuitPublicInputs{ // todo: add sideeffect ranges for the input to these hashes public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_CALL], + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_CALL], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_CALL], new_l2_to_l1_msgs: [L2ToL1Message; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], @@ -60,8 +60,8 @@ impl Serialize for PublicCircuitPublicInput } fields.extend_from_array(self.public_call_stack_hashes); - for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { - fields.extend_from_array(self.new_commitments[i].serialize()); + for i in 0..MAX_NEW_NOTE_HASHES_PER_CALL { + fields.extend_from_array(self.new_note_hashes[i].serialize()); } for i in 0..MAX_NEW_NULLIFIERS_PER_CALL { fields.extend_from_array(self.new_nullifiers[i].serialize()); @@ -88,7 +88,7 @@ impl Deserialize for PublicCircuitPublicInp contract_storage_update_requests: reader.read_struct_array(StorageUpdateRequest::deserialize, [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL]), contract_storage_reads: reader.read_struct_array(StorageRead::deserialize, [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), - new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), + new_note_hashes: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]), new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialize, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]), new_l2_to_l1_msgs: reader.read_struct_array(L2ToL1Message::deserialize, [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 2a2fab60fb0..be81885d059 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -9,21 +9,21 @@ global RETURN_VALUES_LENGTH: Field = 4; * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as * commitment, or nullifier, e.g.,: * - MAX_NEW_NULLIFIERS_PER_CALL - * - MAX_NEW_COMMITMENTS_PER_TX + * - MAX_NEW_NOTE_HASHES_PER_TX * - * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a + * In the kernel circuits, we accumulate elements such as note hashes and the nullifiers from all functions calls in a * transaction. Therefore, we always must have: * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL * * For instance: - * MAX_NEW_COMMITMENTS_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL + * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL * */ // docs:start:constants // "PER CALL" CONSTANTS -global MAX_NEW_COMMITMENTS_PER_CALL: Field = 16; +global MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16; global MAX_NEW_NULLIFIERS_PER_CALL: Field = 16; global MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4; global MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4; @@ -34,9 +34,9 @@ global MAX_READ_REQUESTS_PER_CALL: Field = 32; global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: Field = 1; // "PER TRANSACTION" CONSTANTS -global MAX_NEW_COMMITMENTS_PER_TX: Field = 64; -global MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX: Field = 8; -global MAX_REVERTIBLE_COMMITMENTS_PER_TX: Field = 56; +global MAX_NEW_NOTE_HASHES_PER_TX: Field = 64; +global MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX: Field = 8; +global MAX_REVERTIBLE_NOTE_HASHES_PER_TX: Field = 56; global MAX_NEW_NULLIFIERS_PER_TX: Field = 64; global MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX: Field = 8; @@ -167,7 +167,7 @@ global TX_CONTEXT_DATA_LENGTH: Field = 11; global TX_REQUEST_LENGTH: Field = 17; global GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674; -global COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; +global NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048; global CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32; @@ -192,10 +192,10 @@ global LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly. */ // Indices with size ≤ 8 -global GENERATOR_INDEX__COMMITMENT = 1; -global GENERATOR_INDEX__COMMITMENT_NONCE = 2; -global GENERATOR_INDEX__UNIQUE_COMMITMENT = 3; -global GENERATOR_INDEX__SILOED_COMMITMENT = 4; +global GENERATOR_INDEX__NOTE_HASH = 1; +global GENERATOR_INDEX__NOTE_HASH_NONCE = 2; +global GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3; +global GENERATOR_INDEX__SILOED_NOTE_HASH = 4; global GENERATOR_INDEX__NULLIFIER = 5; global GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6; global GENERATOR_INDEX__OUTER_NULLIFIER = 7; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr index 76bb40ccbb9..1ba04777e9a 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -10,11 +10,10 @@ use crate::abis::side_effect::{SideEffect}; use crate::utils::uint256::U256; use crate::constants::{ ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT, - NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT, + NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR, GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS, - GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT, - GENERATOR_INDEX__FUNCTION_ARGS + GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH, GENERATOR_INDEX__FUNCTION_ARGS }; use crate::messaging::l2_to_l1_message::L2ToL1Message; @@ -158,13 +157,13 @@ pub fn read_request_root_from_siblings( root_from_sibling_path(read_request, leaf_index, sibling_path) } -pub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field { +pub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field { pedersen_hash( [ address.to_field(), inner_commitment ], - GENERATOR_INDEX__SILOED_COMMITMENT + GENERATOR_INDEX__SILOED_NOTE_HASH ) } @@ -283,42 +282,42 @@ pub fn compute_logs_hash( ) } -pub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field { +pub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field { pedersen_hash( [ first_nullifier, commitment_index ], - GENERATOR_INDEX__COMMITMENT_NONCE + GENERATOR_INDEX__NOTE_HASH_NONCE ) } -pub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field { +pub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field { pedersen_hash( [ nonce, - siloed_commitment + siloed_note_hash ], - GENERATOR_INDEX__UNIQUE_COMMITMENT + GENERATOR_INDEX__UNIQUE_NOTE_HASH ) } -pub fn compute_unique_siloed_commitments( +pub fn compute_unique_siloed_note_hashes( first_nullifier: Field, - siloed_commitments: [SideEffect; N] + siloed_note_hashes: [SideEffect; N] ) -> [SideEffect; N] { - let mut unique_siloed_commitments = [SideEffect::empty(); N]; + let mut unique_siloed_note_hashes = [SideEffect::empty(); N]; for i in 0..N { - let siloed_commitment = siloed_commitments[i]; - if siloed_commitment.value != 0 { - let nonce = compute_commitment_nonce(first_nullifier, i); - unique_siloed_commitments[i] = SideEffect { - value: compute_unique_siloed_commitment(nonce, siloed_commitment.value), - counter: siloed_commitment.counter + let siloed_note_hash = siloed_note_hashes[i]; + if siloed_note_hash.value != 0 { + let nonce = compute_note_hash_nonce(first_nullifier, i); + unique_siloed_note_hashes[i] = SideEffect { + value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value), + counter: siloed_note_hash.counter }; } } - unique_siloed_commitments + unique_siloed_note_hashes } pub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field { diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr index 3b655178474..5c1eacf6658 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/fixtures/read_requests.nr @@ -24,7 +24,7 @@ pub fn generate_read_requests_with_config( leaf_index: i, sibling_path: fixtures::note_hash_tree::SIBLING_PATHS[i], is_transient, - hint_to_commitment: hints_to_commitment[i] + hint_to_note_hash: hints_to_commitment[i] }; read_request_membership_witnesses.push(witness); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr index 7eb785d088e..ccf24bb261f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr @@ -16,7 +16,7 @@ use crate::{ tests::{fixtures, testing_harness::build_tx_context}, transaction::tx_context::TxContext }; use crate::constants::{ - MAX_NEW_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUM_FIELDS_PER_SHA256, VK_TREE_HEIGHT }; @@ -114,18 +114,18 @@ impl PreviousKernelDataBuilder { pub fn add_read_request_for_transient_commitment(&mut self, commitment_index: Field) -> Field { let new_read_request_index = self.end.read_requests.len(); - let commitment = self.end.new_commitments.get(commitment_index); + let commitment = self.end.new_note_hashes.get(commitment_index); let read_request = SideEffect { value: commitment.value, counter: self.next_sideffect_counter() }; self.end.read_requests.push(read_request); new_read_request_index } - pub fn append_new_commitments(&mut self, num_new_commitments: Field) { - let mocked_value_offset = self.end.new_commitments.len() + 1; - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { - if i as u64 < num_new_commitments as u64 { + pub fn append_new_note_hashes(&mut self, num_new_note_hashes: Field) { + let mocked_value_offset = self.end.new_note_hashes.len() + 1; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + if i as u64 < num_new_note_hashes as u64 { // The default value is its index + 1. - self.end.new_commitments.push( + self.end.new_note_hashes.push( SideEffect { value: i + mocked_value_offset, counter: self.next_sideffect_counter() } ); } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr index d001cb9dfb4..27db9171226 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr @@ -12,7 +12,7 @@ use crate::{ }; use crate::constants::{ MAX_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH }; @@ -28,7 +28,7 @@ struct PrivateCircuitPublicInputsBuilder { read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, private_call_stack_hashes: BoundedVec, @@ -109,7 +109,7 @@ impl PrivateCircuitPublicInputsBuilder { min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, private_call_stack_hashes: self.private_call_stack_hashes.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr index 5ad58fd1bae..8e4e7923f1f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr @@ -8,7 +8,7 @@ use crate::{ messaging::l2_to_l1_message::L2ToL1Message, tests::fixtures }; use crate::constants::{ - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, NUM_FIELDS_PER_SHA256, RETURN_VALUES_LENGTH }; @@ -20,7 +20,7 @@ struct PublicCircuitPublicInputsBuilder { contract_storage_update_requests: BoundedVec, contract_storage_reads: BoundedVec, public_call_stack_hashes: BoundedVec, - new_commitments: BoundedVec, + new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, new_l2_to_l1_msgs: BoundedVec, unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], @@ -45,7 +45,7 @@ impl PublicCircuitPublicInputsBuilder { contract_storage_update_requests: self.contract_storage_update_requests.storage, contract_storage_reads: self.contract_storage_reads.storage, public_call_stack_hashes: self.public_call_stack_hashes.storage, - new_commitments: self.new_commitments.storage, + new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, unencrypted_logs_hash: self.unencrypted_logs_hash, diff --git a/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml b/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml index f0a4dc2485d..44813823448 100644 --- a/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml +++ b/noir/test_programs/execution_success/brillig_cow_regression/Prover.toml @@ -3,7 +3,7 @@ encrypted_logs_hash = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", ] -new_commitments = [ +new_note_hashes = [ "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr index 974c17dfbc9..457abde32d5 100644 --- a/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr +++ b/noir/test_programs/execution_success/brillig_cow_regression/src/main.nr @@ -1,6 +1,6 @@ // Tests a performance regression found in aztec-packages with brillig cow optimization -global MAX_NEW_COMMITMENTS_PER_TX: Field = 64; +global MAX_NEW_NOTE_HASHES_PER_TX: Field = 64; global MAX_NEW_NULLIFIERS_PER_TX: Field = 64; global MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2; global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16; @@ -30,7 +30,7 @@ impl NewContractData { } struct DataToHash { - new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_TX], + new_note_hashes: [Field; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_TX], public_data_update_requests: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], @@ -47,61 +47,61 @@ struct U256 { } impl U256 { - pub fn from_bytes32(bytes : [u8;32]) -> U256 { + pub fn from_bytes32(bytes: [u8; 32]) -> U256 { // We use addition rather than a bitwise OR as the bitshifts ensure that none of the bytes overlap each other. let high_0 = ((bytes[0] as u64) << 56) - + ((bytes[1] as u64) << 48) - + ((bytes[2] as u64) << 40) - + ((bytes[3] as u64) << 32) - + ((bytes[4] as u64) << 24) - + ((bytes[5] as u64) << 16) - + ((bytes[6] as u64) << 8) - + (bytes[7] as u64); - + + ((bytes[1] as u64) << 48) + + ((bytes[2] as u64) << 40) + + ((bytes[3] as u64) << 32) + + ((bytes[4] as u64) << 24) + + ((bytes[5] as u64) << 16) + + ((bytes[6] as u64) << 8) + + (bytes[7] as u64); + let high_1 = ((bytes[8] as u64) << 56) - + ((bytes[9] as u64) << 48) - + ((bytes[10] as u64) << 40) - + ((bytes[11] as u64) << 32) - + ((bytes[12] as u64) << 24) - + ((bytes[13] as u64) << 16) - + ((bytes[14] as u64) << 8) - + (bytes[15] as u64); - + + ((bytes[9] as u64) << 48) + + ((bytes[10] as u64) << 40) + + ((bytes[11] as u64) << 32) + + ((bytes[12] as u64) << 24) + + ((bytes[13] as u64) << 16) + + ((bytes[14] as u64) << 8) + + (bytes[15] as u64); + let low_0 = ((bytes[16] as u64) << 56) - + ((bytes[17] as u64) << 48) - + ((bytes[18] as u64) << 40) - + ((bytes[19] as u64) << 32) - + ((bytes[20] as u64) << 24) - + ((bytes[21] as u64) << 16) - + ((bytes[22] as u64) << 8) - + (bytes[23] as u64); - + + ((bytes[17] as u64) << 48) + + ((bytes[18] as u64) << 40) + + ((bytes[19] as u64) << 32) + + ((bytes[20] as u64) << 24) + + ((bytes[21] as u64) << 16) + + ((bytes[22] as u64) << 8) + + (bytes[23] as u64); + let low_1 = ((bytes[24] as u64) << 56) - + ((bytes[25] as u64) << 48) - + ((bytes[26] as u64) << 40) - + ((bytes[27] as u64) << 32) - + ((bytes[28] as u64) << 24) - + ((bytes[29] as u64) << 16) - + ((bytes[30] as u64) << 8) - + (bytes[31] as u64); - - U256{inner : [high_0, high_1, low_0, low_1]} + + ((bytes[25] as u64) << 48) + + ((bytes[26] as u64) << 40) + + ((bytes[27] as u64) << 32) + + ((bytes[28] as u64) << 24) + + ((bytes[29] as u64) << 16) + + ((bytes[30] as u64) << 8) + + (bytes[31] as u64); + + U256 { inner: [high_0, high_1, low_0, low_1] } } - pub fn to_u128_limbs(self) -> [Field;2] { + pub fn to_u128_limbs(self) -> [Field; 2] { let two_pow_64 = 2.pow_32(64); let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field; let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; - - [high,low] + + [high, low] } } unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA256] { let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - let new_commitments = kernel_data.new_commitments; + let new_note_hashes = kernel_data.new_note_hashes; let new_nullifiers = kernel_data.new_nullifiers; let public_data_update_requests = kernel_data.public_data_update_requests; let newL2ToL1msgs = kernel_data.new_l2_to_l1_msgs; @@ -110,10 +110,10 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA let mut offset = 0; - for j in 0..MAX_NEW_COMMITMENTS_PER_TX { - calldata_hash_inputs[offset + j] = new_commitments[j]; + for j in 0..MAX_NEW_NOTE_HASHES_PER_TX { + calldata_hash_inputs[offset + j] = new_note_hashes[j]; } - offset += MAX_NEW_COMMITMENTS_PER_TX ; + offset += MAX_NEW_NOTE_HASHES_PER_TX ; for j in 0..MAX_NEW_NULLIFIERS_PER_TX { calldata_hash_inputs[offset + j] = new_nullifiers[j]; diff --git a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts index 46e31cac924..5562b919cd4 100644 --- a/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts +++ b/yarn-project/archiver/src/archiver/archiver_store_test_suite.ts @@ -369,8 +369,6 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch await expect(store.getContractData(block.body.txEffects[0].contractData[0].contractAddress)).resolves.toEqual( block.body.txEffects[0].contractData[0], ); - - expect(block.body.txEffects[0].contractData[1]).toBe(undefined); }); it('returns undefined if contract data is not found', async () => { diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index e40b65b3a00..1b544f10b4f 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -71,7 +71,7 @@ export class SentTx { const tx = (await this.pxe.getTx(txHash))!; const visibleNotes = await this.pxe.getNotes({ txHash }); receipt.debugInfo = { - newCommitments: tx.newCommitments, + newNoteHashes: tx.newNoteHashes, newNullifiers: tx.newNullifiers, newPublicDataWrites: tx.newPublicDataWrites, newL2ToL1Msgs: tx.newL2ToL1Msgs, diff --git a/yarn-project/circuit-types/src/body.ts b/yarn-project/circuit-types/src/body.ts index b82cf11e7f6..1a61dc5fa9b 100644 --- a/yarn-project/circuit-types/src/body.ts +++ b/yarn-project/circuit-types/src/body.ts @@ -1,14 +1,14 @@ import { ContractData, L2BlockL2Logs, PublicDataWrite, TxEffect } from '@aztec/circuit-types'; import { - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, } from '@aztec/circuits.js'; import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; export class Body { constructor(public l1ToL2Messages: Fr[], public txEffects: TxEffect[]) {} @@ -81,19 +81,35 @@ export class Body { const numberOfTxsIncludingEmpty = newNullifiers.length / MAX_NEW_NULLIFIERS_PER_TX; for (let i = 0; i < numberOfTxsIncludingEmpty; i += 1) { + // TODO(#4720): this should use TxEffect.fromBuffer txEffects.push( new TxEffect( - newNoteHashes.slice(i * MAX_NEW_COMMITMENTS_PER_TX, (i + 1) * MAX_NEW_COMMITMENTS_PER_TX), - newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX), - newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX), + newNoteHashes.slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + newNullifiers.slice(i * MAX_NEW_NULLIFIERS_PER_TX, (i + 1) * MAX_NEW_NULLIFIERS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, + newL2ToL1Msgs.slice(i * MAX_NEW_L2_TO_L1_MSGS_PER_TX, (i + 1) * MAX_NEW_L2_TO_L1_MSGS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_L2_TO_L1_MSGS_PER_TX + >, newPublicDataWrites.slice( i * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, (i + 1) * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - ), - newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX), - newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX), - newEncryptedLogs!.txLogs[i], - newUnencryptedLogs!.txLogs[i], + ) as Tuple, + newContracts.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_CONTRACTS_PER_TX + >, + newContractData.slice(i * MAX_NEW_CONTRACTS_PER_TX, (i + 1) * MAX_NEW_CONTRACTS_PER_TX) as Tuple< + ContractData, + typeof MAX_NEW_CONTRACTS_PER_TX + >, + newEncryptedLogs.txLogs[i], + newUnencryptedLogs.txLogs[i], ), ); } diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts index 93e115f9e28..c9efbb09ab8 100644 --- a/yarn-project/circuit-types/src/l2_block.ts +++ b/yarn-project/circuit-types/src/l2_block.ts @@ -2,15 +2,16 @@ import { Body, ContractData, L2Tx, LogType, PublicDataWrite, TxEffect, TxHash, T import { AppendOnlyTreeSnapshot, Header, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, STRING_ENCODING, } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot, makeHeader } from '@aztec/circuits.js/factories'; +import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { sha256 } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; @@ -127,12 +128,12 @@ export class L2Block { const txEffects = [...new Array(txsPerBlock)].map( _ => new TxEffect( - times(MAX_NEW_COMMITMENTS_PER_TX, Fr.random), - times(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), - times(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.random), - times(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.random), - times(MAX_NEW_CONTRACTS_PER_TX, Fr.random), - times(MAX_NEW_CONTRACTS_PER_TX, ContractData.random), + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, Fr.random), + makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), + makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.random), + makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataWrite.random), + makeTuple(MAX_NEW_CONTRACTS_PER_TX, Fr.random), + makeTuple(MAX_NEW_CONTRACTS_PER_TX, ContractData.random), TxL2Logs.random(numPrivateCallsPerTx, numEncryptedLogsPerCall, LogType.ENCRYPTED), TxL2Logs.random(numPublicCallsPerTx, numUnencryptedLogsPerCall, LogType.UNENCRYPTED), ), diff --git a/yarn-project/circuit-types/src/l2_tx.ts b/yarn-project/circuit-types/src/l2_tx.ts index 593f85d7b81..4c5d9514cd3 100644 --- a/yarn-project/circuit-types/src/l2_tx.ts +++ b/yarn-project/circuit-types/src/l2_tx.ts @@ -1,7 +1,7 @@ import { - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, Vector, @@ -31,9 +31,9 @@ export class L2Tx { constructor( /** - * New commitments created by the transaction. + * New note hashes created by the transaction. */ - public newCommitments: Fr[], + public newNoteHashes: Fr[], /** * New nullifiers created by the transaction. */ @@ -100,7 +100,7 @@ export class L2Tx { */ toBuffer() { return Buffer.concat([ - new Vector(this.newCommitments).toBuffer(), + new Vector(this.newNoteHashes).toBuffer(), new Vector(this.newNullifiers).toBuffer(), new Vector(this.newPublicDataWrites).toBuffer(), new Vector(this.newL2ToL1Msgs).toBuffer(), @@ -121,7 +121,7 @@ export class L2Tx { static random() { const rand = (min: number, max: number) => Math.floor(Math.random() * max) + min; return new L2Tx( - times(rand(0, MAX_NEW_COMMITMENTS_PER_TX), Fr.random), + times(rand(0, MAX_NEW_NOTE_HASHES_PER_TX), Fr.random), times(rand(1, MAX_NEW_NULLIFIERS_PER_TX), Fr.random), times(rand(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX), PublicDataWrite.random), times(rand(0, MAX_NEW_L2_TO_L1_MSGS_PER_TX), Fr.random), diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 23a2d232209..e36bf56e085 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -176,8 +176,8 @@ export class Tx { newContractDataSize: this.newContracts.map(c => c.toBuffer().length).reduce((a, b) => a + b, 0), newCommitmentCount: - arrayNonEmptyLength(this.data!.endNonRevertibleData.newCommitments, SideEffect.isEmpty) + - arrayNonEmptyLength(this.data!.end.newCommitments, SideEffect.isEmpty), + arrayNonEmptyLength(this.data!.endNonRevertibleData.newNoteHashes, SideEffect.isEmpty) + + arrayNonEmptyLength(this.data!.end.newNoteHashes, SideEffect.isEmpty), newNullifierCount: arrayNonEmptyLength(this.data!.endNonRevertibleData.newNullifiers, SideEffectLinkedToNoteHash.isEmpty) + diff --git a/yarn-project/circuit-types/src/tx/tx_receipt.ts b/yarn-project/circuit-types/src/tx/tx_receipt.ts index 00c8334f1d2..0bcd900acc7 100644 --- a/yarn-project/circuit-types/src/tx/tx_receipt.ts +++ b/yarn-project/circuit-types/src/tx/tx_receipt.ts @@ -88,9 +88,9 @@ export class TxReceipt { */ interface DebugInfo { /** - * New commitments created by the transaction. + * New note hashes created by the transaction. */ - newCommitments: Fr[]; + newNoteHashes: Fr[]; /** * New nullifiers created by the transaction. */ diff --git a/yarn-project/circuit-types/src/tx_effect.ts b/yarn-project/circuit-types/src/tx_effect.ts index 89a18aa25a8..77b49552673 100644 --- a/yarn-project/circuit-types/src/tx_effect.ts +++ b/yarn-project/circuit-types/src/tx_effect.ts @@ -1,43 +1,47 @@ import { ContractData, PublicDataWrite, TxL2Logs } from '@aztec/circuit-types'; -import { Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { + Fr, + MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '@aztec/circuits.js'; import { sha256 } from '@aztec/foundation/crypto'; +import { Tuple } from '@aztec/foundation/serialize'; export class TxEffect { constructor( /** - * The commitments to be inserted into the note hash tree. + * The note hashes to be inserted into the note hash tree. */ - public newNoteHashes: Fr[], + public newNoteHashes: Tuple, /** * The nullifiers to be inserted into the nullifier tree. */ - public newNullifiers: Fr[], + public newNullifiers: Tuple, /** * The L2 to L1 messages to be inserted into the messagebox on L1. */ - public newL2ToL1Msgs: Fr[], + public newL2ToL1Msgs: Tuple, /** * The public data writes to be inserted into the public data tree. */ - public newPublicDataWrites: PublicDataWrite[], + public newPublicDataWrites: Tuple, /** * The leaves of the new contract data that will be inserted into the contracts tree. */ - public contractLeaves: Fr[], + public contractLeaves: Tuple, /** - * The the contracts data of the new contracts. + * The contract data of the new contracts. */ - public contractData: ContractData[], + public contractData: Tuple, /** * The logs of the txEffect */ public encryptedLogs: TxL2Logs, public unencryptedLogs: TxL2Logs, - ) { - if (newNoteHashes.length % MAX_NEW_COMMITMENTS_PER_TX !== 0) { - throw new Error(`The number of new commitments must be a multiple of ${MAX_NEW_COMMITMENTS_PER_TX}.`); - } - } + ) {} hash() { const noteHashesBuffer = Buffer.concat(this.newNoteHashes.map(x => x.toBuffer())); @@ -47,11 +51,8 @@ export class TxEffect { const encryptedLogsHashKernel0 = this.encryptedLogs.hash(); const unencryptedLogsHashKernel0 = this.unencryptedLogs.hash(); - if ( - (this.contractLeaves.length > 1 && !this.contractLeaves[1].isZero()) || - (this.contractData.length > 1 && !this.contractData[1].isEmpty()) - ) { - throw new Error('We only support max one new contract per tx'); + if (MAX_NEW_CONTRACTS_PER_TX !== 1) { + throw new Error('Only one contract per transaction is supported for now.'); } const inputValue = Buffer.concat([ diff --git a/yarn-project/circuits.js/fixtures/Benchmarking.test.json b/yarn-project/circuits.js/fixtures/Benchmarking.test.json index dc23d9e8c0d..6bd40d7241c 100644 --- a/yarn-project/circuits.js/fixtures/Benchmarking.test.json +++ b/yarn-project/circuits.js/fixtures/Benchmarking.test.json @@ -428,7 +428,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -1099,7 +1099,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -1671,7 +1671,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -2384,7 +2384,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -3098,7 +3098,7 @@ } }, { - "name": "new_commitments", + "name": "new_note_hashes", "type": { "kind": "array", "length": 16, @@ -3388,7 +3388,7 @@ "path": "/home/santiago/Projects/aztec3-packages/noir-contracts/contracts/benchmarking_contract/src/main.nr" }, "40": { - "source": "use crate::{\n abi::{\n PrivateContextInputs,\n PublicContextInputs,\n },\n key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n get_block_header::get_block_header,\n nullifier_key::get_nullifier_key_pair,\n },\n types::vec::BoundedVec,\n utils::Reader,\n};\nuse dep::protocol_types::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_data::FunctionData,\n function_selector::FunctionSelector,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n call_stack_item::PrivateCallStackItem,\n call_stack_item::PublicCallStackItem,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash},\n },\n address::{\n AztecAddress,\n EthAddress,\n },\n constants::{\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n },\n contrakt::{\n deployment_data::ContractDeploymentData,\n storage_read::StorageRead,\n storage_update_request::StorageUpdateRequest,\n },\n hash::hash_args,\n grumpkin_point::GrumpkinPoint,\n};\nuse dep::std::{\n grumpkin_scalar::GrumpkinScalar,\n option::Option,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_header: BlockHeader,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(SideEffect::empty()),\n\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n block_header: inputs.block_header,\n\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_block_header(self, block_number: u32) -> BlockHeader {\n get_block_header(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.block_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect {\n value: read_request,\n counter: self.side_effect_counter,\n };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter,\n };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: nullified_commitment,\n counter: self.side_effect_counter,\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinScalar {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key, key_pair.secret_key);\n // TODO: Add request to context.\n // self.context.push_nullifier_key_validation_request(public_key, secret_key);\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address,\n function_selector, \n args_hash,\n self.side_effect_counter,\n );\n let mut reader = Reader::new(fields);\n\n let item = PrivateCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1\n read_requests: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]),\n new_commitments: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]),\n new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialise, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]),\n private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]),\n public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]),\n new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]),\n end_side_effect_counter: reader.read() as u32,\n encrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n encrypted_log_preimages_length: reader.read(),\n unencrypted_log_preimages_length: reader.read(),\n block_header: BlockHeader{\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : reader.read(),\n nullifier_tree_root : reader.read(),\n contract_tree_root : reader.read(),\n l1_to_l2_message_tree_root : reader.read(),\n archive_root : reader.read(),\n public_data_tree_root: reader.read(),\n global_variables_hash: reader.read(),\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: GrumpkinPoint {\n x: reader.read(), \n y: reader.read()\n },\n constructor_vk_hash : reader.read(),\n function_tree_root : reader.read(),\n contract_address_salt : reader.read(),\n portal_contract_address : EthAddress::from_field(reader.read()),\n },\n chain_id: reader.read(),\n version: reader.read(),\n },\n is_execution_request: reader.read() as bool,\n };\n\n reader.finish();\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n \n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_header: BlockHeader::empty(),\n prover_address: AztecAddress::zero(),\n },\n is_execution_request: true,\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n\nstruct PublicContext {\n inputs: PublicContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_reads: BoundedVec,\n public_call_stack_hashes: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_header: BlockHeader,\n prover_address: AztecAddress,\n}\n\nimpl PublicContext {\n pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = StorageRead::empty();\n let empty_storage_update = StorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_reads: BoundedVec::new(empty_storage_read),\n public_call_stack_hashes: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_header: inputs.block_header,\n prover_address: AztecAddress::zero(),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_reads: self.contract_storage_reads.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.inputs.block_header,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter\n };\n self.new_commitments.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: 0, // cannot nullify pending notes in public context\n counter: self.side_effect_counter\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}\n", + "source": "use crate::{\n abi::{\n PrivateContextInputs,\n PublicContextInputs,\n },\n key::nullifier_key::validate_nullifier_key_against_address,\n messaging::process_l1_to_l2_message,\n oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n get_block_header::get_block_header,\n nullifier_key::get_nullifier_key_pair,\n },\n types::vec::BoundedVec,\n utils::Reader,\n};\nuse dep::protocol_types::{\n abis::{\n block_header::BlockHeader,\n call_context::CallContext,\n function_data::FunctionData,\n function_selector::FunctionSelector,\n private_circuit_public_inputs::PrivateCircuitPublicInputs,\n public_circuit_public_inputs::PublicCircuitPublicInputs,\n call_stack_item::PrivateCallStackItem,\n call_stack_item::PublicCallStackItem,\n side_effect::{SideEffect, SideEffectLinkedToNoteHash},\n },\n address::{\n AztecAddress,\n EthAddress,\n },\n constants::{\n MAX_NEW_NOTE_HASHES_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n },\n contrakt::{\n deployment_data::ContractDeploymentData,\n storage_read::StorageRead,\n storage_update_request::StorageUpdateRequest,\n },\n hash::hash_args,\n grumpkin_point::GrumpkinPoint,\n};\nuse dep::std::{\n grumpkin_scalar::GrumpkinScalar,\n option::Option,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: PrivateContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n private_call_stack_hashes : BoundedVec,\n public_call_stack_hashes : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_header: BlockHeader,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(SideEffect::empty()),\n\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n block_header: inputs.block_header,\n\n private_call_stack_hashes: BoundedVec::new(0),\n public_call_stack_hashes: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn get_block_header(self, block_number: u32) -> BlockHeader {\n get_block_header(block_number, self)\n }\n\n pub fn finish(self) -> PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n private_call_stack_hashes: self.private_call_stack_hashes.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n end_side_effect_counter: self.side_effect_counter,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.block_header,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n let side_effect = SideEffect {\n value: read_request,\n counter: self.side_effect_counter,\n };\n self.read_requests.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter,\n };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: nullified_commitment,\n counter: self.side_effect_counter,\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn request_nullifier_secret_key(&mut self, account: AztecAddress) -> GrumpkinScalar {\n let key_pair = get_nullifier_key_pair(account);\n validate_nullifier_key_against_address(account, key_pair.public_key, key_pair.secret_key);\n // TODO: Add request to context.\n // self.context.push_nullifier_key_validation_request(public_key, secret_key);\n key_pair.secret_key\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address,\n function_selector, \n args_hash,\n self.side_effect_counter,\n );\n let mut reader = Reader::new(fields);\n\n let item = PrivateCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1\n read_requests: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]),\n new_note_hashes: reader.read_struct_array(SideEffect::deserialise, [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL]),\n new_nullifiers: reader.read_struct_array(SideEffectLinkedToNoteHash::deserialise, [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL]),\n private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]),\n public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]),\n new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]),\n end_side_effect_counter: reader.read() as u32,\n encrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]),\n encrypted_log_preimages_length: reader.read(),\n unencrypted_log_preimages_length: reader.read(),\n block_header: BlockHeader{\n // Must match order in `private_circuit_public_inputs.hpp`\n note_hash_tree_root : reader.read(),\n nullifier_tree_root : reader.read(),\n contract_tree_root : reader.read(),\n l1_to_l2_message_tree_root : reader.read(),\n archive_root : reader.read(),\n public_data_tree_root: reader.read(),\n global_variables_hash: reader.read(),\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: GrumpkinPoint {\n x: reader.read(), \n y: reader.read()\n },\n constructor_vk_hash : reader.read(),\n function_tree_root : reader.read(),\n contract_address_salt : reader.read(),\n portal_contract_address : EthAddress::from_field(reader.read()),\n },\n chain_id: reader.read(),\n version: reader.read(),\n },\n is_execution_request: reader.read() as bool,\n };\n\n reader.finish();\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;\n \n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.private_call_stack_hashes.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash,\n self.side_effect_counter\n );\n\n let mut reader = Reader::new(fields);\n\n let item = PublicCallStackItem {\n contract_address: AztecAddress::from_field(reader.read()),\n function_data: FunctionData {\n selector: FunctionSelector::from_field(reader.read()),\n is_internal: reader.read() as bool,\n is_private: reader.read() as bool,\n is_constructor: reader.read() as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : AztecAddress::from_field(reader.read()),\n storage_contract_address : AztecAddress::from_field(reader.read()),\n portal_contract_address : EthAddress::from_field(reader.read()),\n function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1]\n is_delegate_call : reader.read() as bool,\n is_static_call : reader.read() as bool,\n is_contract_deployment: reader.read() as bool,\n start_side_effect_counter: reader.read() as u32,\n },\n args_hash: reader.read(),\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_note_hashes: [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],\n new_nullifiers: [SideEffectLinkedToNoteHash::empty(); MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_header: BlockHeader::empty(),\n prover_address: AztecAddress::zero(),\n },\n is_execution_request: true,\n };\n reader.finish();\n\n assert(contract_address.eq(item.contract_address));\n assert(function_selector.eq(item.function_data.selector));\n\n assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);\n // We increment the sideffect counter by one, to account for the call itself being a side effect.\n self.side_effect_counter = self.side_effect_counter + 1;\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address));\n assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address));\n\n self.public_call_stack_hashes.push(item.hash());\n }\n}\n\nstruct PublicContext {\n inputs: PublicContextInputs,\n side_effect_counter: u32,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_reads: BoundedVec,\n public_call_stack_hashes: BoundedVec,\n\n new_note_hashes: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_header: BlockHeader,\n prover_address: AztecAddress,\n}\n\nimpl PublicContext {\n pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = StorageRead::empty();\n let empty_storage_update = StorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n side_effect_counter: inputs.call_context.start_side_effect_counter,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_reads: BoundedVec::new(empty_storage_read),\n public_call_stack_hashes: BoundedVec::new(0),\n\n new_note_hashes: BoundedVec::new(SideEffect::empty()),\n new_nullifiers: BoundedVec::new(SideEffectLinkedToNoteHash::empty()),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_header: inputs.block_header,\n prover_address: AztecAddress::zero(),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> AztecAddress {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> AztecAddress {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> EthAddress {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> FunctionSelector {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_reads: self.contract_storage_reads.storage,\n return_values: self.return_values.storage,\n new_note_hashes: self.new_note_hashes.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack_hashes: self.public_call_stack_hashes.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_header: self.inputs.block_header,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n let side_effect = SideEffect {\n value: note_hash,\n counter: self.side_effect_counter\n };\n self.new_note_hashes.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n let side_effect = SideEffectLinkedToNoteHash {\n value: nullifier,\n note_hash: 0, // cannot nullify pending notes in public context\n counter: self.side_effect_counter\n };\n self.new_nullifiers.push(side_effect);\n self.side_effect_counter = self.side_effect_counter + 1;\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_message_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, 0)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: AztecAddress, \n function_selector: FunctionSelector,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/context.nr" }, "43": { @@ -3456,11 +3456,11 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/note_getter.nr" }, "88": { - "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let serialized_note = serialize(*note);\n assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = 0;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note, context);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}\n", + "source": "use crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n broadcast: bool\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let serialized_note = serialize(*note);\n assert(notify_created_note(storage_slot, serialized_note, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n\n if broadcast {\n let broadcast = note_interface.broadcast;\n broadcast(context, storage_slot, *note);\n }\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = 0;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note, context);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending note hash\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullifier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/lifecycle.nr" }, "91": { - "source": "use dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n },\n hash::pedersen_hash,\n};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)\n}\n", + "source": "use dep::protocol_types::{\n address::AztecAddress,\n constants::{\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n },\n hash::pedersen_hash,\n};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen_hash([storage_slot, note_hash], 0)\n}\n\npub fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field {\n let inputs = [contract_address.to_field(), inner_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__SILOED_NOTE_HASH)\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_hash(inputs, GENERATOR_INDEX__UNIQUE_NOTE_HASH)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/note/note_hash.nr" }, "92": { @@ -3476,11 +3476,11 @@ "path": "/home/santiago/Projects/aztec3-packages/aztec-nr/aztec/src/types/type_serialization/field_serialization.nr" }, "105": { - "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_COMMITMENTS_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_COMMITMENTS_PER_TX ≥ MAX_NEW_COMMITMENTS_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_COMMITMENTS_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_COMMITMENTS_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__COMMITMENT_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_COMMITMENT = 3;\nglobal GENERATOR_INDEX__SILOED_COMMITMENT = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", + "source": "global ARGS_LENGTH: Field = 16;\nglobal RETURN_VALUES_LENGTH: Field = 4;\n\n/**\n * Convention for constant array lengths are mainly divided in 2 classes:\n * - FUNCTION CALL\n * - TRANSACTION\n *\n * Agreed convention is to use MAX_XXX_PER_CALL resp. MAX_XXX_PER_TX, where XXX denotes a type of element such as\n * commitment, or nullifier, e.g.,:\n * - MAX_NEW_NULLIFIERS_PER_CALL\n * - MAX_NEW_NOTE_HASHES_PER_TX\n *\n * In the kernel circuits, we accumulate elements such as commitments and the nullifiers from all functions calls in a\n * transaction. Therefore, we always must have:\n * MAX_XXX_PER_TX ≥ MAX_XXX_PER_CALL\n *\n * For instance:\n * MAX_NEW_NOTE_HASHES_PER_TX ≥ MAX_NEW_NOTE_HASHES_PER_CALL\n * MAX_NEW_NULLIFIERS_PER_TX ≥ MAX_NEW_NULLIFIERS_PER_CALL\n *\n */\n\n// docs:start:constants\n// \"PER CALL\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_CALL: Field = 16;\nglobal MAX_NEW_NULLIFIERS_PER_CALL: Field = 16;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL: Field = 4;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_CALL: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_CALL: Field = 16;\nglobal MAX_READ_REQUESTS_PER_CALL: Field = 32;\n\n// \"PER TRANSACTION\" CONSTANTS\nglobal MAX_NEW_NOTE_HASHES_PER_TX: Field = 64;\nglobal MAX_NEW_NULLIFIERS_PER_TX: Field = 64;\nglobal MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8;\nglobal MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2;\nglobal MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16;\nglobal MAX_PUBLIC_DATA_READS_PER_TX: Field = 16;\nglobal MAX_NEW_CONTRACTS_PER_TX: Field = 1;\nglobal MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX: Field = 4;\nglobal MAX_READ_REQUESTS_PER_TX: Field = 128;\nglobal NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\nglobal NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1;\n// docs:end:constants\n\n// ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP: Field = 16;\n\n// TREES RELATED CONSTANTS\nglobal VK_TREE_HEIGHT: Field = 3;\nglobal FUNCTION_TREE_HEIGHT: Field = 5;\nglobal CONTRACT_TREE_HEIGHT: Field = 16;\nglobal NOTE_HASH_TREE_HEIGHT: Field = 32;\nglobal PUBLIC_DATA_TREE_HEIGHT: Field = 40;\nglobal NULLIFIER_TREE_HEIGHT: Field = 20;\nglobal L1_TO_L2_MSG_TREE_HEIGHT: Field = 16;\nglobal ROLLUP_VK_TREE_HEIGHT: Field = 8;\n\n// SUB-TREES RELATED CONSTANTS\nglobal CONTRACT_SUBTREE_HEIGHT: Field = 0;\nglobal CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 16;\nglobal NOTE_HASH_SUBTREE_HEIGHT: Field = 6;\nglobal NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 26;\nglobal NULLIFIER_SUBTREE_HEIGHT: Field = 6;\nglobal PUBLIC_DATA_SUBTREE_HEIGHT: Field = 4;\nglobal ARCHIVE_HEIGHT: Field = 16;\nglobal NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 14;\nglobal PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: Field = 36;\nglobal L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4;\nglobal L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12;\n\n// MISC CONSTANTS\nglobal FUNCTION_SELECTOR_NUM_BYTES: Field = 4;\nglobal MAPPING_SLOT_PEDERSEN_SEPARATOR: Field = 4;\n// sha256 hash is stored in two fields to accommodate all 256-bits of the hash\nglobal NUM_FIELDS_PER_SHA256: Field = 2;\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\n// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts\n// Some are defined here because Noir doesn't yet support globals referencing other globals yet.\n// Move these constants to a noir file once the issue bellow is resolved:\n// https://github.com/noir-lang/noir/issues/1734\nglobal L1_TO_L2_MESSAGE_LENGTH: Field = 8;\nglobal L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH: Field = 25;\nglobal MAX_NOTE_FIELDS_LENGTH: Field = 20;\n// GET_NOTE_ORACLE_RETURN_LENGT = MAX_NOTE_FIELDS_LENGTH + 1 + 2\n// The plus 1 is 1 extra field for nonce.\n// + 2 for EXTRA_DATA: [number_of_return_notes, contract_address]\nglobal GET_NOTE_ORACLE_RETURN_LENGTH: Field = 23;\nglobal MAX_NOTES_PER_PAGE: Field = 10;\n// VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2;\nglobal VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212;\nglobal CALL_CONTEXT_LENGTH: Field = 8;\nglobal BLOCK_HEADER_LENGTH: Field = 7;\nglobal FUNCTION_DATA_LENGTH: Field = 4;\nglobal CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6;\n// Change this ONLY if you have changed the PrivateCircuitPublicInputs structure.\n// In other words, if the structure/size of the public inputs of a function call changes then we\n// should change this constant as well as the offsets in private_call_stack_item.nr\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 189;\nglobal CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: Field = 3;\nglobal CONTRACT_STORAGE_READ_LENGTH: Field = 2;\n// Change this ONLY if you have changed the PublicCircuitPublicInputs structure.\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: Field = 190;\nglobal GET_NOTES_ORACLE_RETURN_LENGTH: Field = 674;\nglobal CALL_PRIVATE_FUNCTION_RETURN_SIZE: Field = 195;\nglobal PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 87;\nglobal PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH: Field = 177;\nglobal NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: Field = 2048;\nglobal PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: Field = 1024;\nglobal CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52;\nglobal L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\nglobal LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP: Field = 64;\n\n/**\n * Enumerate the hash_indices which are used for pedersen hashing.\n * We start from 1 to avoid the default generators. The generator indices are listed\n * based on the number of elements each index hashes. The following conditions must be met:\n *\n * +-----------+-------------------------------+----------------------+\n * | Hash size | Number of elements hashed (n) | Condition to use |\n * |-----------+-------------------------------+----------------------|\n * | LOW | n ≤ 8 | 0 < hash_index ≤ 32 |\n * | MID | 8 < n ≤ 16 | 32 < hash_index ≤ 40 |\n * | HIGH | 16 < n ≤ 48 | 40 < hash_index ≤ 48 |\n * +-----------+-------------------------------+----------------------+\n *\n * Note: When modifying, modify `GeneratorIndexPacker` in packer.hpp accordingly.\n */\n// Indices with size ≤ 8\nglobal GENERATOR_INDEX__COMMITMENT = 1;\nglobal GENERATOR_INDEX__NOTE_HASH_NONCE = 2;\nglobal GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3;\nglobal GENERATOR_INDEX__SILOED_NOTE_HASH = 4;\nglobal GENERATOR_INDEX__NULLIFIER = 5;\nglobal GENERATOR_INDEX__INITIALIZATION_NULLIFIER = 6;\nglobal GENERATOR_INDEX__OUTER_NULLIFIER = 7;\nglobal GENERATOR_INDEX__PUBLIC_DATA_READ = 8;\nglobal GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST = 9;\nglobal GENERATOR_INDEX__FUNCTION_DATA = 10;\nglobal GENERATOR_INDEX__FUNCTION_LEAF = 11;\nglobal GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA = 12;\nglobal GENERATOR_INDEX__CONSTRUCTOR = 13;\nglobal GENERATOR_INDEX__CONSTRUCTOR_ARGS = 14;\nglobal GENERATOR_INDEX__CONTRACT_ADDRESS = 15;\nglobal GENERATOR_INDEX__CONTRACT_LEAF = 16;\nglobal GENERATOR_INDEX__CALL_CONTEXT = 17;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM = 18;\nglobal GENERATOR_INDEX__CALL_STACK_ITEM_2 = 19;\nglobal GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET = 20;\nglobal GENERATOR_INDEX__L2_TO_L1_MSG = 21;\nglobal GENERATOR_INDEX__TX_CONTEXT = 22;\nglobal GENERATOR_INDEX__PUBLIC_LEAF_INDEX = 23;\nglobal GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;\nglobal GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;\nglobal GENERATOR_INDEX__GLOBAL_VARIABLES = 26;\nglobal GENERATOR_INDEX__PARTIAL_ADDRESS = 27;\nglobal GENERATOR_INDEX__BLOCK_HASH = 28;\nglobal GENERATOR_INDEX__SIDE_EFFECT = 29;\n// Indices with size ≤ 16\nglobal GENERATOR_INDEX__TX_REQUEST = 33;\nglobal GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;\n// Indices with size ≤ 44\nglobal GENERATOR_INDEX__VK = 41;\nglobal GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS = 42;\nglobal GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS = 43;\nglobal GENERATOR_INDEX__FUNCTION_ARGS = 44;\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/constants.nr" }, "111": { - "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE,\n GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", + "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::FunctionLeafPreimage;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::utils::bounded_vec::BoundedVec;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT,\n ARGS_HASH_CHUNK_LENGTH,\n CONTRACT_TREE_HEIGHT, \n FUNCTION_TREE_HEIGHT, \n NOTE_HASH_TREE_HEIGHT,\n NUM_FIELDS_PER_SHA256,\n GENERATOR_INDEX__SILOED_NOTE_HASH,\n GENERATOR_INDEX__OUTER_NULLIFIER,\n GENERATOR_INDEX__VK,\n GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS,\n GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__NOTE_HASH_NONCE,\n GENERATOR_INDEX__UNIQUE_NOTE_HASH,\n GENERATOR_INDEX__FUNCTION_ARGS,\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n function_tree_root: Field,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, function_tree_root };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_note_hash(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_NOTE_HASH\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_note_hash_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__NOTE_HASH_NONCE\n )\n}\n\npub fn compute_unique_siloed_note_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_note_hash\n ],\n GENERATOR_INDEX__UNIQUE_NOTE_HASH\n )\n}\n\npub fn compute_unique_siloed_note_hashes(\n first_nullifier: Field,\n siloed_note_hashes: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_note_hashes = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_note_hash = siloed_note_hashes[i];\n if siloed_note_hash.value != 0 {\n let nonce = compute_note_hash_nonce(first_nullifier, i);\n unique_siloed_note_hashes[i] = SideEffect {\n value: compute_unique_siloed_note_hash(nonce, siloed_note_hash.value),\n counter: siloed_note_hash.counter\n };\n }\n }\n unique_siloed_note_hashes\n}\n\npub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/home/santiago/Projects/aztec3-packages/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "126": { diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 317ea220c43..47bbff17361 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -2,7 +2,7 @@ // GENERATED FILE - DO NOT EDIT, RUN yarn remake-constants export const ARGS_LENGTH = 16; export const RETURN_VALUES_LENGTH = 4; -export const MAX_NEW_COMMITMENTS_PER_CALL = 16; +export const MAX_NEW_NOTE_HASHES_PER_CALL = 16; export const MAX_NEW_NULLIFIERS_PER_CALL = 16; export const MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL = 4; export const MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL = 4; @@ -11,9 +11,9 @@ export const MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL = 16; export const MAX_PUBLIC_DATA_READS_PER_CALL = 16; export const MAX_READ_REQUESTS_PER_CALL = 32; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; -export const MAX_NEW_COMMITMENTS_PER_TX = 64; -export const MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; -export const MAX_REVERTIBLE_COMMITMENTS_PER_TX = 56; +export const MAX_NEW_NOTE_HASHES_PER_TX = 64; +export const MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; +export const MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; export const MAX_NEW_NULLIFIERS_PER_TX = 64; export const MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; export const MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; @@ -99,7 +99,7 @@ export const STATE_REFERENCE_LENGTH = 10; export const TX_CONTEXT_DATA_LENGTH = 11; export const TX_REQUEST_LENGTH = 17; export const GET_NOTES_ORACLE_RETURN_LENGTH = 674; -export const COMMITMENTS_NUM_BYTES_PER_BASE_ROLLUP = 2048; +export const NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP = 2048; export const CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP = 32; @@ -108,10 +108,10 @@ export const CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED = 52; export const L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 64; export const LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; export enum GeneratorIndex { - COMMITMENT = 1, - COMMITMENT_NONCE = 2, - UNIQUE_COMMITMENT = 3, - SILOED_COMMITMENT = 4, + NOTE_HASH = 1, + NOTE_HASH_NONCE = 2, + UNIQUE_NOTE_HASH = 3, + SILOED_NOTE_HASH = 4, NULLIFIER = 5, INITIALIZATION_NULLIFIER = 6, OUTER_NULLIFIER = 7, diff --git a/yarn-project/circuits.js/src/hash/hash.test.ts b/yarn-project/circuits.js/src/hash/hash.test.ts index 1839ba3e475..3f56b4167e3 100644 --- a/yarn-project/circuits.js/src/hash/hash.test.ts +++ b/yarn-project/circuits.js/src/hash/hash.test.ts @@ -14,7 +14,7 @@ import { computeVarArgsHash, hashConstructor, hashVK, - siloCommitment, + siloNoteHash, siloNullifier, } from './hash.js'; @@ -55,7 +55,7 @@ describe('hash', () => { it('computes siloed commitment', () => { const contractAddress = new AztecAddress(new Fr(123n).toBuffer()); const uniqueCommitment = new Fr(456); - const res = siloCommitment(contractAddress, uniqueCommitment); + const res = siloNoteHash(contractAddress, uniqueCommitment); expect(res).toMatchSnapshot(); }); diff --git a/yarn-project/circuits.js/src/hash/hash.ts b/yarn-project/circuits.js/src/hash/hash.ts index c9407b2b1e9..c545af04dfc 100644 --- a/yarn-project/circuits.js/src/hash/hash.ts +++ b/yarn-project/circuits.js/src/hash/hash.ts @@ -115,18 +115,18 @@ export function hashConstructor(functionData: FunctionData, argsHash: Fr, constr * @returns A commitment nonce. */ export function computeCommitmentNonce(nullifierZero: Fr, commitmentIndex: number): Fr { - return pedersenHash([nullifierZero.toBuffer(), numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.COMMITMENT_NONCE); + return pedersenHash([nullifierZero.toBuffer(), numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.NOTE_HASH_NONCE); } /** * Computes a siloed commitment, given the contract address and the commitment itself. * A siloed commitment effectively namespaces a commitment to a specific contract. * @param contract - The contract address - * @param innerCommitment - The commitment to silo. + * @param innerNoteHash - The commitment to silo. * @returns A siloed commitment. */ -export function siloCommitment(contract: AztecAddress, innerCommitment: Fr): Fr { - return pedersenHash([contract.toBuffer(), innerCommitment.toBuffer()], GeneratorIndex.SILOED_COMMITMENT); +export function siloNoteHash(contract: AztecAddress, innerNoteHash: Fr): Fr { + return pedersenHash([contract.toBuffer(), innerNoteHash.toBuffer()], GeneratorIndex.SILOED_NOTE_HASH); } /** @@ -136,7 +136,7 @@ export function siloCommitment(contract: AztecAddress, innerCommitment: Fr): Fr * @returns A unique commitment. */ export function computeUniqueCommitment(nonce: Fr, siloedCommitment: Fr): Fr { - return pedersenHash([nonce.toBuffer(), siloedCommitment.toBuffer()], GeneratorIndex.UNIQUE_COMMITMENT); + return pedersenHash([nonce.toBuffer(), siloedCommitment.toBuffer()], GeneratorIndex.UNIQUE_NOTE_HASH); } /** diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 811685523c0..d707423fb87 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -4,12 +4,12 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -20,7 +20,7 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -161,9 +161,9 @@ export class CombinedAccumulatedData { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX >, /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -216,7 +216,7 @@ export class CombinedAccumulatedData { return serializeToBuffer( this.readRequests, this.nullifierKeyValidationRequests, - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -245,7 +245,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( reader.readArray(MAX_READ_REQUESTS_PER_TX, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext), - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -273,7 +273,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - makeTuple(MAX_NEW_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -298,10 +298,10 @@ export class CombinedAccumulatedData { nonRevertible: PublicAccumulatedNonRevertibleData, revertible: PublicAccumulatedRevertibleData, ): CombinedAccumulatedData { - const newCommitments = padArrayEnd( - [...nonRevertible.newCommitments, ...revertible.newCommitments].filter(x => !x.isEmpty()), + const newNoteHashes = padArrayEnd( + [...nonRevertible.newNoteHashes, ...revertible.newNoteHashes].filter(x => !x.isEmpty()), SideEffect.empty(), - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, ); const newNullifiers = padArrayEnd( @@ -331,7 +331,7 @@ export class CombinedAccumulatedData { return new CombinedAccumulatedData( revertible.readRequests, revertible.nullifierKeyValidationRequests, - newCommitments, + newNoteHashes, newNullifiers, revertible.privateCallStack, publicCallStack, @@ -361,9 +361,9 @@ export class PublicAccumulatedRevertibleData { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX >, /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -419,7 +419,7 @@ export class PublicAccumulatedRevertibleData { return serializeToBuffer( this.readRequests, this.nullifierKeyValidationRequests, - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -448,7 +448,7 @@ export class PublicAccumulatedRevertibleData { return new this( reader.readArray(MAX_READ_REQUESTS_PER_TX, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext), - reader.readArray(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -467,7 +467,7 @@ export class PublicAccumulatedRevertibleData { return new this( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - padArrayEnd(finalData.newCommitments, SideEffect.empty(), MAX_REVERTIBLE_COMMITMENTS_PER_TX), + padArrayEnd(finalData.newNoteHashes, SideEffect.empty(), MAX_REVERTIBLE_NOTE_HASHES_PER_TX), padArrayEnd(finalData.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_REVERTIBLE_NULLIFIERS_PER_TX), finalData.privateCallStack, padArrayEnd(finalData.publicCallStack, CallRequest.empty(), MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX), @@ -495,7 +495,7 @@ export class PublicAccumulatedRevertibleData { return new this( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -518,9 +518,9 @@ export class PublicAccumulatedRevertibleData { export class PrivateAccumulatedRevertibleData { constructor( /** - * The new commitments made in this transaction. + * The new note hashes made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new nullifiers made in this transaction. */ @@ -564,7 +564,7 @@ export class PrivateAccumulatedRevertibleData { toBuffer() { return serializeToBuffer( - this.newCommitments, + this.newNoteHashes, this.newNullifiers, this.privateCallStack, this.publicCallStack, @@ -589,7 +589,7 @@ export class PrivateAccumulatedRevertibleData { static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedRevertibleData { const reader = BufferReader.asReader(buffer); return new PrivateAccumulatedRevertibleData( - reader.readArray(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), @@ -613,7 +613,7 @@ export class PrivateAccumulatedRevertibleData { static empty() { return new PrivateAccumulatedRevertibleData( - makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), @@ -632,7 +632,7 @@ export class PrivateAccumulatedNonRevertibleData { /** * The new non-revertible commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new non-revertible nullifiers made in this transaction. */ @@ -644,13 +644,13 @@ export class PrivateAccumulatedNonRevertibleData { ) {} toBuffer() { - return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); + return serializeToBuffer(this.newNoteHashes, this.newNullifiers, this.publicCallStack); } static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedNonRevertibleData { const reader = BufferReader.asReader(buffer); return new PrivateAccumulatedNonRevertibleData( - reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), ); @@ -666,7 +666,7 @@ export class PrivateAccumulatedNonRevertibleData { static empty() { return new PrivateAccumulatedNonRevertibleData( - makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), ); @@ -678,7 +678,7 @@ export class PublicAccumulatedNonRevertibleData { /** * The new non-revertible commitments made in this transaction. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * The new non-revertible nullifiers made in this transaction. */ @@ -701,13 +701,13 @@ export class PublicAccumulatedNonRevertibleData { ) {} toBuffer() { - return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); + return serializeToBuffer(this.newNoteHashes, this.newNullifiers, this.publicCallStack); } static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new this( - reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), @@ -725,7 +725,7 @@ export class PublicAccumulatedNonRevertibleData { static empty() { return new this( - makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), @@ -735,7 +735,7 @@ export class PublicAccumulatedNonRevertibleData { static fromPrivateAccumulatedNonRevertibleData(data: PrivateAccumulatedNonRevertibleData) { return new this( - data.newCommitments, + data.newNoteHashes, data.newNullifiers, data.publicCallStack, makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index a3e2a3edc7b..81bdee22ede 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -1,7 +1,7 @@ import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, @@ -21,13 +21,13 @@ export class PrivateKernelTailCircuitPrivateInputs { */ public previousKernel: PrivateKernelInnerData, /** - * The sorted new commitments. + * The sorted new note hashes. */ - public sortedNewCommitments: Tuple, + public sortedNewNoteHashes: Tuple, /** - * The sorted new commitments indexes. Maps original to sorted. + * The sorted new note hashes indexes. Maps original to sorted. */ - public sortedNewCommitmentsIndexes: Tuple, + public sortedNewNoteHashesIndexes: Tuple, /** * Contains hints for the transient read requests to localize corresponding commitments. */ @@ -57,8 +57,8 @@ export class PrivateKernelTailCircuitPrivateInputs { toBuffer() { return serializeToBuffer( this.previousKernel, - this.sortedNewCommitments, - this.sortedNewCommitmentsIndexes, + this.sortedNewNoteHashes, + this.sortedNewNoteHashesIndexes, this.readCommitmentHints, this.sortedNewNullifiers, this.sortedNewNullifiersIndexes, @@ -76,8 +76,8 @@ export class PrivateKernelTailCircuitPrivateInputs { const reader = BufferReader.asReader(buffer); return new PrivateKernelTailCircuitPrivateInputs( reader.readObject(PrivateKernelInnerData), - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX, SideEffect), - reader.readNumbers(MAX_NEW_COMMITMENTS_PER_TX), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), + reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_TX), reader.readArray(MAX_READ_REQUESTS_PER_TX, Fr), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), reader.readNumbers(MAX_NEW_NULLIFIERS_PER_TX), diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index cdf55d91df2..49fbd831180 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -7,8 +7,8 @@ import { FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, @@ -59,9 +59,9 @@ export class PrivateCircuitPublicInputs { typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL >, /** - * New commitments created by the corresponding function call. + * New note hashes created by the corresponding function call. */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * New nullifiers created by the corresponding function call. */ @@ -147,7 +147,7 @@ export class PrivateCircuitPublicInputs { reader.readObject(Fr), reader.readArray(MAX_READ_REQUESTS_PER_CALL, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr), @@ -173,7 +173,7 @@ export class PrivateCircuitPublicInputs { reader.readField(), reader.readArray(MAX_READ_REQUESTS_PER_CALL, SideEffect), reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readFieldArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL), reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL), @@ -202,7 +202,7 @@ export class PrivateCircuitPublicInputs { Fr.ZERO, makeTuple(MAX_READ_REQUESTS_PER_CALL, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, NullifierKeyValidationRequest.empty), - makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, Fr.zero), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr.zero), @@ -231,7 +231,7 @@ export class PrivateCircuitPublicInputs { this.minRevertibleSideEffectCounter.isZero() && isEmptyArray(this.readRequests) && isEmptyArray(this.nullifierKeyValidationRequests) && - isEmptyArray(this.newCommitments) && + isEmptyArray(this.newNoteHashes) && isEmptyArray(this.newNullifiers) && isZeroArray(this.privateCallStackHashes) && isZeroArray(this.publicCallStackHashes) && @@ -260,7 +260,7 @@ export class PrivateCircuitPublicInputs { fields.minRevertibleSideEffectCounter, fields.readRequests, fields.nullifierKeyValidationRequests, - fields.newCommitments, + fields.newNoteHashes, fields.newNullifiers, fields.privateCallStackHashes, fields.publicCallStackHashes, diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts index dace12f6fe7..c615bc6f77d 100644 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts +++ b/yarn-project/circuits.js/src/structs/public_call_stack_item.test.ts @@ -24,7 +24,7 @@ describe('PublicCallStackItem', () => { callStack.contractAddress = AztecAddress.fromField(new Fr(1)); callStack.functionData = new FunctionData(new FunctionSelector(2), false, false, false); callStack.isExecutionRequest = true; - callStack.publicInputs.newCommitments[0] = new SideEffect(new Fr(1), new Fr(0)); + callStack.publicInputs.newNoteHashes[0] = new SideEffect(new Fr(1), new Fr(0)); const hash = callStack.hash(); expect(hash.toString()).toMatchSnapshot(); @@ -38,7 +38,7 @@ describe('PublicCallStackItem', () => { callStack.contractAddress = AztecAddress.fromField(new Fr(1)); callStack.functionData = new FunctionData(new FunctionSelector(2), false, false, false); - callStack.publicInputs.newCommitments[0] = new SideEffect(new Fr(1), new Fr(0)); + callStack.publicInputs.newNoteHashes[0] = new SideEffect(new Fr(1), new Fr(0)); const hash = callStack.hash(); expect(hash.toString()).toMatchSnapshot(); diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index 4bf4d0140f6..b0412432048 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -8,8 +8,8 @@ import { FieldsOf } from '@aztec/foundation/types'; import { GeneratorIndex, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, @@ -58,9 +58,9 @@ export class PublicCircuitPublicInputs { */ public publicCallStackHashes: Tuple, /** - * New commitments created within a public execution call + * New note hashes created within a public execution call */ - public newCommitments: Tuple, + public newNoteHashes: Tuple, /** * New nullifiers created within a public execution call */ @@ -110,7 +110,7 @@ export class PublicCircuitPublicInputs { makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest.empty), makeTuple(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead.empty), makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr.zero), - makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect.empty), + makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message.empty), makeTuple(2, Fr.zero), @@ -132,7 +132,7 @@ export class PublicCircuitPublicInputs { isArrayEmpty(this.contractStorageUpdateRequests, item => item.isEmpty()) && isArrayEmpty(this.contractStorageReads, item => item.isEmpty()) && isFrArrayEmpty(this.publicCallStackHashes) && - isSideEffectArrayEmpty(this.newCommitments) && + isSideEffectArrayEmpty(this.newNoteHashes) && isSideEffectLinkedArrayEmpty(this.newNullifiers) && isArrayEmpty(this.newL2ToL1Msgs, item => item.isEmpty()) && isFrArrayEmpty(this.unencryptedLogsHash) && @@ -155,7 +155,7 @@ export class PublicCircuitPublicInputs { fields.contractStorageUpdateRequests, fields.contractStorageReads, fields.publicCallStackHashes, - fields.newCommitments, + fields.newNoteHashes, fields.newNullifiers, fields.newL2ToL1Msgs, fields.unencryptedLogsHash, @@ -197,7 +197,7 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest), reader.readArray(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead), reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, Fr), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readArray(NUM_FIELDS_PER_SHA256, Fr), @@ -217,7 +217,7 @@ export class PublicCircuitPublicInputs { reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, ContractStorageUpdateRequest), reader.readArray(MAX_PUBLIC_DATA_READS_PER_CALL, ContractStorageRead), reader.readFieldArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL), - reader.readArray(MAX_NEW_COMMITMENTS_PER_CALL, SideEffect), + reader.readArray(MAX_NEW_NOTE_HASHES_PER_CALL, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_CALL, SideEffectLinkedToNoteHash), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, L2ToL1Message), reader.readFieldArray(NUM_FIELDS_PER_SHA256), diff --git a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts index 008fc02ace0..e77b32692ab 100644 --- a/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts +++ b/yarn-project/circuits.js/src/structs/read_request_membership_witness.ts @@ -3,7 +3,7 @@ import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { MAX_NEW_COMMITMENTS_PER_CALL, NOTE_HASH_TREE_HEIGHT } from '../constants.gen.js'; +import { MAX_NEW_NOTE_HASHES_PER_CALL, NOTE_HASH_TREE_HEIGHT } from '../constants.gen.js'; import { MembershipWitness } from './membership_witness.js'; /** @@ -22,19 +22,19 @@ export class ReadRequestMembershipWitness { */ public siblingPath: Tuple, /** - * Whether or not the read request corresponds to a pending commitment. + * Whether or not the read request corresponds to a pending note hash. */ public isTransient = false, /** - * When transient, the commitment being read was created by some app circuit in the current TX. - * The kernel will need some hint to efficiently find that commitment for a given read request. + * When transient, the note hash being read was created by some app circuit in the current TX. + * The kernel will need some hint to efficiently find that note hash for a given read request. * When not transient, this can be 0. */ - public hintToCommitment: Fr, + public hintToNoteHash: Fr, ) { - if (hintToCommitment.toBigInt() > MAX_NEW_COMMITMENTS_PER_CALL) { + if (hintToNoteHash.toBigInt() > MAX_NEW_NOTE_HASHES_PER_CALL) { throw new Error( - `Expected ReadRequestMembershipWitness' hintToCommitment(${hintToCommitment}) to be <= NEW_COMMITMENTS_LENGTH(${MAX_NEW_COMMITMENTS_PER_CALL})`, + `Expected ReadRequestMembershipWitness' hintToNoteHash(${hintToNoteHash}) to be <= NEW_NOTE_HASHES_LENGTH(${MAX_NEW_NOTE_HASHES_PER_CALL})`, ); } } @@ -44,7 +44,7 @@ export class ReadRequestMembershipWitness { toBufferBE(this.leafIndex.toBigInt(), 32), ...this.siblingPath, this.isTransient, - this.hintToCommitment, + this.hintToNoteHash, ); } @@ -93,26 +93,26 @@ export class ReadRequestMembershipWitness { leafIndex: Fr, siblingPath: Tuple, isTransient: boolean, - hintToCommitment: Fr, + hintToNoteHash: Fr, ): ReadRequestMembershipWitness { return new ReadRequestMembershipWitness( leafIndex, siblingPath.map(x => Fr.fromBuffer(x)) as Tuple, isTransient, - hintToCommitment, + hintToNoteHash, ); } static fromMembershipWitness( membershipWitness: MembershipWitness, isTransient: boolean, - hintToCommitment: Fr, + hintToNoteHash: Fr, ): ReadRequestMembershipWitness { return new ReadRequestMembershipWitness( new Fr(membershipWitness.leafIndex), membershipWitness.siblingPath as Tuple, isTransient, - hintToCommitment, + hintToNoteHash, ); } @@ -126,7 +126,7 @@ export class ReadRequestMembershipWitness { const leafIndex = Fr.fromBuffer(reader); const siblingPath = reader.readArray(NOTE_HASH_TREE_HEIGHT, Fr); const isTransient = reader.readBoolean(); - const hintToCommitment = Fr.fromBuffer(reader); - return new ReadRequestMembershipWitness(leafIndex, siblingPath, isTransient, hintToCommitment); + const hintToNoteHash = Fr.fromBuffer(reader); + return new ReadRequestMembershipWitness(leafIndex, siblingPath, isTransient, hintToNoteHash); } } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 3bd6887749b..edb18d5a2f5 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -34,14 +34,14 @@ import { GrumpkinScalar, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -58,7 +58,7 @@ import { MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -262,7 +262,7 @@ export function makeAccumulatedData(seed = 1, full = false): CombinedAccumulated makeNullifierKeyValidationRequestContext, seed + 0x100, ), - tupleGenerator(MAX_NEW_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x120), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), tupleGenerator(MAX_NEW_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), @@ -292,7 +292,7 @@ export function makeCombinedAccumulatedRevertibleData(seed = 1, full = false): P makeNullifierKeyValidationRequestContext, seed + 0x100, ), - tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x120), + tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), @@ -316,7 +316,7 @@ export function makeFinalAccumulatedData(seed = 1, full = false): PrivateAccumul const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PrivateAccumulatedRevertibleData( - tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x100), + tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x100), tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), @@ -338,7 +338,7 @@ export function makeAccumulatedNonRevertibleData(seed = 1, full = false): Privat const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PrivateAccumulatedNonRevertibleData( - tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x101), + tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), ); @@ -348,7 +348,7 @@ export function makeCombinedAccumulatedNonRevertibleData(seed = 1, full = false) const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new PublicAccumulatedNonRevertibleData( - tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x101), + tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0x601), @@ -418,7 +418,7 @@ export function makePublicCircuitPublicInputs( tupleGenerator(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, makeContractStorageUpdateRequest, seed + 0x400), tupleGenerator(MAX_PUBLIC_DATA_READS_PER_CALL, makeContractStorageRead, seed + 0x500), tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), - tupleGenerator(MAX_NEW_COMMITMENTS_PER_CALL, makeNewSideEffect, seed + 0x700), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_CALL, makeNewSideEffect, seed + 0x700), tupleGenerator(MAX_NEW_NULLIFIERS_PER_CALL, makeNewSideEffectLinkedToNoteHash, seed + 0x800), tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x900), tupleGenerator(2, fr, seed + 0x901), @@ -821,7 +821,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn makeNullifierKeyValidationRequest, seed + 0x300, ), - newCommitments: makeTuple(MAX_NEW_COMMITMENTS_PER_CALL, sideEffectFromNumber, seed + 0x400), + newNoteHashes: makeTuple(MAX_NEW_NOTE_HASHES_PER_CALL, sideEffectFromNumber, seed + 0x400), newNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_CALL, sideEffectLinkedFromNumber, seed + 0x500), privateCallStackHashes: makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), publicCallStackHashes: makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x700), diff --git a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts index 0fe30e0b8af..f1baba3cc46 100644 --- a/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts @@ -54,7 +54,7 @@ describe('e2e_inclusion_proofs_contract', () => { describe('proves note existence and its nullifier non-existence and nullifier non-existence failure case', () => { // Owner of a note let noteCreationBlockNumber: number; - let newCommitments, visibleNotes: any; + let newNoteHashes, visibleNotes: any; const value = 100n; let validNoteBlockNumber: any; @@ -63,11 +63,11 @@ describe('e2e_inclusion_proofs_contract', () => { const receipt = await contract.methods.create_note(owner, value).send().wait({ debug: true }); noteCreationBlockNumber = receipt.blockNumber!; - ({ newCommitments, visibleNotes } = receipt.debugInfo!); + ({ newNoteHashes, visibleNotes } = receipt.debugInfo!); }); it('should return the correct values for creating a note', () => { - expect(newCommitments.length).toBe(1); + expect(newNoteHashes.length).toBe(1); expect(visibleNotes.length).toBe(1); const [receivedValue, receivedOwner, _randomness] = visibleNotes[0].note.items; expect(receivedValue.toBigInt()).toBe(value); @@ -158,9 +158,9 @@ describe('e2e_inclusion_proofs_contract', () => { const receipt = await contract.methods.create_note(owner, value).send().wait({ debug: true }); noteCreationBlockNumber = receipt.blockNumber!; - const { newCommitments, visibleNotes } = receipt.debugInfo!; + const { newNoteHashes, visibleNotes } = receipt.debugInfo!; - expect(newCommitments.length).toBe(1); + expect(newNoteHashes.length).toBe(1); expect(visibleNotes.length).toBe(1); const [receivedValue, receivedOwner, _randomness] = visibleNotes[0].note.items; expect(receivedValue.toBigInt()).toBe(value); diff --git a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts index 40ea8166bf9..597fe7e944e 100644 --- a/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts +++ b/yarn-project/end-to-end/src/e2e_non_contract_account.test.ts @@ -77,7 +77,7 @@ describe('e2e_non_contract_account', () => { // check that 1 commitment was created const tx = await pxe.getTx(receipt.txHash); - const nonZeroCommitments = tx?.newCommitments.filter(c => c.value > 0); + const nonZeroCommitments = tx?.newNoteHashes.filter(c => c.value > 0); expect(nonZeroCommitments?.length).toBe(1); // Add the note diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 8b545859d32..ef720e7ca05 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -49,7 +49,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(tx?.newNullifiers.length).toEqual(2); expect(await contract.methods.is_legendary_initialized().view()).toEqual(true); @@ -75,7 +75,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -99,7 +99,7 @@ describe('e2e_state_vars', () => { .wait(); expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -114,7 +114,7 @@ describe('e2e_state_vars', () => { const receipt = await contract.methods.increase_legendary_points().send().wait(); expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the nullifier of the previous note expect(tx?.newNullifiers.length).toEqual(2); @@ -136,7 +136,7 @@ describe('e2e_state_vars', () => { expect(receipt.status).toEqual(TxStatus.MINED); const tx = await wallet.getTx(receipt.txHash); - expect(tx?.newCommitments.length).toEqual(1); + expect(tx?.newNoteHashes.length).toEqual(1); // 1 for the tx, another for the initializer expect(tx?.newNullifiers.length).toEqual(2); expect(await contract.methods.is_imm_initialized().view()).toEqual(true); diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index c363a71278f..49fe9f2705a 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -14,7 +14,7 @@ import { Header, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, @@ -179,7 +179,7 @@ describe('L1Publisher integration', () => { const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, makeNewSideEffect, seed + 0x100); + processedTx.data.end.newNoteHashes = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100); processedTx.data.end.newNullifiers = makeTuple( MAX_REVERTIBLE_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 6944399b88f..301417ce4a1 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -440,7 +440,7 @@ export class CrossChainTestHarness { } async redeemShieldPrivatelyOnL2(shieldAmount: bigint, secret: Fr) { - this.logger('Spending commitment in private call'); + this.logger('Spending note in private call'); const privateTx = this.l2Token.methods.redeem_shield(this.ownerAddress, shieldAmount, secret).send(); const privateReceipt = await privateTx.wait(); expect(privateReceipt.status).toBe(TxStatus.MINED); diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap index 1bbae4a36d1..6e46b38bd9f 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap @@ -1055,9 +1055,9 @@ PrivateKernelInnerCircuitPublicInputs { }, }, ], - "newCommitments": [ - SideEffect { - "counter": Fr { + "newContracts": [ + NewContractData { + "contractAddress": AztecAddress { "asBigInt": 0n, "asBuffer": { "data": [ @@ -1097,7 +1097,7 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + "contractClassId": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -1137,11 +1137,8 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { + "portalContractAddress": EthAddress { + "buffer": { "data": [ 0, 0, @@ -1163,63 +1160,95 @@ PrivateKernelInnerCircuitPublicInputs { 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, ], "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, + }, + ], + "newL2ToL1Msgs": [ + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", }, }, + ], + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 0n, @@ -6304,10 +6333,8 @@ PrivateKernelInnerCircuitPublicInputs { }, }, }, - ], - "newContracts": [ - NewContractData { - "contractAddress": AztecAddress { + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -6347,7 +6374,7 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "contractClassId": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -6387,8 +6414,11 @@ PrivateKernelInnerCircuitPublicInputs { "type": "Buffer", }, }, - "portalContractAddress": EthAddress { - "buffer": { + }, + SideEffect { + "counter": Fr { + "asBigInt": 0n, + "asBuffer": { "data": [ 0, 0, @@ -6410,97 +6440,67 @@ PrivateKernelInnerCircuitPublicInputs { 0, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, ], "type": "Buffer", }, }, - }, - ], - "newL2ToL1Msgs": [ - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr { + "value": Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + ], + "newNullifiers": [ + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -35914,7 +35914,200 @@ PrivateKernelTailCircuitPublicInputs { }, }, ], - "newCommitments": [ + "newContracts": [ + NewContractData { + "contractAddress": AztecAddress { + "asBigInt": 7667752348302703004105847231271989658843538975557179704689760117635404498899n, + "asBuffer": { + "data": [ + 16, + 243, + 203, + 69, + 185, + 4, + 96, + 183, + 89, + 171, + 13, + 30, + 15, + 188, + 64, + 63, + 182, + 216, + 212, + 55, + 181, + 74, + 72, + 194, + 224, + 79, + 40, + 42, + 36, + 239, + 135, + 211, + ], + "type": "Buffer", + }, + }, + "contractClassId": Fr { + "asBigInt": 14382725657784677548089422063797280690497459898548737366354813204068709973929n, + "asBuffer": { + "data": [ + 31, + 204, + 85, + 144, + 188, + 44, + 12, + 186, + 124, + 105, + 137, + 241, + 157, + 212, + 243, + 50, + 29, + 209, + 56, + 100, + 241, + 88, + 182, + 78, + 71, + 162, + 226, + 76, + 31, + 100, + 63, + 169, + ], + "type": "Buffer", + }, + }, + "portalContractAddress": EthAddress { + "buffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + ], + "newL2ToL1Msgs": [ + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + ], + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 3n, @@ -40508,199 +40701,6 @@ PrivateKernelTailCircuitPublicInputs { }, }, ], - "newContracts": [ - NewContractData { - "contractAddress": AztecAddress { - "asBigInt": 7667752348302703004105847231271989658843538975557179704689760117635404498899n, - "asBuffer": { - "data": [ - 16, - 243, - 203, - 69, - 185, - 4, - 96, - 183, - 89, - 171, - 13, - 30, - 15, - 188, - 64, - 63, - 182, - 216, - 212, - 55, - 181, - 74, - 72, - 194, - 224, - 79, - 40, - 42, - 36, - 239, - 135, - 211, - ], - "type": "Buffer", - }, - }, - "contractClassId": Fr { - "asBigInt": 14382725657784677548089422063797280690497459898548737366354813204068709973929n, - "asBuffer": { - "data": [ - 31, - 204, - 85, - 144, - 188, - 44, - 12, - 186, - 124, - 105, - 137, - 241, - 157, - 212, - 243, - 50, - 29, - 209, - 56, - 100, - 241, - 88, - 182, - 78, - 71, - 162, - 226, - 76, - 31, - 100, - 63, - 169, - ], - "type": "Buffer", - }, - }, - "portalContractAddress": EthAddress { - "buffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - ], - "newL2ToL1Msgs": [ - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - ], "newNullifiers": [ SideEffectLinkedToNoteHash { "counter": Fr { @@ -50835,7 +50835,7 @@ PrivateKernelTailCircuitPublicInputs { ], }, "endNonRevertibleData": PrivateAccumulatedNonRevertibleData { - "newCommitments": [ + "newNoteHashes": [ SideEffect { "counter": Fr { "asBigInt": 0n, diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 218fe5adbfc..fb32ea07a6d 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -25,11 +25,11 @@ import { GrumpkinScalar, Header, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -40,7 +40,7 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, @@ -663,7 +663,7 @@ export function mapPrivateCircuitPublicInputsToNoir( privateCircuitPublicInputs.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestToNoir, ), - new_commitments: mapTuple(privateCircuitPublicInputs.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(privateCircuitPublicInputs.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(privateCircuitPublicInputs.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack_hashes: mapTuple(privateCircuitPublicInputs.privateCallStackHashes, mapFieldToNoir), public_call_stack_hashes: mapTuple(privateCircuitPublicInputs.publicCallStackHashes, mapFieldToNoir), @@ -720,7 +720,7 @@ export function mapReadRequestMembershipWitnessToNoir( leaf_index: mapFieldToNoir(readRequestMembershipWitness.leafIndex), sibling_path: mapTuple(readRequestMembershipWitness.siblingPath, mapFieldToNoir), is_transient: readRequestMembershipWitness.isTransient, - hint_to_commitment: mapFieldToNoir(readRequestMembershipWitness.hintToCommitment), + hint_to_note_hash: mapFieldToNoir(readRequestMembershipWitness.hintToNoteHash), }; } @@ -879,7 +879,7 @@ export function mapCombinedAccumulatedDataFromNoir( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, mapNullifierKeyValidationRequestContextFromNoir, ), - mapTupleFromNoir(combinedAccumulatedData.new_commitments, MAX_NEW_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(combinedAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(combinedAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir( combinedAccumulatedData.private_call_stack, @@ -919,7 +919,7 @@ export function mapFinalAccumulatedDataFromNoir( finalAccumulatedData: PrivateAccumulatedRevertibleDataNoir, ): PrivateAccumulatedRevertibleData { return new PrivateAccumulatedRevertibleData( - mapTupleFromNoir(finalAccumulatedData.new_commitments, MAX_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(finalAccumulatedData.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir( finalAccumulatedData.new_nullifiers, MAX_REVERTIBLE_NULLIFIERS_PER_TX, @@ -953,7 +953,7 @@ export function mapAccumulatedNonRevertibleDataFromNoir( accumulatedMetaData: PrivateAccumulatedNonRevertibleDataNoir, ): PrivateAccumulatedNonRevertibleData { return new PrivateAccumulatedNonRevertibleData( - mapTupleFromNoir(accumulatedMetaData.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(accumulatedMetaData.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir( accumulatedMetaData.new_nullifiers, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, @@ -976,7 +976,7 @@ export function mapAccumulatedNonRevertibleDataToNoir( accumulatedMetaData: PrivateAccumulatedNonRevertibleData, ): PrivateAccumulatedNonRevertibleDataNoir { return { - new_commitments: mapTuple(accumulatedMetaData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(accumulatedMetaData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(accumulatedMetaData.newNullifiers, mapSideEffectLinkedToNoir), public_call_stack: mapTuple(accumulatedMetaData.publicCallStack, mapCallRequestToNoir), }; @@ -986,7 +986,7 @@ export function mapPrivateAccumulatedRevertibleDataToNoir( data: PrivateAccumulatedRevertibleData, ): PrivateAccumulatedRevertibleDataNoir { return { - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), @@ -1013,7 +1013,7 @@ export function mapCombinedAccumulatedDataToNoir( combinedAccumulatedData.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestContextToNoir, ), - new_commitments: mapTuple(combinedAccumulatedData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(combinedAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(combinedAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(combinedAccumulatedData.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(combinedAccumulatedData.publicCallStack, mapCallRequestToNoir), @@ -1092,7 +1092,7 @@ export function mapPublicAccumulatedRevertibleDataToNoir( data.nullifierKeyValidationRequests, mapNullifierKeyValidationRequestContextToNoir, ), - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), @@ -1111,7 +1111,7 @@ export function mapPublicAccumulatedNonRevertibleDataToNoir( data: PublicAccumulatedNonRevertibleData, ): PublicAccumulatedNonRevertibleDataNoir { return { - new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), public_data_reads: mapTuple(data.publicDataReads, mapPublicDataReadToNoir), @@ -1184,7 +1184,7 @@ export function mapFinalAccumulatedDataToNoir( finalAccumulatedData: PrivateAccumulatedRevertibleData, ): PrivateAccumulatedRevertibleDataNoir { return { - new_commitments: mapTuple(finalAccumulatedData.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(finalAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(finalAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), private_call_stack: mapTuple(finalAccumulatedData.privateCallStack, mapCallRequestToNoir), public_call_stack: mapTuple(finalAccumulatedData.publicCallStack, mapCallRequestToNoir), @@ -1249,8 +1249,8 @@ export function mapPrivateKernelTailCircuitPrivateInputsToNoir( ): PrivateKernelTailCircuitPrivateInputsNoir { return { previous_kernel: mapPrivateKernelInnerDataToNoir(inputs.previousKernel), - sorted_new_commitments: mapTuple(inputs.sortedNewCommitments, mapSideEffectToNoir), - sorted_new_commitments_indexes: mapTuple(inputs.sortedNewCommitmentsIndexes, mapNumberToNoir), + sorted_new_note_hashes: mapTuple(inputs.sortedNewNoteHashes, mapSideEffectToNoir), + sorted_new_note_hashes_indexes: mapTuple(inputs.sortedNewNoteHashesIndexes, mapNumberToNoir), read_commitment_hints: mapTuple(inputs.readCommitmentHints, mapFieldToNoir), sorted_new_nullifiers: mapTuple(inputs.sortedNewNullifiers, mapSideEffectLinkedToNoir), sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), @@ -1286,7 +1286,7 @@ export function mapPublicAccumulatedNonRevertibleDataFromNoir( data: PublicAccumulatedNonRevertibleDataNoir, ): PublicAccumulatedNonRevertibleData { return new PublicAccumulatedNonRevertibleData( - mapTupleFromNoir(data.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(data.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(data.new_nullifiers, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir( data.public_call_stack, @@ -1312,7 +1312,7 @@ export function mapPublicAccumulatedRevertibleDataFromNoir( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, mapNullifierKeyValidationRequestContextFromNoir, ), - mapTupleFromNoir(data.new_commitments, MAX_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(data.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(data.new_nullifiers, MAX_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), mapTupleFromNoir(data.private_call_stack, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), mapTupleFromNoir(data.public_call_stack, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), @@ -1421,7 +1421,7 @@ export function mapPublicCircuitPublicInputsToNoir( ), contract_storage_reads: mapTuple(publicInputs.contractStorageReads, mapStorageReadToNoir), public_call_stack_hashes: mapTuple(publicInputs.publicCallStackHashes, mapFieldToNoir), - new_commitments: mapTuple(publicInputs.newCommitments, mapSideEffectToNoir), + new_note_hashes: mapTuple(publicInputs.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(publicInputs.newNullifiers, mapSideEffectLinkedToNoir), new_l2_to_l1_msgs: mapTuple(publicInputs.newL2ToL1Msgs, mapL2ToL1MessageToNoir), unencrypted_logs_hash: mapTuple(publicInputs.unencryptedLogsHash, mapFieldToNoir), diff --git a/yarn-project/pxe/src/database/deferred_note_dao.test.ts b/yarn-project/pxe/src/database/deferred_note_dao.test.ts index 457da7d81a4..757aad9100d 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.test.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.test.ts @@ -10,7 +10,7 @@ export const randomDeferredNoteDao = ({ txHash = randomTxHash(), storageSlot = Fr.random(), noteTypeId = Fr.random(), - newCommitments = [Fr.random(), Fr.random()], + newNoteHashes = [Fr.random(), Fr.random()], dataStartIndexForTx = Math.floor(Math.random() * 100), }: Partial = {}) => { return new DeferredNoteDao( @@ -20,7 +20,7 @@ export const randomDeferredNoteDao = ({ storageSlot, noteTypeId, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, ); }; diff --git a/yarn-project/pxe/src/database/deferred_note_dao.ts b/yarn-project/pxe/src/database/deferred_note_dao.ts index 97f6a41bd21..af0ee6a89b2 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.ts @@ -21,8 +21,8 @@ export class DeferredNoteDao { public noteTypeId: Fr, /** The hash of the tx the note was created in. Equal to the first nullifier */ public txHash: TxHash, - /** New commitments in this transaction, one of which belongs to this note */ - public newCommitments: Fr[], + /** New note hashes in this transaction, one of which belongs to this note */ + public newNoteHashes: Fr[], /** The next available leaf index for the note hash tree for this transaction */ public dataStartIndexForTx: number, ) {} @@ -35,7 +35,7 @@ export class DeferredNoteDao { this.storageSlot.toBuffer(), this.noteTypeId.toBuffer(), this.txHash.toBuffer(), - new Vector(this.newCommitments), + new Vector(this.newNoteHashes), this.dataStartIndexForTx, ); } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index c52785c4743..fd3049681f3 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -2,10 +2,10 @@ import { FunctionL2Logs, Note } from '@aztec/circuit-types'; import { FunctionData, FunctionSelector, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_READ_REQUESTS_PER_CALL, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MembershipWitness, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -52,8 +52,8 @@ describe('Kernel Prover', () => { const createExecutionResult = (fnName: string, newNoteIndices: number[] = []): ExecutionResult => { const publicInputs = PrivateCircuitPublicInputs.empty(); - publicInputs.newCommitments = makeTuple( - MAX_NEW_COMMITMENTS_PER_CALL, + publicInputs.newNoteHashes = makeTuple( + MAX_NEW_NOTE_HASHES_PER_CALL, i => i < newNoteIndices.length ? new SideEffect(generateFakeCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO) @@ -83,12 +83,12 @@ describe('Kernel Prover', () => { const createProofOutput = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelInnerCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } - publicInputs.end.newCommitments = commitments; + publicInputs.end.newNoteHashes = commitments; return { publicInputs, proof: makeEmptyProof(), @@ -97,12 +97,12 @@ describe('Kernel Prover', () => { const createProofOutputFinal = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelTailCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } - publicInputs.end.newCommitments = commitments; + publicInputs.end.newNoteHashes = commitments; return { publicInputs, proof: makeEmptyProof(), @@ -153,7 +153,7 @@ describe('Kernel Prover', () => { proofCreator = mock(); proofCreator.getSiloedCommitments.mockImplementation(publicInputs => - Promise.resolve(publicInputs.newCommitments.map(com => createFakeSiloedCommitment(com.value))), + Promise.resolve(publicInputs.newNoteHashes.map(com => createFakeSiloedCommitment(com.value))), ); proofCreator.createProofInit.mockResolvedValue(createProofOutput([])); proofCreator.createProofInner.mockResolvedValue(createProofOutput([])); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 2f6f1eb2444..aa8aa944e63 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -3,7 +3,7 @@ import { CallRequest, Fr, GrumpkinScalar, - MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, @@ -177,8 +177,8 @@ export class KernelProver { const [sortedCommitments, sortedCommitmentsIndexes] = this.sortSideEffects< SideEffect, - typeof MAX_NEW_COMMITMENTS_PER_TX - >(output.publicInputs.end.newCommitments); + typeof MAX_NEW_NOTE_HASHES_PER_TX + >(output.publicInputs.end.newNoteHashes); const [sortedNullifiers, sortedNullifiersIndexes] = this.sortSideEffects< SideEffectLinkedToNoteHash, @@ -214,7 +214,7 @@ export class KernelProver { const outputFinal = await this.proofCreator.createProofTail(privateInputs); // Only return the notes whose commitment is in the commitments of the final proof. - const finalNewCommitments = outputFinal.publicInputs.end.newCommitments; + const finalNewCommitments = outputFinal.publicInputs.end.newNoteHashes; const outputNotes = finalNewCommitments.map(c => newNotes[c.value.toString()]).filter(c => !!c); return { ...outputFinal, outputNotes }; @@ -308,11 +308,11 @@ export class KernelProver { } = executionResult; const contractAddress = publicInputs.callContext.storageContractAddress; // Assuming that for each new commitment there's an output note added to the execution result. - const newCommitments = await this.proofCreator.getSiloedCommitments(publicInputs); + const newNoteHashes = await this.proofCreator.getSiloedCommitments(publicInputs); return newNotes.map((data, i) => ({ contractAddress, data, - commitment: newCommitments[i], + commitment: newNoteHashes[i], })); } @@ -323,18 +323,18 @@ export class KernelProver { * to return more than one hint with the same index (contrary to getNullifierHints). * * @param readRequests - The array of read requests. - * @param commitments - The array of commitments. + * @param noteHashes - The array of commitments. * @returns An array of hints where each element is the index of the commitment in commitments array * corresponding to the read request. In other words we have readRequests[i] == commitments[hints[i]]. */ private getReadRequestHints( readRequests: Tuple, - commitments: Tuple, + noteHashes: Tuple, ): Tuple { const hints = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero); for (let i = 0; i < MAX_READ_REQUESTS_PER_TX && !readRequests[i].isEmpty(); i++) { const equalToRR = (cmt: SideEffect) => cmt.value.equals(readRequests[i].value); - const result = commitments.findIndex(equalToRR); + const result = noteHashes.findIndex(equalToRR); if (result == -1) { throw new Error( `The read request at index ${i} with value ${readRequests[i].toString()} does not match to any commitment.`, @@ -353,26 +353,26 @@ export class KernelProver { * (resp. nullified commitments) array. It is crucial in this case that each hint points to a different index * of the nullified commitments array. Otherwise, the private kernel will fail to validate. * - * @param nullifiedCommitments - The array of nullified commitments. - * @param commitments - The array of commitments. + * @param nullifiedNoteHashes - The array of nullified note hashes. + * @param noteHashes - The array of note hasshes. * @returns An array of hints where each element is the index of the commitment in commitments array * corresponding to the nullified commitments. In other words we have nullifiedCommitments[i] == commitments[hints[i]]. */ private getNullifierHints( - nullifiedCommitments: Tuple, - commitments: Tuple, + nullifiedNoteHashes: Tuple, + noteHashes: Tuple, ): Tuple { const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero); const alreadyUsed = new Set(); for (let i = 0; i < MAX_NEW_NULLIFIERS_PER_TX; i++) { - if (!nullifiedCommitments[i].isZero()) { + if (!nullifiedNoteHashes[i].isZero()) { const equalToCommitment = (cmt: SideEffect, index: number) => - cmt.value.equals(nullifiedCommitments[i]) && !alreadyUsed.has(index); - const result = commitments.findIndex(equalToCommitment); + cmt.value.equals(nullifiedNoteHashes[i]) && !alreadyUsed.has(index); + const result = noteHashes.findIndex(equalToCommitment); alreadyUsed.add(result); if (result == -1) { throw new Error( - `The nullified commitment at index ${i} with value ${nullifiedCommitments[ + `The nullified commitment at index ${i} with value ${nullifiedNoteHashes[ i ].toString()} does not match to any commitment.`, ); diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index bd53ce0e56e..6dfabdc0642 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -9,7 +9,7 @@ import { Proof, makeEmptyProof, } from '@aztec/circuits.js'; -import { siloCommitment } from '@aztec/circuits.js/hash'; +import { siloNoteHash } from '@aztec/circuits.js/hash'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; @@ -53,7 +53,7 @@ export interface ProofCreator { /** * Computes the siloed commitments for a given set of public inputs. * - * @param publicInputs - The public inputs containing the contract address and new commitments to be used in generating siloed commitments. + * @param publicInputs - The public inputs containing the contract address and new note hashes to be used in generating siloed note hashes. * @returns An array of Fr (finite field) elements representing the siloed commitments. */ getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs): Promise; @@ -97,7 +97,7 @@ export class KernelProofCreator implements ProofCreator { const contractAddress = publicInputs.callContext.storageContractAddress; return Promise.resolve( - publicInputs.newCommitments.map(commitment => siloCommitment(contractAddress, commitment.value)), + publicInputs.newNoteHashes.map(commitment => siloNoteHash(contractAddress, commitment.value)), ); } diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts index 6c66111c2b0..73ea1f08a27 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -11,10 +11,11 @@ import { Note, TxL2Logs, } from '@aztec/circuit-types'; -import { Fr, MAX_NEW_COMMITMENTS_PER_TX } from '@aztec/circuits.js'; +import { Fr, MAX_NEW_NOTE_HASHES_PER_TX } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { pedersenHash } from '@aztec/foundation/crypto'; import { Point } from '@aztec/foundation/fields'; +import { Tuple } from '@aztec/foundation/serialize'; import { ConstantKeyPair } from '@aztec/key-store'; import { openTmpStore } from '@aztec/kv-store/utils'; import { AcirSimulator } from '@aztec/simulator'; @@ -39,7 +40,7 @@ describe('Note Processor', () => { let keyStore: MockProxy; let simulator: MockProxy; const firstBlockNum = 123; - const numCommitmentsPerBlock = TXS_PER_BLOCK * MAX_NEW_COMMITMENTS_PER_TX; + const numCommitmentsPerBlock = TXS_PER_BLOCK * MAX_NEW_NOTE_HASHES_PER_TX; const firstBlockDataStartIndex = (firstBlockNum - 1) * numCommitmentsPerBlock; const firstBlockDataEndIndex = firstBlockNum * numCommitmentsPerBlock; @@ -53,12 +54,12 @@ describe('Note Processor', () => { let usedOwnedNote = 0; for (let i = 0; i < TXS_PER_BLOCK; ++i) { const ownedDataIndices = ownedData[i] || []; - if (ownedDataIndices.some(index => index >= MAX_NEW_COMMITMENTS_PER_TX)) { - throw new Error(`Data index should be less than ${MAX_NEW_COMMITMENTS_PER_TX}.`); + if (ownedDataIndices.some(index => index >= MAX_NEW_NOTE_HASHES_PER_TX)) { + throw new Error(`Data index should be less than ${MAX_NEW_NOTE_HASHES_PER_TX}.`); } const logs: FunctionL2Logs[] = []; - for (let noteIndex = 0; noteIndex < MAX_NEW_COMMITMENTS_PER_TX; ++noteIndex) { + for (let noteIndex = 0; noteIndex < MAX_NEW_NOTE_HASHES_PER_TX; ++noteIndex) { const isOwner = ownedDataIndices.includes(noteIndex); const publicKey = isOwner ? owner.getPublicKey() : Point.random(); const note = (isOwner && ownedNotes[usedOwnedNote]) || L1NotePayload.random(); @@ -108,7 +109,10 @@ describe('Note Processor', () => { for (let i = 0; i < TXS_PER_BLOCK; i++) { block.body.txEffects[i].newNoteHashes = newNotes .map(n => computeMockNoteHash(n.note)) - .slice(i * MAX_NEW_COMMITMENTS_PER_TX, (i + 1) * MAX_NEW_COMMITMENTS_PER_TX); + .slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >; } const randomBlockContext = new L2BlockContext(block); @@ -183,17 +187,17 @@ describe('Note Processor', () => { expect.objectContaining({ ...ownedL1NotePayloads[0], // Index 1 log in the 2nd tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (2 - 1) + 1), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (2 - 1) + 1), }), expect.objectContaining({ ...ownedL1NotePayloads[1], // Index 0 log in the 4th tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 0), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (4 - 1) + 0), }), expect.objectContaining({ ...ownedL1NotePayloads[2], // Index 2 log in the 4th tx. - index: BigInt(thisBlockDataStartIndex + MAX_NEW_COMMITMENTS_PER_TX * (4 - 1) + 2), + index: BigInt(thisBlockDataStartIndex + MAX_NEW_NOTE_HASHES_PER_TX * (4 - 1) + 2), }), ]); }, 30_000); diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index 31ce051d2ac..b5f349278f1 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -7,7 +7,7 @@ import { L2BlockL2Logs, } from '@aztec/circuit-types'; import { NoteProcessorStats } from '@aztec/circuit-types/stats'; -import { MAX_NEW_COMMITMENTS_PER_TX, PublicKey } from '@aztec/circuits.js'; +import { MAX_NEW_NOTE_HASHES_PER_TX, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -123,8 +123,8 @@ export class NoteProcessor { for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) { this.stats.txs++; const dataStartIndexForTx = - dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_COMMITMENTS_PER_TX; - const newCommitments = block.body.txEffects[indexOfTxInABlock].newNoteHashes; + dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_NOTE_HASHES_PER_TX; + const newNoteHashes = block.body.txEffects[indexOfTxInABlock].newNoteHashes; // Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding // to the index of a tx in a block. const txFunctionLogs = txLogs[indexOfTxInABlock].functionLogs; @@ -142,7 +142,7 @@ export class NoteProcessor { this.publicKey, payload, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, excludedIndices, ); @@ -159,7 +159,7 @@ export class NoteProcessor { payload.storageSlot, payload.noteTypeId, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, ); deferredNoteDaos.push(deferredNoteDao); @@ -254,7 +254,7 @@ export class NoteProcessor { const excludedIndices: Set = new Set(); const noteDaos: NoteDao[] = []; for (const deferredNote of deferredNoteDaos) { - const { note, contractAddress, storageSlot, noteTypeId, txHash, newCommitments, dataStartIndexForTx } = + const { note, contractAddress, storageSlot, noteTypeId, txHash, newNoteHashes, dataStartIndexForTx } = deferredNote; const payload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId); @@ -264,7 +264,7 @@ export class NoteProcessor { this.publicKey, payload, txHash, - newCommitments, + newNoteHashes, dataStartIndexForTx, excludedIndices, ); diff --git a/yarn-project/pxe/src/note_processor/produce_note_dao.ts b/yarn-project/pxe/src/note_processor/produce_note_dao.ts index 23823c7d5fe..396012a4ee9 100644 --- a/yarn-project/pxe/src/note_processor/produce_note_dao.ts +++ b/yarn-project/pxe/src/note_processor/produce_note_dao.ts @@ -14,7 +14,7 @@ import { NoteDao } from '../database/note_dao.js'; * @param publicKey - The public counterpart to the private key to be used in note decryption. * @param payload - An instance of l1NotePayload. * @param txHash - The hash of the transaction that created the note. Equivalent to the first nullifier of the transaction. - * @param newCommitments - New commitments in this transaction, one of which belongs to this note. + * @param newNoteHashes - New note hashes in this transaction, one of which belongs to this note. * @param dataStartIndexForTx - The next available leaf index for the note hash tree for this transaction. * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same l1NotePayload, we need to find a different index for each replicate. * @param simulator - An instance of AcirSimulator. @@ -25,13 +25,13 @@ export async function produceNoteDao( publicKey: PublicKey, payload: L1NotePayload, txHash: TxHash, - newCommitments: Fr[], + newNoteHashes: Fr[], dataStartIndexForTx: number, excludedIndices: Set, ): Promise { const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier( simulator, - newCommitments, + newNoteHashes, txHash, payload, excludedIndices, diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index 926c989f68b..34619026f70 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -338,10 +338,10 @@ export class PXEService implements PXE { const nonces: Fr[] = []; const firstNullifier = tx.newNullifiers[0]; - const commitments = tx.newCommitments; - for (let i = 0; i < commitments.length; ++i) { - const commitment = commitments[i]; - if (commitment.equals(Fr.ZERO)) { + const hashes = tx.newNoteHashes; + for (let i = 0; i < hashes.length; ++i) { + const hash = hashes[i]; + if (hash.equals(Fr.ZERO)) { break; } @@ -355,11 +355,11 @@ export class PXEService implements PXE { ); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Remove this once notes added from public also include nonces. - if (commitment.equals(siloedNoteHash)) { + if (hash.equals(siloedNoteHash)) { nonces.push(Fr.ZERO); break; } - if (commitment.equals(uniqueSiloedNoteHash)) { + if (hash.equals(uniqueSiloedNoteHash)) { nonces.push(nonce); } } diff --git a/yarn-project/scripts/src/benchmarks/aggregate.ts b/yarn-project/scripts/src/benchmarks/aggregate.ts index 1b2235765d9..d3e027f3e6f 100644 --- a/yarn-project/scripts/src/benchmarks/aggregate.ts +++ b/yarn-project/scripts/src/benchmarks/aggregate.ts @@ -154,7 +154,7 @@ function processTxAddedToPool(entry: TxAddedToPoolStats, results: BenchmarkColle append(results, 'tx_size_in_bytes', entry.newContractCount, entry.size); } -/** Process entries for events tx-private-part-processed, grouped by new commitments */ +/** Process entries for events tx-private-part-processed, grouped by new note hashes */ function processTxPXEProcessingStats(entry: TxPXEProcessingStats, results: BenchmarkCollectedResults) { append(results, 'tx_pxe_processing_time_ms', entry.newCommitmentCount, entry.duration); } diff --git a/yarn-project/scripts/src/benchmarks/markdown.ts b/yarn-project/scripts/src/benchmarks/markdown.ts index 4db86e19e23..2fb3ddec168 100644 --- a/yarn-project/scripts/src/benchmarks/markdown.ts +++ b/yarn-project/scripts/src/benchmarks/markdown.ts @@ -243,7 +243,7 @@ Transaction sizes based on how many contracts are deployed in the tx. ${getTableContent(pick(benchmark, metricsByContractCount), baseBenchmark, 'deployed contracts')} Transaction processing duration by data writes. -${getTableContent(pick(benchmark, metricsTxPxeProcessing), baseBenchmark, 'new commitments')} +${getTableContent(pick(benchmark, metricsTxPxeProcessing), baseBenchmark, 'new note hashes')} ${getTableContent(pick(benchmark, metricsTxSeqProcessing), baseBenchmark, 'public data writes')} diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index 6196bc52879..8b52b4a3fd3 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -19,13 +19,16 @@ import { Fr, GlobalVariables, Header, + MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, @@ -55,7 +58,7 @@ import { import { makeTuple, range } from '@aztec/foundation/array'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { times } from '@aztec/foundation/collection'; -import { to2Fields } from '@aztec/foundation/serialize'; +import { Tuple, to2Fields } from '@aztec/foundation/serialize'; import { openTmpStore } from '@aztec/kv-store/utils'; import { MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; @@ -134,14 +137,14 @@ describe('sequencer/solo_block_builder', () => { return makeEmptyProcessedTxFromHistoricalTreeRoots(header, chainId, version); }; - // Updates the expectedDb trees based on the new commitments, contracts, and nullifiers from these txs + // Updates the expectedDb trees based on the new note hashes, contracts, and nullifiers from these txs const updateExpectedTreesFromTxs = async (txs: ProcessedTx[]) => { const newContracts = txs.flatMap(tx => tx.data.end.newContracts.map(cd => cd.hash())); for (const [tree, leaves] of [ [ MerkleTreeId.NOTE_HASH_TREE, txs.flatMap(tx => - [...tx.data.endNonRevertibleData.newCommitments, ...tx.data.end.newCommitments].map(l => l.value.toBuffer()), + [...tx.data.endNonRevertibleData.newNoteHashes, ...tx.data.end.newNoteHashes].map(l => l.value.toBuffer()), ), ], [MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer())], @@ -231,12 +234,23 @@ describe('sequencer/solo_block_builder', () => { const txEffects: TxEffect[] = txs.map( tx => new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value), - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value), + tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), - tx.data.combinedData.newContracts.map(cd => cd.hash()), - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)), + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple< + PublicDataWrite, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + >, + tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, + tx.data.combinedData.newContracts.map( + cd => new ContractData(cd.contractAddress, cd.portalContractAddress), + ) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), @@ -317,13 +331,13 @@ describe('sequencer/solo_block_builder', () => { const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple( - MAX_REVERTIBLE_COMMITMENTS_PER_TX, + processedTx.data.end.newNoteHashes = makeTuple( + MAX_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100, ); - processedTx.data.endNonRevertibleData.newCommitments = makeTuple( - MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + processedTx.data.endNonRevertibleData.newNoteHashes = makeTuple( + MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100, ); diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index 903b51a40d6..1d38330567d 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -10,6 +10,8 @@ import { GlobalVariables, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, + MAX_NEW_CONTRACTS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, @@ -103,13 +105,25 @@ export class SoloBlockBuilder implements BlockBuilder { // Collect all new nullifiers, commitments, and contracts from all txs in this block const txEffects: TxEffect[] = txs.map( tx => + // TODO(#4720): Combined data should most likely contain the tx effect directly new TxEffect( - tx.data.combinedData.newCommitments.map((c: SideEffect) => c.value), - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value), + tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value) as Tuple< + Fr, + typeof MAX_NEW_NOTE_HASHES_PER_TX + >, + tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value) as Tuple< + Fr, + typeof MAX_NEW_NULLIFIERS_PER_TX + >, tx.data.combinedData.newL2ToL1Msgs, - tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), - tx.data.combinedData.newContracts.map(cd => cd.hash()), - tx.data.combinedData.newContracts.map(cd => new ContractData(cd.contractAddress, cd.portalContractAddress)), + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)) as Tuple< + PublicDataWrite, + typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + >, + tx.data.combinedData.newContracts.map(cd => cd.hash()) as Tuple, + tx.data.combinedData.newContracts.map( + cd => new ContractData(cd.contractAddress, cd.portalContractAddress), + ) as Tuple, tx.encryptedLogs || new TxL2Logs([]), tx.unencryptedLogs || new TxL2Logs([]), ), @@ -603,14 +617,14 @@ export class SoloBlockBuilder implements BlockBuilder { // Update the contract and note hash trees with the new items being inserted to get the new roots // that will be used by the next iteration of the base rollup circuit, skipping the empty ones const newContracts = tx.data.combinedData.newContracts.map(cd => cd.hash()); - const newCommitments = tx.data.combinedData.newCommitments.map(x => x.value.toBuffer()); + const newNoteHashes = tx.data.combinedData.newNoteHashes.map(x => x.value.toBuffer()); await this.db.appendLeaves( MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer()), ); - await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newCommitments); + await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newNoteHashes); // The read witnesses for a given TX should be generated before the writes of the same TX are applied. // All reads that refer to writes in the same tx are transient and can be simplified out. diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index e3914d58263..980f5de1e8f 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -8,8 +8,8 @@ import { GlobalVariables, Header, L2ToL1Message, - MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, @@ -310,7 +310,7 @@ export abstract class AbstractPhaseManager { callContext: result.execution.callContext, proverAddress: AztecAddress.ZERO, argsHash: computeVarArgsHash(result.execution.args), - newCommitments: padArrayEnd(result.newCommitments, SideEffect.empty(), MAX_NEW_COMMITMENTS_PER_CALL), + newNoteHashes: padArrayEnd(result.newNoteHashes, SideEffect.empty(), MAX_NEW_NOTE_HASHES_PER_CALL), newNullifiers: padArrayEnd(result.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_NEW_NULLIFIERS_PER_CALL), newL2ToL1Msgs: padArrayEnd(result.newL2ToL1Messages, L2ToL1Message.empty(), MAX_NEW_L2_TO_L1_MSGS_PER_CALL), returnValues: padArrayEnd(result.returnValues, Fr.ZERO, RETURN_VALUES_LENGTH), diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index b9855e6e4ef..284da77cecf 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -374,7 +374,7 @@ function makePublicExecutionResultFromRequest(item: PublicCallRequest): PublicEx execution: item, nestedExecutions: [], returnValues: [new Fr(1n)], - newCommitments: [], + newNoteHashes: [], newL2ToL1Messages: [], newNullifiers: [], contractStorageReads: [], @@ -399,7 +399,7 @@ function makePublicExecutionResult( execution, nestedExecutions, returnValues: [], - newCommitments: [], + newNoteHashes: [], newNullifiers: [], newL2ToL1Messages: [], contractStorageReads: [], diff --git a/yarn-project/simulator/src/avm/temporary_executor_migration.ts b/yarn-project/simulator/src/avm/temporary_executor_migration.ts index db955dfe61d..ad66c6b9885 100644 --- a/yarn-project/simulator/src/avm/temporary_executor_migration.ts +++ b/yarn-project/simulator/src/avm/temporary_executor_migration.ts @@ -60,7 +60,7 @@ export function temporaryConvertAvmResults( newWorldState: JournalData, result: AvmContractCallResults, ): PublicExecutionResult { - const newCommitments = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); + const newNoteHashes = newWorldState.newNoteHashes.map(noteHash => new SideEffect(noteHash, Fr.zero())); const contractStorageReads: ContractStorageRead[] = []; const reduceStorageReadRequests = (contractAddress: bigint, storageReads: Map) => { @@ -97,7 +97,7 @@ export function temporaryConvertAvmResults( return { execution, - newCommitments, + newNoteHashes, newL2ToL1Messages, newNullifiers, contractStorageReads, diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index 3759622933f..d62b92aba68 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -19,7 +19,7 @@ import { TxContext, } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; -import { computePublicDataTreeLeafSlot, computeUniqueCommitment, siloCommitment } from '@aztec/circuits.js/hash'; +import { computePublicDataTreeLeafSlot, computeUniqueCommitment, siloNoteHash } from '@aztec/circuits.js/hash'; import { FunctionAbi, FunctionArtifact, countArgumentsSize } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; @@ -232,7 +232,7 @@ export class ClientExecutionContext extends ViewDataOracle { notes.forEach(n => { if (n.index !== undefined) { - const siloedNoteHash = siloCommitment(n.contractAddress, n.innerNoteHash); + const siloedNoteHash = siloNoteHash(n.contractAddress, n.innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(n.nonce, siloedNoteHash); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) // Should always be uniqueSiloedNoteHash when publicly created notes include nonces. @@ -309,7 +309,7 @@ export class ClientExecutionContext extends ViewDataOracle { #checkValidStaticCall(childExecutionResult: ExecutionResult) { if ( - childExecutionResult.callStackItem.publicInputs.newCommitments.some(item => !item.isEmpty()) || + childExecutionResult.callStackItem.publicInputs.newNoteHashes.some(item => !item.isEmpty()) || childExecutionResult.callStackItem.publicInputs.newNullifiers.some(item => !item.isEmpty()) || childExecutionResult.callStackItem.publicInputs.newL2ToL1Msgs.some(item => !item.isEmpty()) || !childExecutionResult.callStackItem.publicInputs.encryptedLogPreimagesLength.equals(new Fr(4)) || diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index a8e03dcdfc5..63d3b4d09e5 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -7,7 +7,7 @@ import { FunctionData, Header, L1_TO_L2_MSG_TREE_HEIGHT, - MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_NOTE_HASHES_PER_CALL, NOTE_HASH_TREE_HEIGHT, PartialStateReference, PublicCallRequest, @@ -24,7 +24,7 @@ import { computeCommitmentNonce, computeMessageSecretHash, computeVarArgsHash, - siloCommitment, + siloNoteHash, } from '@aztec/circuits.js/hash'; import { FunctionArtifact, @@ -232,8 +232,8 @@ describe('Private Execution test suite', () => { const txContext = { isContractDeploymentTx: true, contractDeploymentData }; const result = await runSimulator({ artifact, txContext }); - const emptyCommitments = new Array(MAX_NEW_COMMITMENTS_PER_CALL).fill(Fr.ZERO); - expect(sideEffectArrayToValueArray(result.callStackItem.publicInputs.newCommitments)).toEqual(emptyCommitments); + const emptyCommitments = new Array(MAX_NEW_NOTE_HASHES_PER_CALL).fill(Fr.ZERO); + expect(sideEffectArrayToValueArray(result.callStackItem.publicInputs.newNoteHashes)).toEqual(emptyCommitments); expect(result.callStackItem.publicInputs.contractDeploymentData).toEqual(contractDeploymentData); }); @@ -320,12 +320,12 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(new Fr(869710811710178111116101n)); // ValueNote - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const [commitment] = newCommitments; + const [commitment] = newNoteHashes; expect(commitment).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, @@ -346,12 +346,12 @@ describe('Private Execution test suite', () => { expect(newNote.storageSlot).toEqual(computeSlotForMapping(new Fr(1n), owner)); expect(newNote.noteTypeId).toEqual(new Fr(869710811710178111116101n)); // ValueNote - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const [commitment] = newCommitments; + const [commitment] = newNoteHashes; expect(commitment).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, @@ -394,12 +394,12 @@ describe('Private Execution test suite', () => { expect(recipientNote.storageSlot).toEqual(recipientStorageSlot); expect(recipientNote.noteTypeId).toEqual(noteTypeId); - const newCommitments = sideEffectArrayToValueArray(result.callStackItem.publicInputs.newCommitments).filter( + const newNoteHashes = sideEffectArrayToValueArray(result.callStackItem.publicInputs.newNoteHashes).filter( field => !field.equals(Fr.ZERO), ); - expect(newCommitments).toHaveLength(2); + expect(newNoteHashes).toHaveLength(2); - const [changeNoteCommitment, recipientNoteCommitment] = newCommitments; + const [changeNoteCommitment, recipientNoteCommitment] = newNoteHashes; expect(recipientNoteCommitment).toEqual( await acirSimulator.computeInnerNoteHash(contractAddress, recipientStorageSlot, noteTypeId, recipientNote.note), ); @@ -797,7 +797,7 @@ describe('Private Execution test suite', () => { const noteHash = hashFields(note.items); const storageSlot = new Fr(5); const innerNoteHash = hashFields([storageSlot, noteHash]); - const siloedNoteHash = siloCommitment(contractAddress, innerNoteHash); + const siloedNoteHash = siloNoteHash(contractAddress, innerNoteHash); oracle.getNotes.mockResolvedValue([ { contractAddress, @@ -893,7 +893,7 @@ describe('Private Execution test suite', () => { }); }); - describe('pending commitments contract', () => { + describe('pending note hashes contract', () => { beforeEach(() => { oracle.getCompleteAddress.mockImplementation((address: AztecAddress) => { if (address.equals(owner)) { @@ -912,7 +912,7 @@ describe('Private Execution test suite', () => { ); }); - it('should be able to insert, read, and nullify pending commitments in one call', async () => { + it('should be able to insert, read, and nullify pending note hashes in one call', async () => { oracle.getNotes.mockResolvedValue([]); const amountToTransfer = 100n; @@ -936,12 +936,12 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; + const noteHash = newNoteHashes[0]; const storageSlot = computeSlotForMapping(new Fr(1n), owner); const noteTypeId = new Fr(869710811710178111116101n); // ValueNote @@ -951,7 +951,7 @@ describe('Private Execution test suite', () => { noteTypeId, noteAndSlot.note, ); - expect(commitment).toEqual(innerNoteHash); + expect(noteHash).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) const readRequest = sideEffectArrayToValueArray(result.callStackItem.publicInputs.readRequests)[0]; @@ -973,7 +973,7 @@ describe('Private Execution test suite', () => { expect(nullifier.value).toEqual(expectedNullifier); }); - it('should be able to insert, read, and nullify pending commitments in nested calls', async () => { + it('should be able to insert, read, and nullify pending note hashes in nested calls', async () => { oracle.getNotes.mockResolvedValue([]); const amountToTransfer = 100n; @@ -1028,19 +1028,19 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(execInsert.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(execInsert.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; + const noteHash = newNoteHashes[0]; const innerNoteHash = await acirSimulator.computeInnerNoteHash( contractAddress, noteAndSlot.storageSlot, noteAndSlot.noteTypeId, noteAndSlot.note, ); - expect(commitment).toEqual(innerNoteHash); + expect(noteHash).toEqual(innerNoteHash); // read request should match innerNoteHash for pending notes (there is no nonce, so can't compute "unique" hash) const readRequest = execGetThenNullify.callStackItem.publicInputs.readRequests[0]; @@ -1092,13 +1092,13 @@ describe('Private Execution test suite', () => { expect(noteAndSlot.note.items[0]).toEqual(new Fr(amountToTransfer)); - const newCommitments = sideEffectArrayToValueArray( - nonEmptySideEffects(result.callStackItem.publicInputs.newCommitments), + const newNoteHashes = sideEffectArrayToValueArray( + nonEmptySideEffects(result.callStackItem.publicInputs.newNoteHashes), ); - expect(newCommitments).toHaveLength(1); + expect(newNoteHashes).toHaveLength(1); - const commitment = newCommitments[0]; - expect(commitment).toEqual( + const noteHash = newNoteHashes[0]; + expect(noteHash).toEqual( await acirSimulator.computeInnerNoteHash( contractAddress, storageSlot, diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index b8192633373..cff1858a008 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -1,6 +1,6 @@ import { AztecNode, Note } from '@aztec/circuit-types'; import { CompleteAddress } from '@aztec/circuits.js'; -import { computeUniqueCommitment, siloCommitment } from '@aztec/circuits.js/hash'; +import { computeUniqueCommitment, siloNoteHash } from '@aztec/circuits.js/hash'; import { ABIParameterVisibility, FunctionArtifactWithDebugMetadata, getFunctionArtifact } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { pedersenHash } from '@aztec/foundation/crypto'; @@ -52,7 +52,7 @@ describe('Simulator', () => { const note = createNote(); const tokenNoteHash = hashFields(note.items); const innerNoteHash = hashFields([storageSlot, tokenNoteHash]); - const siloedNoteHash = siloCommitment(contractAddress, innerNoteHash); + const siloedNoteHash = siloNoteHash(contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(nonce, siloedNoteHash); const innerNullifier = hashFields([ uniqueSiloedNoteHash, diff --git a/yarn-project/simulator/src/public/execution.ts b/yarn-project/simulator/src/public/execution.ts index 419c7d3a1be..6d6bca3ee1c 100644 --- a/yarn-project/simulator/src/public/execution.ts +++ b/yarn-project/simulator/src/public/execution.ts @@ -22,8 +22,8 @@ export interface PublicExecutionResult { execution: PublicExecution; /** The return values of the function. */ returnValues: Fr[]; - /** The new commitments to be inserted into the commitments tree. */ - newCommitments: SideEffect[]; + /** The new note hashes to be inserted into the note hashes tree. */ + newNoteHashes: SideEffect[]; /** The new l2 to l1 messages generated in this call. */ newL2ToL1Messages: L2ToL1Message[]; /** The new nullifiers to be inserted into the nullifier tree. */ @@ -143,7 +143,7 @@ function contractStorageUpdateRequestToPublicDataUpdateRequest( */ export function checkValidStaticCall( - newCommitments: SideEffect[], + newNoteHashes: SideEffect[], newNullifiers: SideEffectLinkedToNoteHash[], contractStorageUpdateRequests: ContractStorageUpdateRequest[], newL2ToL1Messages: L2ToL1Message[], @@ -151,7 +151,7 @@ export function checkValidStaticCall( ) { if ( contractStorageUpdateRequests.length > 0 || - newCommitments.length > 0 || + newNoteHashes.length > 0 || newNullifiers.length > 0 || newL2ToL1Messages.length > 0 || unencryptedLogs.logs.length > 0 diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index e59feed7444..087c7372bc8 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -52,12 +52,12 @@ export async function executePublicFunction( const { returnValues, newL2ToL1Msgs, - newCommitments: newCommitmentsPadded, + newNoteHashes: newNoteHashesPadded, newNullifiers: newNullifiersPadded, } = PublicCircuitPublicInputs.fromFields(returnWitness); const newL2ToL1Messages = newL2ToL1Msgs.filter(v => !v.isEmpty()); - const newCommitments = newCommitmentsPadded.filter(v => !v.isEmpty()); + const newNoteHashes = newNoteHashesPadded.filter(v => !v.isEmpty()); const newNullifiers = newNullifiersPadded.filter(v => !v.isEmpty()); const { contractStorageReads, contractStorageUpdateRequests } = context.getStorageActionData(); @@ -72,7 +72,7 @@ export async function executePublicFunction( return { execution, - newCommitments, + newNoteHashes, newL2ToL1Messages, newNullifiers, contractStorageReads, @@ -134,7 +134,7 @@ export class PublicExecutor { if (executionResult.execution.callContext.isStaticCall) { checkValidStaticCall( - executionResult.newCommitments, + executionResult.newNoteHashes, executionResult.newNullifiers, executionResult.contractStorageUpdateRequests, executionResult.newL2ToL1Messages, diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index 7171d3656de..9070b0e1938 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -302,7 +302,7 @@ describe('ACIR public execution simulator', () => { params = [amount, new Fr(1)]; }); - it('Should be able to create a commitment from the public context', async () => { + it('Should be able to create a note hash from the public context', async () => { const shieldArtifact = TokenContractArtifact.functions.find(f => f.name === 'shield')!; const msgSender = AztecAddress.random(); const secretHash = Fr.random(); @@ -327,13 +327,13 @@ describe('ACIR public execution simulator', () => { const execution: PublicExecution = { contractAddress, functionData, args, callContext }; const result = await executor.simulate(execution, GlobalVariables.empty()); - // Assert the commitment was created - expect(result.newCommitments.length).toEqual(1); + // Assert the note hash was created + expect(result.newNoteHashes.length).toEqual(1); const expectedNoteHash = pedersenHash([amount.toBuffer(), secretHash.toBuffer()]); const storageSlot = new Fr(5); // for pending_shields const expectedInnerNoteHash = pedersenHash([storageSlot, expectedNoteHash].map(f => f.toBuffer())); - expect(result.newCommitments[0].value).toEqual(expectedInnerNoteHash); + expect(result.newNoteHashes[0].value).toEqual(expectedInnerNoteHash); }); it('Should be able to create a L2 to L1 message from the public context', async () => { diff --git a/yarn-project/simulator/src/public/public_execution_context.ts b/yarn-project/simulator/src/public/public_execution_context.ts index 434a02be59c..1e48202703c 100644 --- a/yarn-project/simulator/src/public/public_execution_context.ts +++ b/yarn-project/simulator/src/public/public_execution_context.ts @@ -213,7 +213,7 @@ export class PublicExecutionContext extends TypedOracle { if (isStaticCall) { checkValidStaticCall( - childExecutionResult.newCommitments, + childExecutionResult.newNoteHashes, childExecutionResult.newNullifiers, childExecutionResult.contractStorageUpdateRequests, childExecutionResult.newL2ToL1Messages, diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index 3c25882bfed..783523d6808 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -13,7 +13,7 @@ import { WorldStateRunningState, WorldStateStatus, WorldStateSynchronizer } from /** * Synchronizes the world state with the L2 blocks from a L2BlockSource. - * The synchronizer will download the L2 blocks from the L2BlockSource and insert the new commitments into the merkle + * The synchronizer will download the L2 blocks from the L2BlockSource and insert the new note hashes into the merkle * tree. */ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { @@ -171,7 +171,7 @@ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { } /** - * Handles a list of L2 blocks (i.e. Inserts the new commitments into the merkle tree). + * Handles a list of L2 blocks (i.e. Inserts the new note hashes into the merkle tree). * @param l2Blocks - The L2 blocks to handle. * @returns Whether the block handled was produced by this same node. */ @@ -188,7 +188,7 @@ export class ServerWorldStateSynchronizer implements WorldStateSynchronizer { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param l2Block - The L2 block to handle. */ private async handleL2Block(l2Block: L2Block): Promise { diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts index 560906b4d69..4beda52eed7 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations.ts @@ -138,7 +138,7 @@ export interface MerkleTreeOperations { ): Promise>; /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. */ handleL2Block(block: L2Block): Promise; diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts index 26c3cceb896..446a2c501da 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_operations_facade.ts @@ -141,7 +141,7 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. * @returns Whether the block handled was produced by this same node. */ diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index 29c98b8b805..4d72a6035e7 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -352,7 +352,7 @@ export class MerkleTrees implements MerkleTreeDb { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param block - The L2 block to handle. * @returns Whether the block handled was produced by this same node. */ @@ -483,7 +483,7 @@ export class MerkleTrees implements MerkleTreeDb { } /** - * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). + * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree). * @param l2Block - The L2 block to handle. */ async #handleL2Block(l2Block: L2Block): Promise { diff --git a/yellow-paper/docs/calls/public-private-messaging.md b/yellow-paper/docs/calls/public-private-messaging.md index b75cc6f622d..9d8e164625c 100644 --- a/yellow-paper/docs/calls/public-private-messaging.md +++ b/yellow-paper/docs/calls/public-private-messaging.md @@ -79,6 +79,6 @@ Since public functions execute after private functions, it isn't possible for a To elaborate, a public function may not have read access to encrypted private state in the Note Hash Tree, but it can write to it. You could create a note in the public domain, compute its note hash which gets passed to the inputs of the public VM which adds the hash to the note hash tree. The user who wants to redeem the note can add the note preimage to their PXE and then redeem/nullify the note in the private domain at a later time. -In the picture below, it is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new commitments, potentially as part of transferring funds from the public domain to the private domain). +In the picture below, it is worth noting that all data reads performed by private functions are historical in nature, and that private functions are not capable of modifying public storage. Conversely, public functions have the capacity to manipulate private storage (e.g., inserting new note hashes, potentially as part of transferring funds from the public domain to the private domain). ![Public - Private Messaging](./images/calls/pub_pvt_messaging.png) diff --git a/yellow-paper/docs/calls/static-calls.md b/yellow-paper/docs/calls/static-calls.md index 61756cfb413..cb1b2c789c6 100644 --- a/yellow-paper/docs/calls/static-calls.md +++ b/yellow-paper/docs/calls/static-calls.md @@ -13,7 +13,7 @@ I think the options are: Thoughts? Ethereum does the latter. We should write about whichever we choose in this page. --> -- `new_commitments` +- `new_note_hashes` - `new_nullifiers` - `nullified_commitments` - `new_l2_to_l1_msgs` diff --git a/yellow-paper/docs/constants.md b/yellow-paper/docs/constants.md index 496eb93b1c5..1106acd4aa3 100644 --- a/yellow-paper/docs/constants.md +++ b/yellow-paper/docs/constants.md @@ -41,7 +41,7 @@ The statically-sized nature the kernel & rollup circuits will restrict the quant | Name | Value | Description | |---|---|---| -| `MAX_NEW_COMMITMENTS_PER_CALL` | 128 | +| `MAX_NEW_NOTE_HASHES_PER_CALL` | 128 | | `MAX_NEW_NULLIFIERS_PER_CALL` | 128 | | `MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL` | 32 | | `MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL` | 32 | @@ -56,7 +56,7 @@ The statically-sized nature the kernel & rollup circuits will restrict the quant | Name | Value | Description | |---|---|---| -| `MAX_NEW_COMMITMENTS_PER_TX` | 128 | +| `MAX_NEW_NOTE_HASHES_PER_TX` | 128 | | `MAX_NEW_NULLIFIERS_PER_TX` | 128 | | `MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX` | 32 | | `MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX` | 32 | diff --git a/yellow-paper/docs/data-publication-and-availability/index.md b/yellow-paper/docs/data-publication-and-availability/index.md index 4e5aed122a5..fc601823a9b 100644 --- a/yellow-paper/docs/data-publication-and-availability/index.md +++ b/yellow-paper/docs/data-publication-and-availability/index.md @@ -182,7 +182,7 @@ Someone: 787 bytes Total: 1098 bytes ``` -For a more liberal estimation, lets suppose we emit 4 nullifiers, 4 new commitments, and 4 public data writes instead per transaction. +For a more liberal estimation, lets suppose we emit 4 nullifiers, 4 new note hashes, and 4 public data writes instead per transaction. ```python Tx ((512, 1036) bytes): comms=4, nulls=4, pubs=4, l2_to_l1=0, e_logs=988, u_logs=48 diff --git a/yellow-paper/docs/state/note-hash-tree.md b/yellow-paper/docs/state/note-hash-tree.md index 78bab7bb6e3..788b02363ae 100644 --- a/yellow-paper/docs/state/note-hash-tree.md +++ b/yellow-paper/docs/state/note-hash-tree.md @@ -4,22 +4,22 @@ The Note Hash tree is an [append-only Merkle tree](./tree-implementations.md#app Note commitments are immutable once created. Still, notes can be consumed ("read") by functions. To preserve privacy, a consumed note is not removed from the tree, otherwise it would be possible to link the transaction that created a note with the one that consumed it. Instead, a note is consumed by emitting a deterministic [nullifier](./nullifier-tree.md). -Contracts emit new note commitments via the `new_commitments` in the `CircuitPublicInputs` , which are subsequently [siloed](./tree-implementations.md#siloing-leaves) by contract address by the Kernel circuit. Siloing the commitment ensures that a malicious contract cannot create notes for (that is, modify the state of) another contract. +Contracts emit new note commitments via the `new_note_hashes` in the `CircuitPublicInputs` , which are subsequently [siloed](./tree-implementations.md#siloing-leaves) by contract address by the Kernel circuit. Siloing the commitment ensures that a malicious contract cannot create notes for (that is, modify the state of) another contract. The Kernel circuit also guarantees uniqueness of commitments by further hashing them with a nonce, derived from the transaction identifier and the index of the commitment within the transaction's array of newly-created note hashes. Uniqueness means that a note with the same contents can be emitted more than once, and each instance can be independently nullified. Without uniqueness, two notes with the same content would yield the same commitment and nullifier, so nullifying one of them would render the second one as nullified as well. The pseudocode for siloing and making a commitment unique is the following, where each `hash` operation is a Pedersen hash with a unique generator index, indicated by the constant in all caps. ``` -fn compute_unique_siloed_commitment(commitment, contract, transaction): - let siloed_commitment = hash([contract, commitment], SILOED_COMMITMENT) +fn compute_unique_siloed_note_hash(commitment, contract, transaction): + let siloed_note_hash = hash([contract, commitment], SILOED_NOTE_HASH) let index = index_of(commitment, transaction.commitments) - let nonce = hash([transaction.tx_hash, index], COMMITMENT_NONCE) - return hash([nonce, siloed_commitment], UNIQUE_COMMITMENT) + let nonce = hash([transaction.tx_hash, index], NOTE_HASH_NONCE) + return hash([nonce, siloed_note_hash], UNIQUE_NOTE_HASH) ``` The unique siloed commitment of a note is included in the [transaction `data`](../transactions/tx-object.md), and then inserted into the Note Hash tree by the sequencer as the transaction is included in a block. The protocol does not enforce any constraints on any note hashes emitted by an application. This means that applications are responsible for including a `randomness` field in the note hash to make the commitment _hiding_ in addition to _binding_. If an application does not include randomness, and the note preimage can be guessed by an attacker, it makes the note vulnerable to preimage attacks, since the siloing and uniqueness steps do not provide hiding. -Furthermore, since there are no constraints to the commitment emitted by an application, an application can emit any value whatsoever as a `new_commitment`, including values that do not map to a note hash. +Furthermore, since there are no constraints to the commitment emitted by an application, an application can emit any value whatsoever as a `new_note_hash`, including values that do not map to a note hash. diff --git a/yellow-paper/docs/transactions/tx-object.md b/yellow-paper/docs/transactions/tx-object.md index 29c6c9d33a6..c269239cad0 100644 --- a/yellow-paper/docs/transactions/tx-object.md +++ b/yellow-paper/docs/transactions/tx-object.md @@ -42,9 +42,9 @@ Output of the last iteration of the private kernel circuit. Includes _accumulate | Field | Type | Description | |-------|------|-------------| | aggregationObject | AggregationObject | Aggregated proof of all the previous kernel iterations. | -| newCommitments | Field[] | The new commitments made in this transaction. | +| newNoteHashes | Field[] | The new note hashes made in this transaction. | | newNullifiers | Field[] | The new nullifiers made in this transaction. | -| nullifiedCommitments | Field[] | The commitments which are nullified by a nullifier in the above list. | +| nullifiedNoteHashes | Field[] | The note hashes which are nullified by a nullifier in the above list. | | privateCallStack | Field[] | Current private call stack. | | publicCallStack | Field[] | Current public call stack. | | newL2ToL1Msgs | Field[] | All the new L2 to L1 messages created in this transaction. |