Skip to content

Commit b6d4869

Browse files
callinterface doc comments
1 parent 8cd0d2e commit b6d4869

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,68 @@ where
5151
}
5252
}
5353

54+
/// Makes the call to this private function.
55+
///
56+
/// # Arguments
57+
/// * `context` - The PrivateContext -- made magically available to the body
58+
/// of every #[private] function as `context`, through the
59+
/// #[private] annotation's macro.
60+
///
61+
/// # Returns
62+
/// * `T` - Whatever data the called function has returned.
63+
///
64+
/// This enables contracts to interact with each other while maintaining
65+
/// privacy. This "composability" of private contract functions is a key
66+
/// feature of the Aztec network.
67+
///
68+
/// If a user's transaction includes multiple private function calls, then
69+
/// by the design of Aztec, the following information will remain private[1]:
70+
/// - The function selectors and contract addresses of all private function
71+
/// calls will remain private, so an observer of the public mempool will
72+
/// not be able to look at a tx and deduce which private functions have
73+
/// been executed.
74+
/// - The arguments and return values of all private function calls will
75+
/// remain private.
76+
/// - The person who initiated the tx will remain private.
77+
/// - The notes and nullifiers and private logs that are emitted by all
78+
/// private function calls will (if designed well) not leak any user
79+
/// secrets, nor leak which functions have been executed.
80+
///
81+
/// [1] Caveats: Some of these privacy guarantees depend on how app
82+
/// developers design their smart contracts. Some actions _can_ leak
83+
/// information, such as:
84+
/// - Calling an internal public function.
85+
/// - Calling a public function and not setting msg_sender to Option::none
86+
/// (see https://github.com/AztecProtocol/aztec-packages/pull/16433)
87+
/// - Calling any public function will always leak details about the nature
88+
/// of the transaction, so devs should be careful in their contract
89+
/// designs. If it can be done in a private function, then that will give
90+
/// the best privacy.
91+
/// - Not padding the side-effects of a tx to some standardised, uniform
92+
/// size. The kernel circuits can take hints to pad side-effects, so a
93+
/// wallet should be able to request for a particular amount of padding.
94+
/// Wallets should ideally agree on some standard.
95+
/// - Padding should include:
96+
/// - Padding the lengths of note & nullifier arrays
97+
/// - Padding private logs with random fields, up to some standardised
98+
/// size.
99+
/// See also: https://docs.aztec.network/developers/reference/considerations/privacy_considerations
100+
///
101+
/// # Advanced
102+
/// * The call is added to the private call stack and executed by kernel
103+
/// circuits after this function completes
104+
/// * The called function can modify its own contract's private state
105+
/// * Side effects from the called function are included in this transaction
106+
/// * The call inherits the current transaction's context and gas limits
107+
///
108+
/// # Arguments
109+
/// * `context` - The PrivateContext -- made magically available to the body
110+
/// of every #[private] function as `context`, through the
111+
/// #[private] annotation's macro.
112+
///
113+
/// # Returns
114+
/// * `T` - Whatever data the called function has returned.
115+
///
54116
pub fn call(self, context: &mut PrivateContext) -> T {
55117
execution_cache::store(self.args, self.args_hash);
56118
let returns_hash = context.call_private_function_with_args_hash(
@@ -65,6 +127,22 @@ where
65127
returns_hash.get_preimage()
66128
}
67129

130+
/// Makes a _read-only_ call to this private function.
131+
///
132+
/// This is similar to Solidity's `staticcall`. The called function
133+
/// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
134+
/// calls are constrained to also be staticcalls.
135+
///
136+
/// See `call` for more general info on private function calls.
137+
///
138+
/// # Arguments
139+
/// * `context` - The PrivateContext -- made magically available to the body
140+
/// of every #[private] function as `context`, through the
141+
/// #[private] annotation's macro.
142+
///
143+
/// # Returns
144+
/// * `T` - Whatever data the called function has returned.
145+
///
68146
pub fn view(self, context: &mut PrivateContext) -> T {
69147
execution_cache::store(self.args, self.args_hash);
70148
let returns_hash = context.call_private_function_with_args_hash(
@@ -132,6 +210,17 @@ impl<let M: u32, T> PrivateStaticCallInterface<M, T> {
132210
}
133211
}
134212

213+
/// Makes a read-only call to this private function.
214+
///
215+
/// This is similar to Solidity's `staticcall`. The called function
216+
/// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
217+
/// calls are constrained to also be staticcalls.
218+
///
219+
/// # Arguments
220+
/// * `context` - The PrivateContext -- made magically available to the body
221+
/// of every #[private] function as `context`, through the
222+
/// #[private] annotation's macro.
223+
///
135224
pub fn view(self, context: &mut PrivateContext) -> T
136225
where
137226
T: Deserialize,
@@ -208,6 +297,18 @@ where
208297
self
209298
}
210299

300+
/// Makes the call to this public function.
301+
///
302+
/// Will revert if the called function reverts or runs out of gas.
303+
///
304+
/// # Arguments
305+
/// * `context` - The PublicContext -- made magically available to the body
306+
/// of every #[public] function as `context`, through the
307+
/// #[public] annotation's macro.
308+
///
309+
/// # Returns
310+
/// * `T` - Whatever data the called function has returned.
311+
///
211312
pub unconstrained fn call(self, context: &mut PublicContext) -> T {
212313
let returns = context.call_public_function(
213314
self.target_contract,
@@ -220,6 +321,22 @@ where
220321
Deserialize::deserialize(returns.as_array())
221322
}
222323

324+
/// Makes a read-only call to this public function.
325+
///
326+
/// This is similar to Solidity's `staticcall`. The called function
327+
/// cannot modify state or emit events. Any nested calls are constrained to
328+
/// also be staticcalls.
329+
///
330+
/// Will revert if the called function reverts or runs out of gas.
331+
///
332+
/// # Arguments
333+
/// * `context` - The PublicContext -- made magically available to the body
334+
/// of every #[public] function as `context`, through the
335+
/// #[public] annotation's macro.
336+
///
337+
/// # Returns
338+
/// * `T` - Whatever data the called function has returned.
339+
///
223340
pub unconstrained fn view(self, context: &mut PublicContext) -> T {
224341
let returns = context.static_call_public_function(
225342
self.target_contract,
@@ -232,6 +349,35 @@ where
232349
Deserialize::deserialize(returns.as_array())
233350
}
234351

352+
/// Enqueues a call to this public function, to be executed later.
353+
///
354+
/// Unlike private functions which execute immediately on the user's device,
355+
/// public function calls are "enqueued" and executed some time later by a
356+
/// block proposer.
357+
///
358+
/// This means a public function cannot return any values back to a private
359+
/// function, because by the time the public function is being executed,
360+
/// the private function which called it has already completed execution.
361+
/// (In fact, the private function has been executed and proven, along with
362+
/// all other private function calls of the user's tx. A single proof of the
363+
/// tx has been submitted to the Aztec network, and some time later a
364+
/// proposer has picked the tx up from the mempool and begun executing all
365+
/// of the enqueued public functions).
366+
///
367+
/// # Privacy warning
368+
/// Enqueueing a public function call is an inherently leaky action.
369+
/// Many interesting applications will require some interaction with public
370+
/// state, but smart contract developers should try to use public function
371+
/// calls sparingly, and carefully.
372+
/// _Internal_ public function calls are especially leaky, because they
373+
/// completely leak which private contract made the call.
374+
/// See also: https://docs.aztec.network/developers/reference/considerations/privacy_considerations
375+
///
376+
/// # Arguments
377+
/// * `context` - The PrivateContext -- made magically available to the body
378+
/// of every #[private] function as `context`, through the
379+
/// #[private] annotation's macro.
380+
///
235381
pub fn enqueue(self, context: &mut PrivateContext) {
236382
let calldata = self.args.push_front(self.selector.to_field());
237383
let calldata_hash = hash_calldata(calldata);
@@ -244,6 +390,17 @@ where
244390
)
245391
}
246392

393+
/// Enqueues a read-only call to this public function.
394+
///
395+
/// This is similar to Solidity's `staticcall`. The called function
396+
/// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
397+
/// calls are constrained to also be staticcalls.
398+
///
399+
/// # Arguments
400+
/// * `context` - The PrivateContext -- made magically available to the body
401+
/// of every #[private] function as `context`, through the
402+
/// #[private] annotation's macro.
403+
///
247404
pub fn enqueue_view(self, context: &mut PrivateContext) {
248405
let calldata = self.args.push_front(self.selector.to_field());
249406
let calldata_hash = hash_calldata(calldata);
@@ -256,6 +413,37 @@ where
256413
)
257414
}
258415

416+
/// Enqueues a call to this public function, and designates it to be the
417+
/// teardown function for this tx. Only one teardown function call can be
418+
/// made by a tx.
419+
///
420+
/// Niche function: Only wallet developers and paymaster contract developers
421+
/// (aka Fee-payment contracts) will need to make use of this function.
422+
///
423+
/// Aztec supports a three-phase execution model: setup, app logic, teardown.
424+
/// The phases exist to enable a fee payer to take on the risk of paying
425+
/// a transaction fee, safe in the knowledge that their payment (in whatever
426+
/// token or method the user chooses) will succeed, regardless of whether
427+
/// the app logic will succeed. The "setup" phase ensures the fee payer
428+
/// has sufficient balance to pay the proposer their fees.
429+
/// The teardown phase is primarily intended to: calculate exactly
430+
/// how much the user owes, based on gas consumption, and refund the user
431+
/// any change.
432+
///
433+
/// Note: in some cases, the cost of refunding the user (i.e. DA costs of
434+
/// tx side-effects) might exceed the refund amount. For app logic with
435+
/// fairly stable and predictable gas consumption, a material refund amount
436+
/// is unlikely. For app logic with unpredictable gas consumption, a
437+
/// refund might be important to the user (e.g. if a hefty function reverts
438+
/// very early). Wallet/FPC/Paymaster developers should be mindful of this.
439+
///
440+
/// See `enqueue` for more information about enqueuing public function calls.
441+
///
442+
/// # Arguments
443+
/// * `context` - The PrivateContext -- made magically available to the body
444+
/// of every #[private] function as `context`, through the
445+
/// #[private] annotation's macro.
446+
///
259447
pub fn set_as_teardown(self, context: &mut PrivateContext) {
260448
let calldata = self.args.push_front(self.selector.to_field());
261449
let calldata_hash = hash_calldata(calldata);
@@ -328,6 +516,22 @@ where
328516
self
329517
}
330518

519+
/// Makes the read-only call to this public function.
520+
///
521+
/// This is similar to Solidity's `staticcall`. The called function
522+
/// cannot modify state or emit events. Any nested calls are constrained to
523+
/// also be staticcalls.
524+
///
525+
/// Will revert if the called function reverts or runs out of gas.
526+
///
527+
/// # Arguments
528+
/// * `context` - The PublicContext -- made magically available to the body
529+
/// of every #[public] function as `context`, through the
530+
/// #[public] annotation's macro.
531+
///
532+
/// # Returns
533+
/// * `T` - Whatever data the called function has returned.
534+
///
331535
pub unconstrained fn view(self, context: &mut PublicContext) -> T {
332536
let returns = context.static_call_public_function(
333537
self.target_contract,
@@ -338,6 +542,17 @@ where
338542
Deserialize::deserialize(returns.as_array())
339543
}
340544

545+
/// Enqueues a read-only call to this public function.
546+
///
547+
/// This is similar to Solidity's `staticcall`. The called function
548+
/// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
549+
/// calls are constrained to also be staticcalls.
550+
///
551+
/// # Arguments
552+
/// * `context` - The PrivateContext -- made magically available to the body
553+
/// of every #[private] function as `context`, through the
554+
/// #[private] annotation's macro.
555+
///
341556
pub fn enqueue_view(self, context: &mut PrivateContext) {
342557
let calldata = self.args.push_front(self.selector.to_field());
343558
let calldata_hash = hash_calldata(calldata);

0 commit comments

Comments
 (0)