Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: track side effects in public #5129

Merged
merged 15 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ library Constants {
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5;
uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 6;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 214;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 209;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 200;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 215;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 210;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 202;
uint256 internal constant STATE_REFERENCE_LENGTH = 8;
uint256 internal constant TX_CONTEXT_DATA_LENGTH = 4;
uint256 internal constant TX_REQUEST_LENGTH = 10;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ struct PrivateContextInputs {
call_context : CallContext,
historical_header: Header,
private_global_variables: PrivateGlobalVariables,
start_side_effect_counter: u32,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we need to add this here instead of continuing to use the one in CallContext? I'm struggling a bit with how they are different, and why the one in CallContext got renamed to just side_effect_counter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LeilaWang came with the suggestion to remove it from CallContext entirely, which I've attempted to do in #5177

Why did we need to add this here instead of continuing to use the one in CallContext?

The value in call_context is either the start_side_effect_counter for private calls and public calls in public execution, while it is the enqueued_side_effect_counter for enqueued public calls.

The real start_side_effect_counter is the one returned by context.finish() and for enqueued calls it will be different than what's in call_context (I enqueue it at 5 but run the function at 20). Because of the hashing that goes on in the kernel I can't modify call_context.side_effect_counter for enqueued calls.

In #5177 we remove call_context.side_effect_counter and rely on public inputs.

}
// docs:end:private-context-inputs
// docs:end:private-context-inputs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ struct PublicContextInputs {
historical_header: Header,

public_global_variables: PublicGlobalVariables,

start_side_effect_counter: u32,
}
// docs:end:public-context-inputs
18 changes: 8 additions & 10 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl ContextInterface for PrivateContext {

// Returns the header of a block whose state is used during private execution (not the block the transaction is
// included in).
pub fn get_header(self) -> Header {
fn get_header(self) -> Header {
self.historical_header
}

Expand All @@ -113,7 +113,7 @@ impl ContextInterface for PrivateContext {

impl PrivateContext {
pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {
let side_effect_counter = inputs.call_context.start_side_effect_counter;
let side_effect_counter = inputs.start_side_effect_counter;
let mut min_revertible_side_effect_counter = 0;
if is_empty(inputs.call_context.msg_sender) {
min_revertible_side_effect_counter = side_effect_counter;
Expand Down Expand Up @@ -157,12 +157,6 @@ impl PrivateContext {
call_context: self.inputs.call_context,
args_hash: self.args_hash,
return_values: self.return_values.storage,
// TODO(fees): start this from 0 and test the following:
// - in the private circuit init that it gets set correctly
// - in the private circuit inner that it remains 0
// I've had to initialize the counter here so that it would work for contract deployments
// the above checks should be doable after we figure out fee payments for contract deployments
// TO(fees): there are no more contract deployments at the protocol level
min_revertible_side_effect_counter: self.min_revertible_side_effect_counter,
note_hash_read_requests: self.note_hash_read_requests.storage,
nullifier_read_requests: self.nullifier_read_requests.storage,
Expand All @@ -172,6 +166,7 @@ impl PrivateContext {
private_call_stack_hashes: self.private_call_stack_hashes.storage,
public_call_stack_hashes: self.public_call_stack_hashes.storage,
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,
encrypted_logs_hash,
unencrypted_logs_hash,
Expand Down Expand Up @@ -333,7 +328,8 @@ impl PrivateContext {
is_delegate_call
);

assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);
assert_eq(item.public_inputs.call_context.side_effect_counter, self.side_effect_counter);
assert_eq(item.public_inputs.start_side_effect_counter, self.side_effect_counter);
self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1;

assert(contract_address.eq(item.contract_address));
Expand Down Expand Up @@ -458,6 +454,8 @@ impl PrivateContext {
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],
start_side_effect_counter: 0,
end_side_effect_counter: 0,
unencrypted_logs_hash: [0; NUM_FIELDS_PER_SHA256],
unencrypted_log_preimages_length: 0,
historical_header: Header::empty(),
Expand All @@ -471,7 +469,7 @@ impl PrivateContext {
assert(contract_address.eq(item.contract_address));
assert(function_selector.eq(item.function_data.selector));

assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter);
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;

Expand Down
50 changes: 37 additions & 13 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl PublicContext {
pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext {
PublicContext {
inputs,
side_effect_counter: inputs.call_context.start_side_effect_counter,
side_effect_counter: inputs.start_side_effect_counter,
args_hash,
return_values: BoundedVec::new(),
nullifier_read_requests: BoundedVec::new(),
Expand Down Expand Up @@ -154,6 +154,8 @@ impl PublicContext {
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,
start_side_effect_counter: self.inputs.start_side_effect_counter,
end_side_effect_counter: self.side_effect_counter,
unencrypted_logs_hash,
unencrypted_log_preimages_length,
historical_header: self.inputs.historical_header,
Expand Down Expand Up @@ -209,59 +211,81 @@ impl PublicContext {
}

pub fn call_public_function<ARGS_COUNT>(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
call_public_function_internal(contract_address, function_selector, args_hash, false, false)
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, false)
}

pub fn static_call_public_function<ARGS_COUNT>(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
call_public_function_internal(contract_address, function_selector, args_hash, true, false)
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true, false)
}

pub fn delegate_call_public_function<ARGS_COUNT>(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args: [Field; ARGS_COUNT]
) -> [Field; RETURN_VALUES_LENGTH] {
let args_hash = hash_args(args);
assert(args_hash == arguments::pack_arguments(args));
call_public_function_internal(contract_address, function_selector, args_hash, false, true)
self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false, true)
}

pub fn call_public_function_no_args(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_internal(contract_address, function_selector, 0, false, false)
self.call_public_function_with_packed_args(contract_address, function_selector, 0, false, false)
}

pub fn static_call_public_function_no_args(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_internal(contract_address, function_selector, 0, true, false)
self.call_public_function_with_packed_args(contract_address, function_selector, 0, true, false)
}

pub fn delegate_call_public_function_no_args(
_self: Self,
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_internal(contract_address, function_selector, 0, false, true)
self.call_public_function_with_packed_args(contract_address, function_selector, 0, false, true)
}

pub fn call_public_function_with_packed_args(
self: &mut Self,
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
is_static_call: bool,
is_delegate_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {
let side_effect_counter = self.side_effect_counter;
// TODO get next value from output of `call_public_function_internal`
just-mitch marked this conversation as resolved.
Show resolved Hide resolved
self.side_effect_counter += 1;

call_public_function_internal(
contract_address,
function_selector,
args_hash,
side_effect_counter,
is_static_call,
is_delegate_call
)
}
}
3 changes: 3 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/public_call.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fn call_public_function_oracle(
_contract_address: AztecAddress,
_function_selector: FunctionSelector,
_args_hash: Field,
_side_effect_counter: u32,
_is_static_call: bool,
_is_delegate_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {}
Expand All @@ -13,13 +14,15 @@ unconstrained pub fn call_public_function_internal(
contract_address: AztecAddress,
function_selector: FunctionSelector,
args_hash: Field,
side_effect_counter: u32,
is_static_call: bool,
is_delegate_call: bool
) -> [Field; RETURN_VALUES_LENGTH] {
call_public_function_oracle(
contract_address,
function_selector,
args_hash,
side_effect_counter,
is_static_call,
is_delegate_call
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Token {

pub fn transfer_public(
self: Self,
context: PublicContext,
context: &mut PublicContext,
from: AztecAddress,
to: AztecAddress,
amount: Field,
Expand All @@ -27,6 +27,21 @@ impl Token {
);
}

pub fn shield(
self: Self,
context: &mut PublicContext,
from: AztecAddress,
amount: Field,
secret_hash: Field,
nonce: Field
) {
let _ = context.call_public_function(
self.address,
FunctionSelector::from_signature("shield((Field),Field,Field,Field)"),
[from.to_field(), amount, secret_hash, nonce]
);
}

// Private
pub fn unshield(
self: Self,
Expand Down
22 changes: 17 additions & 5 deletions noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract FPC {
}

#[aztec(private)]
fn fee_entrypoint_private(amount: Field, asset: AztecAddress, nonce: Field) {
fn fee_entrypoint_private(amount: Field, asset: AztecAddress, secret_hash: Field, nonce: Field) {
assert(asset == storage.other_asset.read_private());

let _res = Token::at(asset).unshield(
Expand All @@ -32,8 +32,8 @@ contract FPC {

let _void = context.call_public_function(
context.this_address(),
FunctionSelector::from_signature("pay_fee((Field),Field,(Field))"),
[context.msg_sender().to_field(), amount, asset.to_field()]
FunctionSelector::from_signature("pay_fee_with_shielded_rebate(Field,(Field),Field)"),
[amount, asset.to_field(), secret_hash]
);
}

Expand All @@ -55,7 +55,7 @@ contract FPC {
#[aztec(public)]
#[aztec(internal)]
fn prepare_fee(from: AztecAddress, amount: Field, asset: AztecAddress, nonce: Field) {
let _res = Token::at(asset).transfer_public(context, from, context.this_address(), amount, nonce);
let _res = Token::at(asset).transfer_public(&mut context, from, context.this_address(), amount, nonce);
}

#[aztec(public)]
Expand All @@ -68,6 +68,18 @@ contract FPC {
)[0];

// Just do public refunds for the present
Token::at(asset).transfer_public(context, context.this_address(), refund_address, refund, 0)
Token::at(asset).transfer_public(&mut context, context.this_address(), refund_address, refund, 0)
}

#[aztec(public)]
#[aztec(internal)]
fn pay_fee_with_shielded_rebate(amount: Field, asset: AztecAddress, secretHash: Field) {
let refund = context.call_public_function(
storage.gas_token_address.read_public(),
FunctionSelector::from_signature("pay_fee(Field)"),
[amount]
)[0];

Token::at(asset).shield(&mut context, context.this_address(), refund, secretHash, 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ contract ImportTest {
#[aztec(public)]
fn pubCallOpenFn(target: AztecAddress) -> Field {
let test_contract_instance = TestPublicContextInterface::at(target);
let ret = test_contract_instance.create_nullifier_public(context, 1, 2);
let ret = test_contract_instance.create_nullifier_public(&mut context, 1, 2);

ret[0]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl PriceFeed {
Self { address }
}

pub fn get_price(self: Self, context: PublicContext) -> U128 {
pub fn get_price(self: Self, context: &mut PublicContext) -> U128 {
let return_values = context.call_public_function(
self.address,
FunctionSelector::from_signature("get_price(Field)"),
Expand All @@ -36,21 +36,21 @@ impl Token {

pub fn transfer_public(
self: Self,
context: PublicContext,
context: &mut PublicContext,
from: AztecAddress,
to: AztecAddress,
amount: Field,
nonce: Field
) {
context.call_public_function(
let _ = context.call_public_function(
self.address,
FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"),
[from.to_field(), to.to_field(), amount, nonce]
);
}

pub fn mint_public(self: Self, context: PublicContext, to: AztecAddress, amount: Field) {
context.call_public_function(
pub fn mint_public(self: Self, context: &mut PublicContext, to: AztecAddress, amount: Field) {
let _ = context.call_public_function(
self.address,
FunctionSelector::from_signature("mint_public((Field),Field)"),
[to.to_field(), amount]
Expand All @@ -59,12 +59,12 @@ impl Token {

pub fn burn_public(
self: Self,
context: PublicContext,
context: &mut PublicContext,
from: AztecAddress,
amount: Field,
nonce: Field
) {
context.call_public_function(
let _ = context.call_public_function(
self.address,
FunctionSelector::from_signature("burn_public((Field),Field,Field)"),
[from.to_field(), amount, nonce]
Expand Down Expand Up @@ -111,7 +111,7 @@ impl Lending {
Self { address }
}

pub fn update_accumulator(self: Self, context: PublicContext) -> Asset {
pub fn update_accumulator(self: Self, context: &mut PublicContext) -> Asset {
let return_values = context.call_public_function_no_args(
self.address,
FunctionSelector::from_signature("update_accumulator()")
Expand Down
Loading
Loading