Skip to content

Commit

Permalink
feat: expose set_public_teardown_function in private context (#6199)
Browse files Browse the repository at this point in the history
See
[spec](https://docs.aztec.network/protocol-specs/gas-and-fees/tx-setup-and-teardown)

No additional business logic here, just exposing the planned interface.
  • Loading branch information
just-mitch committed May 3, 2024
1 parent 7d80428 commit 4d8b51c
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 75 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ jobs:
dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}"
concurrency_key: yarn-project-test-${{ github.actor }}-x86
- name: "Yarn Project Tests"
timeout-minutes: 25
timeout-minutes: 30
run: earthly-ci --no-output ./yarn-project/+test

prover-client-test:
Expand Down Expand Up @@ -292,7 +292,7 @@ jobs:
dockerhub_password: "${{ secrets.DOCKERHUB_PASSWORD }}"
concurrency_key: docs-preview-${{ inputs.username || github.actor }}-x86
- name: "Docs Preview"
timeout-minutes: 25
timeout-minutes: 30
run: earthly --no-output ./docs/+deploy-preview --PR=${{ github.event.number }} --AZTEC_BOT_COMMENTER_GITHUB_TOKEN=${{ secrets.AZTEC_BOT_GITHUB_TOKEN }} --NETLIFY_AUTH_TOKEN=${{ secrets.NETLIFY_AUTH_TOKEN }} --NETLIFY_SITE_ID=${{ secrets.NETLIFY_SITE_ID }}

# push benchmarking binaries to dockerhub registry
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ library Constants {
+ (NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH * MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL)
+ (NOTE_HASH_LENGTH * MAX_NEW_NOTE_HASHES_PER_CALL)
+ (NULLIFIER_LENGTH * MAX_NEW_NULLIFIERS_PER_CALL) + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL
+ MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + 1
+ (L2_TO_L1_MESSAGE_LENGTH * MAX_NEW_L2_TO_L1_MSGS_PER_CALL) + 2
+ (SIDE_EFFECT_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL)
+ (SIDE_EFFECT_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + 2 + HEADER_LENGTH + TX_CONTEXT_LENGTH;
Expand Down
146 changes: 83 additions & 63 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,32 @@ use crate::{
hash::{hash_args_array, ArgsHasher, compute_encrypted_log_hash, compute_unencrypted_log_hash},
oracle::{
arguments, returns, call_private_function::call_private_function_internal,
enqueue_public_function_call::enqueue_public_function_call_internal, header::get_header_at,
logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog},
enqueue_public_function_call::{
enqueue_public_function_call_internal, set_public_teardown_function_call_internal,
parse_public_call_stack_item_from_oracle
},
header::get_header_at, logs::emit_encrypted_log,
logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog},
nullifier_key::{get_nullifier_keys, NullifierKeys}
}
};
use dep::protocol_types::{
abis::{
global_variables::GlobalVariables, gas::Gas, call_context::CallContext, function_data::FunctionData,
function_selector::FunctionSelector, max_block_number::MaxBlockNumber,
nullifier_key_validation_request::NullifierKeyValidationRequest,
private_call_stack_item::PrivateCallStackItem,
private_circuit_public_inputs::PrivateCircuitPublicInputs,
public_call_stack_item::PublicCallStackItem,
public_circuit_public_inputs::PublicCircuitPublicInputs, read_request::ReadRequest,
note_hash::NoteHash, nullifier::Nullifier, side_effect::SideEffect
public_call_stack_item::PublicCallStackItem, read_request::ReadRequest, note_hash::NoteHash,
nullifier::Nullifier, side_effect::SideEffect
},
address::{AztecAddress, EthAddress},
constants::{
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_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL,
MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL
MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_ENCRYPTED_LOGS_PER_CALL,
MAX_UNENCRYPTED_LOGS_PER_CALL
},
contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},
grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint, header::Header,
messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader,
grumpkin_point::GrumpkinPoint, header::Header, messaging::l2_to_l1_message::L2ToL1Message,
traits::{is_empty, Deserialize, Empty}
};

Expand All @@ -57,6 +55,7 @@ struct PrivateContext {

private_call_stack_hashes : BoundedVec<Field, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,
public_call_stack_hashes : BoundedVec<Field, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL>,
public_teardown_function_hash: Field,
new_l2_to_l1_msgs : BoundedVec<L2ToL1Message, MAX_NEW_L2_TO_L1_MSGS_PER_CALL>,
// docs:end:private-context

Expand Down Expand Up @@ -129,6 +128,7 @@ impl PrivateContext {
historical_header: inputs.historical_header,
private_call_stack_hashes: BoundedVec::new(),
public_call_stack_hashes: BoundedVec::new(),
public_teardown_function_hash: 0,
new_l2_to_l1_msgs: BoundedVec::new(),
encrypted_logs_hashes: BoundedVec::new(),
unencrypted_logs_hashes: BoundedVec::new(),
Expand Down Expand Up @@ -169,6 +169,7 @@ impl PrivateContext {
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,
public_teardown_function_hash: self.public_teardown_function_hash,
new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,
start_side_effect_counter: self.inputs.start_side_effect_counter,
end_side_effect_counter: self.side_effect_counter,
Expand Down Expand Up @@ -257,11 +258,7 @@ impl PrivateContext {
let event_selector = 5; // TODO: compute actual event selector.
let contract_address = self.this_address();
let log_slice = log.to_be_bytes_arr();
let log_hash = compute_unencrypted_log_hash(
contract_address,
event_selector,
log,
);
let log_hash = compute_unencrypted_log_hash(contract_address, event_selector, log);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
self.unencrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
Expand All @@ -281,12 +278,7 @@ impl PrivateContext {
pub fn emit_contract_class_unencrypted_log<N>(&mut self, log: [Field; N]) {
let event_selector = 5; // TODO: compute actual event selector.
let contract_address = self.this_address();
let log_hash = emit_contract_class_unencrypted_log_private_internal(
contract_address,
event_selector,
log,
self.side_effect_counter
);
let log_hash = emit_contract_class_unencrypted_log_private_internal(contract_address, event_selector, log, self.side_effect_counter);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
self.unencrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
Expand Down Expand Up @@ -316,7 +308,7 @@ impl PrivateContext {
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
self.encrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
let encrypted_log_byte_len = 112 + 32*(N + 3);
let encrypted_log_byte_len = 112 + 32 * (N + 3);
// + processed log len (4)
self.encrypted_log_preimages_length += encrypted_log_byte_len + 4;
}
Expand Down Expand Up @@ -516,47 +508,77 @@ impl PrivateContext {
is_delegate_call
);

let mut reader = Reader::new(fields);

// Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and
// there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!
let item = PublicCallStackItem {
contract_address: AztecAddress::from_field(reader.read()),
function_data: reader.read_struct(FunctionData::deserialize),
public_inputs: PublicCircuitPublicInputs {
call_context: reader.read_struct(CallContext::deserialize),
args_hash: reader.read(),
returns_hash: 0,
nullifier_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL],
nullifier_non_existent_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL],
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_note_hashes: [NoteHash::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],
new_nullifiers: [Nullifier::empty(); MAX_NEW_NULLIFIERS_PER_CALL],
new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL],
start_side_effect_counter: 0,
end_side_effect_counter: 0,
unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL],
unencrypted_log_preimages_length: 0,
historical_header: Header::empty(),
global_variables: GlobalVariables::empty(),
prover_address: AztecAddress::zero(),
revert_code: 0,
start_gas_left: Gas::empty(),
end_gas_left: Gas::empty(),
transaction_fee: 0
},
is_execution_request: true
};
reader.finish();
let item = parse_public_call_stack_item_from_oracle(fields);
self.validate_call_stack_item_from_oracle(
item,
contract_address,
function_selector,
args_hash,
is_static_call,
is_delegate_call
);

self.side_effect_counter = self.side_effect_counter + 1;
self.public_call_stack_hashes.push(item.hash());
}

pub fn set_public_teardown_function<ARGS_COUNT>(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) {
let args_hash = hash_args_array(args);
assert(args_hash == arguments::pack_arguments_array(args));
self.set_public_teardown_function_with_packed_args(contract_address, function_selector, args_hash, false, false)
}

pub fn set_public_teardown_function_with_packed_args<ARGS_COUNT>(
&mut self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
is_static_call: bool,
is_delegate_call: bool
) {
let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;
let fields = set_public_teardown_function_call_internal(
contract_address,
function_selector,
args_hash,
self.side_effect_counter,
is_static_call,
is_delegate_call
);

let item = parse_public_call_stack_item_from_oracle(fields);
self.validate_call_stack_item_from_oracle(
item,
contract_address,
function_selector,
args_hash,
is_static_call,
is_delegate_call
);

self.side_effect_counter = self.side_effect_counter + 1;
self.public_teardown_function_hash = item.hash();
}

fn validate_call_stack_item_from_oracle(
self,
item: PublicCallStackItem,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
is_static_call: bool,
is_delegate_call: bool
) {
assert(contract_address.eq(item.contract_address));
assert(function_selector.eq(item.function_data.selector));

assert_eq(item.public_inputs.call_context.side_effect_counter, self.side_effect_counter);
// We increment the sideffect counter by one, to account for the call itself being a side effect.
self.side_effect_counter = self.side_effect_counter + 1;

assert(args_hash == item.public_inputs.args_hash);

Expand All @@ -577,8 +599,6 @@ impl PrivateContext {
item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)
);
}

self.public_call_stack_hashes.push(item.hash());
}
}

Expand All @@ -598,6 +618,7 @@ impl Empty for PrivateContext {
new_nullifiers: BoundedVec::new(),
private_call_stack_hashes : BoundedVec::new(),
public_call_stack_hashes : BoundedVec::new(),
public_teardown_function_hash: 0,
new_l2_to_l1_msgs : BoundedVec::new(),
historical_header: Header::empty(),
encrypted_logs_hashes: BoundedVec::new(),
Expand Down Expand Up @@ -663,7 +684,6 @@ fn emit_contract_class_unencrypted_log_private<N>(
counter: u32
) -> Field {}


unconstrained pub fn emit_contract_class_unencrypted_log_private_internal<N>(
contract_address: AztecAddress,
event_selector: Field,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
use dep::protocol_types::{
abis::function_selector::FunctionSelector, address::AztecAddress,
constants::ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH
abis::{
function_selector::FunctionSelector, public_call_stack_item::PublicCallStackItem,
function_data::FunctionData, public_circuit_public_inputs::PublicCircuitPublicInputs,
call_context::CallContext, read_request::ReadRequest, note_hash::NoteHash, nullifier::Nullifier,
side_effect::SideEffect, global_variables::GlobalVariables, gas::Gas
},
contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},
messaging::l2_to_l1_message::L2ToL1Message, header::Header, address::AztecAddress,
utils::reader::Reader,
constants::{
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_NULLIFIER_READ_REQUESTS_PER_CALL,
MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL,
ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH
}
};

#[oracle(enqueuePublicFunctionCall)]
Expand Down Expand Up @@ -30,3 +44,70 @@ unconstrained pub fn enqueue_public_function_call_internal(
is_delegate_call
)
}

#[oracle(setPublicTeardownFunctionCall)]
fn set_public_teardown_function_call_oracle(
_contract_address: AztecAddress,
_function_selector: FunctionSelector,
_args_hash: Field,
_side_effect_counter: u32,
_is_static_call: bool,
_is_delegate_call: bool
) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH] {}

unconstrained pub fn set_public_teardown_function_call_internal(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
side_effect_counter: u32,
is_static_call: bool,
is_delegate_call: bool
) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH] {
set_public_teardown_function_call_oracle(
contract_address,
function_selector,
args_hash,
side_effect_counter,
is_static_call,
is_delegate_call
)
}

pub fn parse_public_call_stack_item_from_oracle(fields: [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_LENGTH]) -> PublicCallStackItem {
let mut reader = Reader::new(fields);

// Note: Not using PublicCirclePublicInputs::deserialize here, because everything below args_hash is 0 and
// there is no more data in fields because there is only ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE fields!
let item = PublicCallStackItem {
contract_address: AztecAddress::from_field(reader.read()),
function_data: reader.read_struct(FunctionData::deserialize),
public_inputs: PublicCircuitPublicInputs {
call_context: reader.read_struct(CallContext::deserialize),
args_hash: reader.read(),
returns_hash: 0,
nullifier_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL],
nullifier_non_existent_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL],
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_note_hashes: [NoteHash::empty(); MAX_NEW_NOTE_HASHES_PER_CALL],
new_nullifiers: [Nullifier::empty(); MAX_NEW_NULLIFIERS_PER_CALL],
new_l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_NEW_L2_TO_L1_MSGS_PER_CALL],
start_side_effect_counter: 0,
end_side_effect_counter: 0,
unencrypted_logs_hashes: [SideEffect::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL],
unencrypted_log_preimages_length: 0,
historical_header: Header::empty(),
global_variables: GlobalVariables::empty(),
prover_address: AztecAddress::zero(),
revert_code: 0,
start_gas_left: Gas::empty(),
end_gas_left: Gas::empty(),
transaction_fee: 0
},
is_execution_request: true
};
reader.finish();

item
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ fn empty_hash() {
let hash = item.hash();

// Value from private_call_stack_item.test.ts "computes empty item hash" test
let test_data_empty_hash = 0x17fd6ffcb3394b845069dc87e055c37ac50599f274130fac69c6fe919bfe382e;
let test_data_empty_hash = 0x2485b8cfe671417410382ba6dfc803de70d9d45008a1b30c31b34d7c4de92106;
assert_eq(hash, test_data_empty_hash);
}
Loading

0 comments on commit 4d8b51c

Please sign in to comment.