From b7fa30212ba5543d51d5883c10a8146d73a1687e Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Thu, 4 Jan 2024 22:00:25 +0100 Subject: [PATCH] chore: use traits in noir-protocol-circuits (#3832) Simple use of traits in `noir-protocol-circuits` and `aztec-nr` when possible. Missing: Serialize/Deserialize due to: https://github.com/noir-lang/noir/issues/3471 Renamed ::default() to ::empty(), since it better conveys meaning for our use cases (open to discussion). --- .../aztec-nr/aztec/src/note/note_header.nr | 11 ++- .../aztec-nr/safe-math/src/safe_u120.nr | 18 +++-- .../crates/private-kernel-lib/src/common.nr | 2 +- .../crates/public-kernel-lib/src/common.nr | 2 +- .../src/abis/append_only_tree_snapshot.nr | 6 +- .../src/abis/constant_rollup_data.nr | 5 +- .../rollup-lib/src/abis/global_variables.nr | 21 ++--- .../src/abis/public_data_tree_leaf.nr | 37 ++++++--- .../rollup-lib/src/base/base_rollup_inputs.nr | 8 +- .../src/crates/types/src/abis/block_header.nr | 11 ++- .../src/crates/types/src/abis/call_context.nr | 38 +++++---- .../src/crates/types/src/abis/call_request.nr | 48 ++++++----- .../crates/types/src/abis/call_stack_item.nr | 7 +- .../types/src/abis/function_leaf_preimage.nr | 3 +- .../types/src/abis/function_selector.nr | 11 ++- .../types/src/abis/new_contract_data.nr | 33 +++++--- .../types/src/abis/nullifier_leaf_preimage.nr | 20 +++-- .../src/abis/private_circuit_public_inputs.nr | 7 +- .../crates/types/src/abis/public_data_read.nr | 30 ++++--- .../src/abis/public_data_update_request.nr | 24 ++++-- .../src/crates/types/src/abis/side_effect.nr | 79 +++++++++++-------- .../src/crates/types/src/address.nr | 46 ++++++----- .../types/src/contrakt/deployment_data.nr | 10 ++- .../crates/types/src/contrakt/storage_read.nr | 8 +- .../src/contrakt/storage_update_request.nr | 34 +++++--- .../src/crates/types/src/lib.nr | 1 + .../src/crates/types/src/traits.nr | 8 ++ .../crates/types/src/transaction/context.nr | 3 +- .../crates/types/src/transaction/request.nr | 3 +- 29 files changed, 335 insertions(+), 199 deletions(-) create mode 100644 yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr diff --git a/yarn-project/aztec-nr/aztec/src/note/note_header.nr b/yarn-project/aztec-nr/aztec/src/note/note_header.nr index 306e92a4704..b807deea79a 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_header.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_header.nr @@ -1,4 +1,5 @@ use dep::protocol_types::address::AztecAddress; +use dep::protocol_types::traits::Empty; struct NoteHeader { contract_address: AztecAddress, @@ -9,12 +10,14 @@ struct NoteHeader { is_transient: bool, } +impl Empty for NoteHeader { + fn empty() -> Self { + NoteHeader { contract_address: AztecAddress::zero(), nonce: 0, storage_slot: 0, is_transient: false } + } +} + impl NoteHeader { pub fn new(contract_address: AztecAddress, nonce: Field, storage_slot: Field) -> Self { NoteHeader { contract_address, nonce, storage_slot, is_transient: false } } - - pub fn empty() -> Self { - NoteHeader { contract_address: AztecAddress::zero(), nonce: 0, storage_slot: 0, is_transient: false } - } } diff --git a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr index 8412f45a43a..a7051457ce6 100644 --- a/yarn-project/aztec-nr/safe-math/src/safe_u120.nr +++ b/yarn-project/aztec-nr/safe-math/src/safe_u120.nr @@ -1,7 +1,18 @@ +use dep::std::ops::Eq; + struct SafeU120 { value: u120, } +impl Eq for SafeU120 { + fn eq( + self: Self, + other: Self + ) -> bool { + self.value == other.value + } +} + impl SafeU120 { pub fn min() -> Self { Self { @@ -34,13 +45,6 @@ impl SafeU120 { self.value == 0 } - pub fn eq( - self: Self, - other: Self - ) -> bool { - self.value == other.value - } - pub fn lt(self: Self, other: Self) -> bool { self.value < other.value } diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index ef676202151..069a232fd53 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -130,7 +130,7 @@ pub fn initialize_end_values( public_inputs.end.unencrypted_log_preimages_length = start.unencrypted_log_preimages_length; public_inputs.end.optionally_revealed_data = start.optionally_revealed_data; - public_inputs.end.new_contracts = struct_array_to_bounded_vec(start.new_contracts, |ncd: NewContractData| ncd.is_empty(), NewContractData::default()); + public_inputs.end.new_contracts = struct_array_to_bounded_vec(start.new_contracts, |ncd: NewContractData| ncd.is_empty(), NewContractData::empty()); } fn perform_static_call_checks(private_call: PrivateCallData) { diff --git a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr index f80543eacf0..115079acd9a 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr @@ -82,7 +82,7 @@ pub fn initialize_end_values( circuit_outputs.end.encrypted_logs_hash = start.encrypted_logs_hash; circuit_outputs.end.encrypted_log_preimages_length = start.encrypted_log_preimages_length; - circuit_outputs.end.new_contracts = struct_array_to_bounded_vec(previous_kernel.public_inputs.end.new_contracts, |ncd: NewContractData| ncd.is_empty(), NewContractData::default()); + circuit_outputs.end.new_contracts = struct_array_to_bounded_vec(previous_kernel.public_inputs.end.new_contracts, |ncd: NewContractData| ncd.is_empty(), NewContractData::empty()); } fn perform_static_call_checks(public_call: PublicCallData) { diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/append_only_tree_snapshot.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/append_only_tree_snapshot.nr index 9b0456ab60e..4856f446520 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/append_only_tree_snapshot.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/append_only_tree_snapshot.nr @@ -1,10 +1,12 @@ +use dep::std::ops::Eq; + struct AppendOnlyTreeSnapshot { root : Field, next_available_leaf_index : u32 } -impl AppendOnlyTreeSnapshot{ - pub fn eq(self, other : AppendOnlyTreeSnapshot) -> bool { +impl Eq for AppendOnlyTreeSnapshot { + fn eq(self, other : AppendOnlyTreeSnapshot) -> bool { (self.root == other.root) & (self.next_available_leaf_index == other.next_available_leaf_index) } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr index 1871a0ec1ff..8df873f0a3b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr @@ -1,5 +1,6 @@ use crate::abis::global_variables::GlobalVariables; use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot; +use dep::std::ops::Eq; struct ConstantRollupData { // The very latest roots as at the very beginning of the entire rollup: @@ -14,8 +15,8 @@ struct ConstantRollupData { global_variables : GlobalVariables, } -impl ConstantRollupData { - pub fn eq(self, other : ConstantRollupData) -> bool { +impl Eq for ConstantRollupData { + fn eq(self, other : ConstantRollupData) -> bool { self.archive_snapshot.eq(other.archive_snapshot) & self.global_variables.eq(other.global_variables) & (self.private_kernel_vk_tree_root == other.private_kernel_vk_tree_root) & diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/global_variables.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/global_variables.nr index ce4abc63541..d3a92124c2f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/global_variables.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/global_variables.nr @@ -1,4 +1,6 @@ use dep::types::constants::GENERATOR_INDEX__GLOBAL_VARIABLES; +use dep::std::ops::Eq; +use dep::types::traits::Hash; struct GlobalVariables { chain_id : Field, @@ -7,9 +9,17 @@ struct GlobalVariables { timestamp : Field, } -impl GlobalVariables { +impl Eq for GlobalVariables { + fn eq(self, other : GlobalVariables) -> bool { + (self.chain_id == other.chain_id) & + (self.version == other.version) & + (self.block_number == other.block_number) & + (self.timestamp == other.timestamp) + } +} - pub fn hash(self) -> Field { +impl Hash for GlobalVariables { + fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.chain_id, self.version, @@ -19,11 +29,4 @@ impl GlobalVariables { GENERATOR_INDEX__GLOBAL_VARIABLES, ) } - - pub fn eq(self, other : GlobalVariables) -> bool { - (self.chain_id == other.chain_id) & - (self.version == other.version) & - (self.block_number == other.block_number) & - (self.timestamp == other.timestamp) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/public_data_tree_leaf.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/public_data_tree_leaf.nr index 05deed5b395..e820f172175 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/public_data_tree_leaf.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/public_data_tree_leaf.nr @@ -1,3 +1,6 @@ +use dep::std::ops::Eq; +use dep::types::traits::{Empty, Hash}; + struct PublicDataTreeLeafPreimage { slot : Field, value: Field, @@ -5,8 +8,8 @@ struct PublicDataTreeLeafPreimage { next_index : u32, } -impl PublicDataTreeLeafPreimage { - pub fn default() -> Self { +impl Empty for PublicDataTreeLeafPreimage { + fn empty() -> Self { Self { slot: 0, value: 0, @@ -14,12 +17,10 @@ impl PublicDataTreeLeafPreimage { next_index: 0, } } +} - pub fn is_empty(self) -> bool { - (self.slot == 0) & (self.value == 0) & (self.next_slot == 0) & (self.next_index == 0) - } - - pub fn hash(self) -> Field { +impl Hash for PublicDataTreeLeafPreimage { + fn hash(self) -> Field { if self.is_empty() { 0 } else { @@ -28,24 +29,34 @@ impl PublicDataTreeLeafPreimage { } } +impl PublicDataTreeLeafPreimage { + pub fn is_empty(self) -> bool { + (self.slot == 0) & (self.value == 0) & (self.next_slot == 0) & (self.next_index == 0) + } +} + struct PublicDataTreeLeaf { slot: Field, value: Field, } -impl PublicDataTreeLeaf { - pub fn default() -> Self { +impl Eq for PublicDataTreeLeaf { + fn eq(self, other: Self) -> bool { + (self.slot == other.slot) & (self.value == other.value) + } +} + +impl Empty for PublicDataTreeLeaf { + fn empty() -> Self { Self { slot: 0, value: 0, } } +} +impl PublicDataTreeLeaf { pub fn is_empty(self) -> bool { (self.slot == 0) & (self.value == 0) } - - pub fn eq(self, other: Self) -> bool { - (self.slot == other.slot) & (self.value == other.value) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 8bb89362048..afbb0e7a448 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -438,7 +438,7 @@ fn insert_public_data_update_requests( |write: PublicDataTreeLeaf, low_preimage: PublicDataTreeLeafPreimage| { // Build insertion leaf let is_update = low_preimage.slot == write.slot; if is_update { - PublicDataTreeLeafPreimage::default() + PublicDataTreeLeafPreimage::empty() }else { PublicDataTreeLeafPreimage { slot: write.slot, @@ -706,7 +706,7 @@ mod tests { ); } } else { - sorted_public_data_writes[i] = PublicDataTreeLeaf::default(); + sorted_public_data_writes[i] = PublicDataTreeLeaf::empty(); sorted_public_data_writes_indexes[i] = i as u32; } } @@ -1089,7 +1089,7 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { existing_index: 0, value: 1 }); - let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_TX * 2]; + let mut tree_nullifiers = [NullifierLeafPreimage::empty(); MAX_NEW_NULLIFIERS_PER_TX * 2]; tree_nullifiers[0] = NullifierLeafPreimage { nullifier : 0, next_nullifier : 1, @@ -1139,7 +1139,7 @@ mod tests { } let output = builder.execute(); - let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_TX * 2]; + let mut tree_nullifiers = [NullifierLeafPreimage::empty(); MAX_NEW_NULLIFIERS_PER_TX * 2]; tree_nullifiers[0] = builder.pre_existing_nullifiers[0]; tree_nullifiers[1] = NullifierLeafPreimage { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index 78218b09f3f..a850ff4814d 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -5,6 +5,7 @@ use crate::{ }, hash::pedersen_hash, }; +use crate::traits::Empty; // docs:start:block-header struct BlockHeader { @@ -18,6 +19,12 @@ struct BlockHeader { } // docs:end:block-header +impl Empty for BlockHeader { + fn empty() -> Self { + BlockHeader::deserialize([0; BLOCK_HEADER_LENGTH]) + } +} + impl BlockHeader { pub fn assert_is_zero(self) { assert(self.note_hash_tree_root == 0); @@ -77,8 +84,4 @@ impl BlockHeader { self.public_data_tree_root, ], GENERATOR_INDEX__BLOCK_HASH) } - - pub fn empty() -> Self { - BlockHeader::deserialize([0; BLOCK_HEADER_LENGTH]) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr index 241d2b08e31..668dd8fce90 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr @@ -7,6 +7,8 @@ use crate::{ }, hash::pedersen_hash, }; +use dep::std::ops::Eq; +use crate::traits::Hash; // docs:start:call-context struct CallContext { @@ -24,6 +26,26 @@ struct CallContext { } // docs:end:call-context +impl Eq for CallContext { + fn eq(self, call_context: CallContext) -> bool { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) + call_context.msg_sender.eq(self.msg_sender) + & call_context.storage_contract_address.eq(self.storage_contract_address) + & call_context.portal_contract_address.eq(self.portal_contract_address) + & call_context.function_selector.eq(self.function_selector) + & (call_context.is_delegate_call == self.is_delegate_call) + & (call_context.is_static_call == self.is_static_call) + & (call_context.is_contract_deployment == self.is_contract_deployment) + & (call_context.start_side_effect_counter == self.start_side_effect_counter) + } +} + +impl Hash for CallContext { + fn hash(self) -> Field { + pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT) + } +} + impl CallContext { fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] { [ @@ -38,10 +60,6 @@ impl CallContext { ] } - fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT) - } - fn assert_is_zero(self) { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) assert(self.msg_sender.to_field() == 0); @@ -53,16 +71,4 @@ impl CallContext { assert(self.is_contract_deployment == false); assert(self.start_side_effect_counter == 0); } - - fn eq(self, call_context: CallContext) -> bool { - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) - call_context.msg_sender.eq(self.msg_sender) - & call_context.storage_contract_address.eq(self.storage_contract_address) - & call_context.portal_contract_address.eq(self.portal_contract_address) - & call_context.function_selector.eq(self.function_selector) - & (call_context.is_delegate_call == self.is_delegate_call) - & (call_context.is_static_call == self.is_static_call) - & (call_context.is_contract_deployment == self.is_contract_deployment) - & (call_context.start_side_effect_counter == self.start_side_effect_counter) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr index c66972a5319..da97e8b6207 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr @@ -1,26 +1,32 @@ use crate::address::AztecAddress; +use dep::std::ops::Eq; +use crate::traits::Empty; struct CallerContext { msg_sender: AztecAddress, storage_contract_address: AztecAddress, } -impl CallerContext { - pub fn empty() -> Self { +impl Eq for CallerContext { + fn eq(self, caller_context: CallerContext) -> bool { + caller_context.msg_sender.eq(self.msg_sender) + & caller_context.storage_contract_address.eq(self.storage_contract_address) + } +} + +impl Empty for CallerContext { + fn empty() -> Self { CallerContext { msg_sender: AztecAddress::zero(), storage_contract_address: AztecAddress::zero(), } } +} +impl CallerContext { pub fn is_empty(self) -> bool { self.msg_sender.is_zero() & self.storage_contract_address.is_zero() } - - pub fn eq(self, caller_context: CallerContext) -> bool { - caller_context.msg_sender.eq(self.msg_sender) - & caller_context.storage_contract_address.eq(self.storage_contract_address) - } } struct CallRequest { @@ -31,26 +37,30 @@ struct CallRequest { end_side_effect_counter: Field, } -impl CallRequest { - pub fn empty() -> Self { - Self { +impl Eq for CallRequest { + fn eq(self, call_request: CallRequest) -> bool { + (call_request.hash == self.hash) + & (call_request.caller_contract_address.eq(self.caller_contract_address)) + & (call_request.caller_context.eq(self.caller_context)) + & (call_request.start_side_effect_counter == self.start_side_effect_counter) + & (call_request.end_side_effect_counter == self.end_side_effect_counter) + } +} + +impl Empty for CallRequest { + fn empty() -> Self { + CallRequest { hash: 0, caller_contract_address: AztecAddress::zero(), - caller_context: dep::std::unsafe::zeroed(), + caller_context: CallerContext::empty(), start_side_effect_counter: 0, end_side_effect_counter: 0, } } +} +impl CallRequest { pub fn is_empty(self) -> bool { self.hash == 0 } - - pub fn eq(self, call_request: CallRequest) -> bool { - (call_request.hash == self.hash) - & (call_request.caller_contract_address.eq(self.caller_contract_address)) - & (call_request.caller_context.eq(self.caller_context)) - & (call_request.start_side_effect_counter == self.start_side_effect_counter) - & (call_request.end_side_effect_counter == self.end_side_effect_counter) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr index 94aa0dce532..45ebceaf010 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr @@ -7,6 +7,7 @@ use crate::address::AztecAddress; use crate::constants::{ GENERATOR_INDEX__CALL_STACK_ITEM, }; +use crate::traits::Hash; struct PrivateCallStackItem { // This is the _actual_ contract address relating to where this function's code resides in the @@ -21,7 +22,7 @@ struct PrivateCallStackItem { is_execution_request: bool, } -impl PrivateCallStackItem { +impl Hash for PrivateCallStackItem { fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.contract_address.to_field(), @@ -40,7 +41,7 @@ struct PublicCallStackItem { is_execution_request: bool, } -impl PublicCallStackItem { +impl Hash for PublicCallStackItem { fn hash(self) -> Field { let item = if self.is_execution_request { self.as_execution_request() @@ -54,7 +55,9 @@ impl PublicCallStackItem { item.public_inputs.hash(), ], GENERATOR_INDEX__CALL_STACK_ITEM) } +} +impl PublicCallStackItem { fn as_execution_request(self) -> Self { let public_inputs = self.public_inputs; let mut request_public_inputs: PublicCircuitPublicInputs = dep::std::unsafe::zeroed(); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_leaf_preimage.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_leaf_preimage.nr index 2a66a161736..fecfae27bd9 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_leaf_preimage.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_leaf_preimage.nr @@ -1,5 +1,6 @@ use crate::abis::function_selector::FunctionSelector; use crate::constants::GENERATOR_INDEX__FUNCTION_LEAF; +use crate::traits::Hash; struct FunctionLeafPreimage { selector : FunctionSelector, @@ -9,7 +10,7 @@ struct FunctionLeafPreimage { acir_hash : Field } -impl FunctionLeafPreimage { +impl Hash for FunctionLeafPreimage { fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.selector.to_field(), diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index d166bbdf3f6..d076cc09bf8 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -1,4 +1,5 @@ use crate::utils::field::field_from_bytes; +use dep::std::ops::Eq; global SELECTOR_SIZE = 4; @@ -7,6 +8,12 @@ struct FunctionSelector { inner: u32, } +impl Eq for FunctionSelector { + fn eq(self, function_selector: FunctionSelector) -> bool { + function_selector.inner == self.inner + } +} + impl FunctionSelector { fn to_field(self) -> Field { self.inner as Field @@ -40,10 +47,6 @@ impl FunctionSelector { Self { inner: 0 } } - pub fn eq(self, function_selector: FunctionSelector) -> bool { - function_selector.inner == self.inner - } - pub fn serialize(self: Self) -> [Field; 1] { [self.inner as Field] } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr index 89085c0e67f..ece38501b6b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr @@ -1,5 +1,7 @@ use crate::address::{AztecAddress, EthAddress}; use crate::constants::GENERATOR_INDEX__CONTRACT_LEAF; +use dep::std::ops::Eq; +use crate::traits::{Empty, Hash}; struct NewContractData { contract_address: AztecAddress, @@ -7,28 +9,26 @@ struct NewContractData { function_tree_root: Field, } -impl NewContractData { - pub fn is_empty(self) -> bool { - (self.contract_address.to_field() == 0) & - (self.portal_contract_address.to_field() == 0) & - (self.function_tree_root ==0) - } - - pub fn eq(self, data: NewContractData) -> bool { +impl Eq for NewContractData { + fn eq(self, data: NewContractData) -> bool { data.contract_address.eq(self.contract_address) & data.portal_contract_address.eq(self.portal_contract_address) & (data.function_tree_root == self.function_tree_root) } +} - pub fn default() -> Self { +impl Empty for NewContractData { + fn empty() -> Self { Self { - contract_address : AztecAddress::default(), - portal_contract_address : EthAddress::default(), + contract_address : AztecAddress::empty(), + portal_contract_address : EthAddress::empty(), function_tree_root : 0, } } +} - pub fn hash(self) -> Field { +impl Hash for NewContractData { + fn hash(self) -> Field { if self.is_empty() { 0 // We want to return 0 here since the contract_address is zero } else { @@ -40,3 +40,12 @@ impl NewContractData { } } } + +impl NewContractData { + pub fn is_empty(self) -> bool { + (self.contract_address.to_field() == 0) & + (self.portal_contract_address.to_field() == 0) & + (self.function_tree_root ==0) + } + +} diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_leaf_preimage.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_leaf_preimage.nr index 681bd115686..76ac2834bb3 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_leaf_preimage.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/nullifier_leaf_preimage.nr @@ -1,31 +1,37 @@ global NULLIFIER_LEAF_PREIMAGE_LENGTH: Field = 3; +use crate::traits::{Empty, Hash}; + struct NullifierLeafPreimage { nullifier : Field, next_nullifier :Field, next_index : u32, } -impl NullifierLeafPreimage { - pub fn default() -> Self { +impl Empty for NullifierLeafPreimage { + fn empty() -> Self { Self { nullifier : 0, next_nullifier : 0, next_index : 0, } } +} - pub fn is_empty(self) -> bool { - (self.nullifier == 0) & (self.next_nullifier == 0) & (self.next_index == 0) - } - - pub fn hash(self) -> Field { +impl Hash for NullifierLeafPreimage { + fn hash(self) -> Field { if self.is_empty() { 0 } else { dep::std::hash::pedersen_hash(self.serialize()) } } +} + +impl NullifierLeafPreimage { + pub fn is_empty(self) -> bool { + (self.nullifier == 0) & (self.next_nullifier == 0) & (self.next_index == 0) + } pub fn serialize(self) -> [Field; NULLIFIER_LEAF_PREIMAGE_LENGTH] { [self.nullifier, self.next_nullifier, self.next_index as Field] diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 726868af6fe..b788881c768 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -23,6 +23,7 @@ use crate::constants::{ PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS, }; +use crate::traits::Hash; struct PrivateCircuitPublicInputs { call_context: CallContext, @@ -55,8 +56,8 @@ struct PrivateCircuitPublicInputs { version: Field, } -impl PrivateCircuitPublicInputs { - fn hash(self) -> Field { +impl Hash for PrivateCircuitPublicInputs { + fn hash(self) -> Field { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) let mut fields: BoundedVec = BoundedVec::new(0); fields.push(self.call_context.hash()); @@ -89,7 +90,9 @@ impl PrivateCircuitPublicInputs { pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS) } +} +impl PrivateCircuitPublicInputs { fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] { let mut fields: BoundedVec = BoundedVec::new(0); fields.push_array(self.call_context.serialize()); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_read.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_read.nr index 8e3fc4bb497..f009f6d4abc 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_read.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_read.nr @@ -1,30 +1,38 @@ use crate::constants::GENERATOR_INDEX__PUBLIC_DATA_READ; +use dep::std::ops::Eq; +use crate::traits::{Empty,Hash}; struct PublicDataRead { leaf_slot : Field, value : Field, } -impl PublicDataRead { - fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ - self.leaf_slot, - self.value, - ], GENERATOR_INDEX__PUBLIC_DATA_READ) +impl Eq for PublicDataRead { + fn eq(self, public_data_read: PublicDataRead) -> bool { + (public_data_read.leaf_slot == self.leaf_slot) & (public_data_read.value == self.value) } +} - pub fn empty() -> Self { +impl Empty for PublicDataRead { + fn empty() -> Self { Self { leaf_slot : 0, value : 0, } } +} - pub fn is_empty(self) -> bool { - (self.leaf_slot == 0) & (self.value == 0) +impl Hash for PublicDataRead { + fn hash(self) -> Field { + dep::std::hash::pedersen_hash_with_separator([ + self.leaf_slot, + self.value, + ], GENERATOR_INDEX__PUBLIC_DATA_READ) } +} - pub fn eq(self, public_data_read: PublicDataRead) -> bool { - (public_data_read.leaf_slot == self.leaf_slot) & (public_data_read.value == self.value) +impl PublicDataRead { + pub fn is_empty(self) -> bool { + (self.leaf_slot == 0) & (self.value == 0) } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_update_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_update_request.nr index 798f2fcc35e..67ff120f086 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_update_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_data_update_request.nr @@ -1,4 +1,6 @@ use crate::constants::GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST; +use dep::std::ops::Eq; +use crate::traits::{Empty, Hash}; struct PublicDataUpdateRequest { leaf_slot : Field, @@ -6,28 +8,34 @@ struct PublicDataUpdateRequest { new_value : Field } -impl PublicDataUpdateRequest { - pub fn empty() -> Self { +impl Eq for PublicDataUpdateRequest { + fn eq(self, update_request: PublicDataUpdateRequest) -> bool { + (update_request.leaf_slot == self.leaf_slot) & (update_request.old_value == self.old_value) + & (update_request.new_value == self.new_value) + } +} + +impl Empty for PublicDataUpdateRequest { + fn empty() -> Self { Self { leaf_slot : 0, old_value : 0, new_value : 0 } } +} - pub fn eq(self, update_request: PublicDataUpdateRequest) -> bool { - (update_request.leaf_slot == self.leaf_slot) & (update_request.old_value == self.old_value) - & (update_request.new_value == self.new_value) - } - - pub fn hash(self) -> Field { +impl Hash for PublicDataUpdateRequest { + fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.leaf_slot, self.old_value, self.new_value ], GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) } +} +impl PublicDataUpdateRequest { pub fn is_empty(self) -> bool { (self.leaf_slot == 0) & (self.old_value == 0) & (self.new_value == 0) } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index b9c53d23364..da13d853fe9 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -1,10 +1,35 @@ use crate::constants::{GENERATOR_INDEX__SIDE_EFFECT}; +use dep::std::ops::Eq; +use crate::traits::{Empty, Hash}; struct SideEffect{ value: Field, counter: Field, } +impl Eq for SideEffect { + fn eq(self, side_effect: SideEffect) -> bool { + (self.value == side_effect.value) + & (self.counter == side_effect.counter) + } +} + +impl Empty for SideEffect { + fn empty() -> Self { + SideEffect { + value: 0, + counter: 0, + } + } +} + +impl Hash for SideEffect { + fn hash(self) -> Field { + dep::std::hash::pedersen_hash_with_separator( + self.serialize() , GENERATOR_INDEX__SIDE_EFFECT) + } +} + impl SideEffect { pub fn serialize(self) -> [Field; 2] { [self.value, self.counter] @@ -16,33 +41,43 @@ impl SideEffect { counter: values[1], } } - pub fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator( - self.serialize() , GENERATOR_INDEX__SIDE_EFFECT) - } pub fn is_empty(self) -> bool { (self.value == 0) & (self.counter == 0) } +} - pub fn eq(self, side_effect: SideEffect) -> bool { +struct SideEffectLinkedToNoteHash{ + value: Field, + note_hash: Field, + counter: Field, +} + +impl Eq for SideEffectLinkedToNoteHash { + fn eq(self, side_effect: SideEffectLinkedToNoteHash) -> bool { (self.value == side_effect.value) - & (self.counter == side_effect.counter) + & (self.note_hash == side_effect.note_hash) + & (self.counter == side_effect.counter) } +} - pub fn empty() -> SideEffect { - SideEffect { +impl Empty for SideEffectLinkedToNoteHash { + fn empty() -> Self { + SideEffectLinkedToNoteHash { value: 0, + note_hash: 0, counter: 0, } } } -struct SideEffectLinkedToNoteHash{ - value: Field, - note_hash: Field, - counter: Field, +impl Hash for SideEffectLinkedToNoteHash { + fn hash(self) -> Field { + dep::std::hash::pedersen_hash_with_separator( + self.serialize(), + GENERATOR_INDEX__SIDE_EFFECT) + } } impl SideEffectLinkedToNoteHash{ @@ -58,30 +93,10 @@ impl SideEffectLinkedToNoteHash{ } } - pub fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator( - self.serialize(), - GENERATOR_INDEX__SIDE_EFFECT) - } - pub fn is_empty(self) -> bool { (self.value == 0) & (self.note_hash == 0) & (self.counter == 0) } - - pub fn eq(self, side_effect: SideEffectLinkedToNoteHash) -> bool { - (self.value == side_effect.value) - & (self.note_hash == side_effect.note_hash) - & (self.counter == side_effect.counter) - } - - pub fn empty() -> SideEffectLinkedToNoteHash { - SideEffectLinkedToNoteHash { - value: 0, - note_hash: 0, - counter: 0, - } - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index b60330d0c40..5bea56809f4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -7,22 +7,32 @@ use crate::{ utils, grumpkin_point::GrumpkinPoint, }; +use dep::std::ops::Eq; +use crate::traits::Empty; // Aztec address struct AztecAddress { inner : Field } -impl AztecAddress { - pub fn zero() -> Self { +impl Eq for AztecAddress { + fn eq(self, other : Self) -> bool { + self.to_field() == other.to_field() + } +} + +impl Empty for AztecAddress { + fn empty() -> Self { Self { - inner: 0 + inner : 0 } } +} - pub fn default() -> Self { +impl AztecAddress { + pub fn zero() -> Self { Self { - inner : 0 + inner: 0 } } @@ -60,10 +70,6 @@ impl AztecAddress { } } - pub fn eq(self, other : Self) -> bool { - self.to_field() == other.to_field() - } - pub fn serialize(self: Self) -> [Field; 1] { [self.inner] } @@ -79,16 +85,24 @@ struct EthAddress{ inner : Field } -impl EthAddress{ - pub fn zero() -> Self { +impl Eq for EthAddress { + fn eq(self, other : Self) -> bool { + self.to_field() == other.to_field() + } +} + +impl Empty for EthAddress { + fn empty() -> Self { Self { - inner: 0 + inner : 0 } } +} - pub fn default() -> Self { +impl EthAddress{ + pub fn zero() -> Self { Self { - inner : 0 + inner: 0 } } @@ -117,10 +131,6 @@ impl EthAddress{ } } - pub fn eq(self, other : Self) -> bool { - self.to_field() == other.to_field() - } - pub fn serialize(self: Self) -> [Field; 1] { [self.inner] } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr index 5369de614fc..a0ef079d69a 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr @@ -5,6 +5,7 @@ use crate::constants::{ }; use crate::hash::pedersen_hash; use crate::grumpkin_point::GrumpkinPoint; +use crate::traits::Hash; // docs:start:contract-deployment-data struct ContractDeploymentData { @@ -16,6 +17,12 @@ struct ContractDeploymentData { } // docs:end:contract-deployment-data +impl Hash for ContractDeploymentData { + fn hash(self) -> Field { + pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA) + } +} + impl ContractDeploymentData { fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] { [ @@ -36,7 +43,4 @@ impl ContractDeploymentData { self.portal_contract_address.assert_is_zero(); } - fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr index 58aeaa55214..ffc0cbe43c7 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr @@ -5,19 +5,23 @@ use crate::{ }, hash::pedersen_hash, }; +use crate::traits::Empty; struct StorageRead { storage_slot: Field, current_value: Field, } -impl StorageRead { - pub fn empty() -> Self { +impl Empty for StorageRead { + fn empty() -> Self { Self { storage_slot: 0, current_value: 0, } } +} + +impl StorageRead { pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] { [self.storage_slot, self.current_value] diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr index 95f1d68bf4d..d9fab6779b2 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr @@ -5,6 +5,8 @@ use crate::{ }, hash::pedersen_hash, }; +use dep::std::ops::Eq; +use crate::traits::{Hash, Empty}; struct StorageUpdateRequest{ storage_slot : Field, @@ -12,31 +14,37 @@ struct StorageUpdateRequest{ new_value : Field, } -impl StorageUpdateRequest { - pub fn empty() -> Self { +impl Eq for StorageUpdateRequest { + fn eq(self, request: Self) -> bool { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) + (request.storage_slot == self.storage_slot) + & (request.old_value == self.old_value) + & (request.new_value == self.new_value) + } +} + +impl Empty for StorageUpdateRequest { + fn empty() -> Self { StorageUpdateRequest { storage_slot: 0, old_value: 0, new_value: 0, } } +} - pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { - [self.storage_slot, self.old_value, self.new_value] +impl Hash for StorageUpdateRequest { + fn hash(self) -> Field { + pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) } +} - pub fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) +impl StorageUpdateRequest { + pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { + [self.storage_slot, self.old_value, self.new_value] } pub fn is_empty(self) -> bool { self.storage_slot == 0 } - - pub fn eq(self, request: Self) -> bool { - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) - (request.storage_slot == self.storage_slot) - & (request.old_value == self.old_value) - & (request.new_value == self.new_value) - } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr index bde59b6156c..7e22369a462 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr @@ -15,5 +15,6 @@ mod hash; mod interop_testing; mod tests; +mod traits; use abis::kernel_circuit_public_inputs::{ KernelCircuitPublicInputs, KernelCircuitPublicInputsFinal }; diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr new file mode 100644 index 00000000000..03ddb8d9bb8 --- /dev/null +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -0,0 +1,8 @@ +// Preferred over Default trait to convey intent, as default doesn't necessarily mean empty. +trait Empty { + fn empty() -> Self; +} + +trait Hash { + fn hash(self) -> Field; +} diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/context.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/context.nr index 3715951ca78..d34fe3e885b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/context.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/context.nr @@ -1,5 +1,6 @@ use crate::constants::GENERATOR_INDEX__TX_CONTEXT; use crate::contrakt::deployment_data::ContractDeploymentData; +use crate::traits::Hash; struct TxContext { is_fee_payment_tx : bool, @@ -12,7 +13,7 @@ struct TxContext { version : Field, } -impl TxContext { +impl Hash for TxContext { fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.is_fee_payment_tx as Field, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr index f659a81cebd..88d1a820143 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr @@ -2,6 +2,7 @@ use crate::constants::GENERATOR_INDEX__TX_REQUEST; use crate::address::AztecAddress; use crate::transaction::context::TxContext; use crate::abis::function_data::FunctionData; +use crate::traits::Hash; struct TxRequest { origin : AztecAddress, @@ -10,7 +11,7 @@ struct TxRequest { function_data : FunctionData } -impl TxRequest { +impl Hash for TxRequest { fn hash(self) -> Field { dep::std::hash::pedersen_hash_with_separator([ self.origin.to_field(),