Skip to content

feat(aztec-nr)!: add msg_sender to the utility context#24062

Open
nchamo wants to merge 2 commits into
merge-train/fairies-v5from
nchamo/f-671-add-msg_sender-to-utility-context
Open

feat(aztec-nr)!: add msg_sender to the utility context#24062
nchamo wants to merge 2 commits into
merge-train/fairies-v5from
nchamo/f-671-add-msg_sender-to-utility-context

Conversation

@nchamo

@nchamo nchamo commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Why we are doing this

Utility functions had no notion of msg_sender, so a utility that wanted to know its caller had to accept it as a forgeable parameter. HandshakeRegistry::get_app_siloed_secret took an explicit caller argument and siloed the returned secret by it, so a hostile contract could lie about caller and read another app's siloed secret.

Our fix

  • UtilityContext now carries a real msg_sender, set by the simulator on dispatch: nested calls (utility-to-utility or private-to-utility) observe the calling contract's address, and top-level calls observe the from supplied for the simulation. It is exposed as self.msg_sender() and self.context.maybe_msg_sender(), mirroring the private and public contexts.
  • .simulate({ from }) on a utility now sets the top-level msg_sender in addition to determining note/key visibility. Wallet.executeUtility takes { from, additionalScopes } instead of { scopes }.
  • HandshakeRegistry::get_app_siloed_secret drops the forgeable caller parameter and silos by self.msg_sender().

Migration

Covered in the new migration_notes.md entry: TestEnvironment::execute_utility / execute_utility_opts take a leading from, and Wallet.executeUtility options change from { scopes } to { from, additionalScopes }.

Fixes F-671

@nchamo nchamo requested review from a team and nventuro as code owners June 12, 2026 16:43
@nchamo nchamo self-assigned this Jun 12, 2026
Comment thread docs/docs-developers/docs/aztec-nr/testing_contracts.md Outdated
Comment thread docs/docs-developers/docs/resources/migration_notes.md Outdated
Comment thread docs/docs-developers/docs/resources/migration_notes.md
Comment thread noir-projects/aztec-nr/aztec/src/context/utility_context.nr Outdated

if handshake.is_initialized() {
Option::some(handshake.view_note().siloed_for(caller))
Option::some(handshake.view_note().siloed_for(self.msg_sender()))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What if an app invokes this function directly, with an arbitrary from? Wouldn't we be then exposing all of the siloed secrets to the app for all from contracts, letting the app find all onchain activity?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, but isn't it the responsibility of the wallet to prevent that from happening? I mean, an app could also try to get balances for all tokens and accounts, right?

@nchamo nchamo added the ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure label Jun 12, 2026
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as private`);
}

if (request.origin !== contractAddress) {

@nchamo nchamo Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We are now simply avoiding the extra param and doing:

const contractAddress = request.origin;

}

/** The address of the contract whose function is being executed, from the call context. */
protected get contractAddress(): AztecAddress {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added this to avoid changing over 50 this.contractAddress to this.callContext.contractAddress

export type PrivateExecutionOracleArgs = UtilityExecutionOracleArgs & {
argsHash: Fr;
txContext: TxContext;
callContext: CallContext;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved into UtilityOracle

* The caller address: it becomes the utility's `msg_sender` and determines which notes and keys are visible
* during execution. Pass `NO_FROM` when there is no acting account.
*/
from: AztecAddress | NoFrom;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Made this change to keep it consistent with proveTx and simulateTx

@nchamo nchamo requested a review from nventuro June 12, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants