From 0fda73fb8fc7c4cd125b6a3a58694dcdb25bfed9 Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 3 Sep 2024 15:57:40 +0100 Subject: [PATCH 1/2] feat: calculate `FunctionSelector`s and `EventSelector`s during comptime --- noir-projects/aztec-nr/authwit/src/auth.nr | 11 ++++---- .../aztec/src/encrypted_logs/incoming_body.nr | 2 +- .../contracts/avm_test_contract/src/main.nr | 4 ++- .../contracts/fpc_contract/src/main.nr | 8 ++++-- .../contracts/parent_contract/src/main.nr | 28 +++++++++++++------ .../contracts/test_contract/src/main.nr | 4 ++- .../contracts/token_contract/src/main.nr | 4 ++- .../aztec_macros/src/transforms/events.rs | 2 +- .../nargo_fmt/tests/expected/contract.nr | 13 +++++---- .../tooling/nargo_fmt/tests/input/contract.nr | 13 +++++---- 10 files changed, 57 insertions(+), 32 deletions(-) diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index 7e8f33c03960..8ff6f70bf20e 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -219,8 +219,9 @@ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_o // We perform a static call here and not a standard one to ensure that the account contract cannot re-enter. let result: Field = context.static_call_private_function( on_behalf_of, - FunctionSelector::from_signature("verify_private_authwit(Field)"), - [inner_hash] + comptime { + FunctionSelector::from_signature("verify_private_authwit(Field)") + }, [inner_hash] ).unpack_into(); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); // Compute the nullifier, similar computation to the outer hash, but without the chain_id and version. @@ -263,7 +264,7 @@ pub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_ pub fn assert_inner_hash_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, inner_hash: Field) { let result: Field = context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - FunctionSelector::from_signature("consume((Field),Field)"), + comptime { FunctionSelector::from_signature("consume((Field),Field)") }, [on_behalf_of.to_field(), inner_hash].as_slice(), GasOpts::default() ).deserialize_into(); @@ -357,7 +358,7 @@ pub fn compute_authwit_message_hash(consumer: AztecAddress, chain_id: Field, ver pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authorize: bool) { context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - FunctionSelector::from_signature("set_authorized(Field,bool)"), + comptime { FunctionSelector::from_signature("set_authorized(Field,bool)") }, [message_hash, authorize as Field].as_slice(), GasOpts::default() ).assert_empty(); @@ -373,7 +374,7 @@ pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authoriz pub fn set_reject_all(context: &mut PublicContext, reject: bool) { context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - FunctionSelector::from_signature("set_reject_all(bool)"), + comptime { FunctionSelector::from_signature("set_reject_all(bool)") }, [context.this_address().to_field(), reject as Field].as_slice(), GasOpts::default() ).assert_empty(); diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr index e3d2ea442629..39af0fba85a0 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/incoming_body.nr @@ -177,7 +177,7 @@ mod test { impl EventInterface for TestEvent { fn get_event_type_id() -> EventSelector { - EventSelector::from_signature("TestEvent(Field,Field,Field)") + comptime { EventSelector::from_signature("TestEvent(Field,Field,Field)") } } fn private_to_be_bytes(self, randomness: Field) -> [u8; TEST_EVENT_BYTES_LEN] { diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index e69c10ce92f3..6c13b53130d1 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -341,7 +341,9 @@ contract AvmTest { #[aztec(public)] fn check_selector() { assert( - context.selector() == FunctionSelector::from_signature("check_selector()"), "Unexpected selector!" + context.selector() == comptime { + FunctionSelector::from_signature("check_selector()") + }, "Unexpected selector!" ); } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index 2aab1481669a..823591a754cf 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -28,7 +28,9 @@ contract FPC { // FPC::at(context.this_address()).pay_refund_with_shielded_rebate(amount, asset, secret_hash).set_public_teardown_function(&mut context); context.set_public_teardown_function( context.this_address(), - FunctionSelector::from_signature("pay_refund_with_shielded_rebate(Field,(Field),Field)"), + comptime { + FunctionSelector::from_signature("pay_refund_with_shielded_rebate(Field,(Field),Field)") + }, [amount, asset.to_field(), secret_hash] ); } @@ -41,7 +43,9 @@ contract FPC { // FPC::at(context.this_address()).pay_refund(context.msg_sender(), amount, asset).set_public_teardown_function(&mut context); context.set_public_teardown_function( context.this_address(), - FunctionSelector::from_signature("pay_refund((Field),Field,(Field))"), + comptime { + FunctionSelector::from_signature("pay_refund((Field),Field,(Field))") + }, [context.msg_sender().to_field(), amount, asset.to_field()] ); } diff --git a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr index fb6181311417..ee3b17663c63 100644 --- a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr @@ -56,7 +56,7 @@ contract Parent { context.call_public_function(target_contract, target_selector, [target_value]); } - // Private function that enqueues two calls to a child contract: + // Private function that enqueues two calls to a child contract: // - one through a nested call to enqueue_call_to_child with value 10, // - followed by one issued directly from this function with value 20. #[aztec(private)] @@ -64,7 +64,9 @@ contract Parent { target_contract: AztecAddress, target_selector: FunctionSelector ) { - let enqueue_call_to_child_selector = FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)"); + let enqueue_call_to_child_selector = comptime { + FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)") + }; let _ret = context.call_private_function( context.this_address(), enqueue_call_to_child_selector, @@ -73,7 +75,7 @@ contract Parent { context.call_public_function(target_contract, target_selector, [20]); } - // Private function that enqueues two calls to a child contract: + // Private function that enqueues two calls to a child contract: // - one issued directly from this function with value 20, // - followed by one through a nested call to enqueue_call_to_child with value 10. #[aztec(private)] @@ -82,7 +84,9 @@ contract Parent { target_selector: FunctionSelector ) { context.call_public_function(target_contract, target_selector, [20]); - let enqueue_call_to_child_selector = FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)"); + let enqueue_call_to_child_selector = comptime { + FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)") + }; let _ret = context.call_private_function( context.this_address(), enqueue_call_to_child_selector, @@ -110,7 +114,9 @@ contract Parent { target_selector: FunctionSelector, target_value: Field ) { - let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); + let pub_entry_point_selector = comptime { + FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") + }; let this_address = context.this_address(); let _void = context.call_public_function( this_address, @@ -126,7 +132,9 @@ contract Parent { target_selector: FunctionSelector, target_value: Field ) { - let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); + let pub_entry_point_selector = comptime { + FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") + }; let this_address = context.this_address(); context.call_public_function( @@ -265,7 +273,9 @@ contract Parent { let value_to_set = 7; let parent_private_set_call_interface = Parent::interface().private_call( child_contract_address, - FunctionSelector::from_signature("private_set_value(Field,(Field))"), + comptime { + FunctionSelector::from_signature("private_set_value(Field,(Field))") + }, [value_to_set, owner.to_field()] ); let result: Field = env.call_private(parent_private_set_call_interface); @@ -282,7 +292,9 @@ contract Parent { // Get value from child through parent let parent_private_get_call_interface = Parent::interface().private_call( child_contract_address, - FunctionSelector::from_signature("private_get_value(Field,(Field))"), + comptime { + FunctionSelector::from_signature("private_get_value(Field,(Field))") + }, [7, owner.to_field()] ); let read_result: Field = env.call_private(parent_private_get_call_interface); diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 703e0e7e9cbd..b14a44df769b 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -213,7 +213,9 @@ contract Test { fn test_setting_teardown() { context.set_public_teardown_function( context.this_address(), - FunctionSelector::from_signature("dummy_public_call()"), + comptime { + FunctionSelector::from_signature("dummy_public_call()") + }, [] ); } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 2d058ed5c79f..819a3395fbb0 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -572,7 +572,9 @@ contract Token { // function has access to the final transaction fee, which is needed to compute the actual refund amount. context.set_public_teardown_function( context.this_address(), - FunctionSelector::from_signature("complete_refund(((Field,Field,bool)),((Field,Field,bool)),Field)"), + comptime { + FunctionSelector::from_signature("complete_refund(((Field,Field,bool)),((Field,Field,bool)),Field)") + }, [ fee_payer_point.inner.x, fee_payer_point.inner.y, fee_payer_point.inner.is_infinite as Field, user_point.inner.x, user_point.inner.y, user_point.inner.is_infinite as Field, funded_amount ] diff --git a/noir/noir-repo/aztec_macros/src/transforms/events.rs b/noir/noir-repo/aztec_macros/src/transforms/events.rs index b02cf1cc6225..ede8a350bf24 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/events.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/events.rs @@ -230,7 +230,7 @@ fn generate_fn_get_event_type_id( let function_source = format!( " fn get_event_type_id() -> dep::aztec::protocol_types::abis::event_selector::EventSelector {{ - dep::aztec::protocol_types::abis::event_selector::EventSelector::from_signature(\"{event_type}({from_signature_input})\") + comptime {{ dep::aztec::protocol_types::abis::event_selector::EventSelector::from_signature(\"{event_type}({from_signature_input})\") }} }} ", ) diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr index e3a5877725af..c1360a69cf31 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr @@ -1,6 +1,6 @@ -// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -// Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -// Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. +// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +// Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. // Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; @@ -63,8 +63,9 @@ contract Benchmarking { storage.balances.at(owner).write(current + value); let _callStackItem1 = context.call_public_function( context.this_address(), - FunctionSelector::from_signature("broadcast(Field)"), - [owner] + comptime { + FunctionSelector::from_signature("broadcast(Field)") + }, [owner] ); } @@ -75,5 +76,5 @@ contract Benchmarking { } } -// Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 +// Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 contract Uniswap {} diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr index e3a5877725af..c1360a69cf31 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr @@ -1,6 +1,6 @@ -// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -// Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -// Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. +// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +// Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. // Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; @@ -63,8 +63,9 @@ contract Benchmarking { storage.balances.at(owner).write(current + value); let _callStackItem1 = context.call_public_function( context.this_address(), - FunctionSelector::from_signature("broadcast(Field)"), - [owner] + comptime { + FunctionSelector::from_signature("broadcast(Field)") + }, [owner] ); } @@ -75,5 +76,5 @@ contract Benchmarking { } } -// Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 +// Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 contract Uniswap {} From 207f169c61f6e294d2b829f8d727213fee89a3bd Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 3 Sep 2024 17:37:24 +0100 Subject: [PATCH 2/2] . --- noir-projects/aztec-nr/authwit/src/auth.nr | 15 +++++++++++---- .../tooling/nargo_fmt/tests/expected/contract.nr | 3 ++- .../tooling/nargo_fmt/tests/input/contract.nr | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index 8ff6f70bf20e..9e240682fae7 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -221,7 +221,8 @@ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_o on_behalf_of, comptime { FunctionSelector::from_signature("verify_private_authwit(Field)") - }, [inner_hash] + }, + [inner_hash] ).unpack_into(); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); // Compute the nullifier, similar computation to the outer hash, but without the chain_id and version. @@ -264,7 +265,9 @@ pub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_ pub fn assert_inner_hash_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, inner_hash: Field) { let result: Field = context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { FunctionSelector::from_signature("consume((Field),Field)") }, + comptime { + FunctionSelector::from_signature("consume((Field),Field)") + }, [on_behalf_of.to_field(), inner_hash].as_slice(), GasOpts::default() ).deserialize_into(); @@ -358,7 +361,9 @@ pub fn compute_authwit_message_hash(consumer: AztecAddress, chain_id: Field, ver pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authorize: bool) { context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { FunctionSelector::from_signature("set_authorized(Field,bool)") }, + comptime { + FunctionSelector::from_signature("set_authorized(Field,bool)") + }, [message_hash, authorize as Field].as_slice(), GasOpts::default() ).assert_empty(); @@ -374,7 +379,9 @@ pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authoriz pub fn set_reject_all(context: &mut PublicContext, reject: bool) { context.call_public_function( CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { FunctionSelector::from_signature("set_reject_all(bool)") }, + comptime { + FunctionSelector::from_signature("set_reject_all(bool)") + }, [context.this_address().to_field(), reject as Field].as_slice(), GasOpts::default() ).assert_empty(); diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr index c1360a69cf31..cb7505f845ca 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr @@ -65,7 +65,8 @@ contract Benchmarking { context.this_address(), comptime { FunctionSelector::from_signature("broadcast(Field)") - }, [owner] + }, + [owner] ); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr index c1360a69cf31..cb7505f845ca 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/contract.nr @@ -65,7 +65,8 @@ contract Benchmarking { context.this_address(), comptime { FunctionSelector::from_signature("broadcast(Field)") - }, [owner] + }, + [owner] ); }