Skip to content

Commit 5981432

Browse files
authored
feat!: merge the txe session state transition oracles, redo the internal wiring, introduce context handlers (#16659)
This one leaves things in a bit of a messy state, as doing _the entire_ transition is unfeasiable, but the things that are ready _do_ look good, and it's a good starting place for future changes. The session now calls the translator (service) with a handler for state changes (the session itself) and a handler for all other calls. On session state transitions, a new handler is installed and the old one closed and committed to. There's now a handler for `public_context` which does the avm opcodes, and consequently the `txe_oracle` no longer knows how to process these (because it doesn't need to). I also cleaned up the state transition oracles to take all params in one go instead of relying on mutating global session state, which helps make this smoother and also helps with the cleanup and eventual removal of the `txe_oracle`.
2 parents 34eabaa + ad58ec4 commit 5981432

File tree

9 files changed

+495
-307
lines changed

9 files changed

+495
-307
lines changed

noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr

Lines changed: 38 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,11 @@ impl TestEnvironment {
149149
_self: Self,
150150
f: fn[Env](&mut PublicContext) -> T,
151151
) -> T {
152-
txe_oracles::set_public_txe_context();
152+
txe_oracles::set_public_txe_context(Option::none());
153153

154154
let mut context = PublicContext::new(|| 0);
155155
let ret_value = f(&mut context);
156156

157-
// merge calls below into 'exit public txe context' -> this mines a block
158-
txe_oracles::advance_blocks_by(1);
159157
txe_oracles::set_top_level_txe_context();
160158

161159
ret_value
@@ -164,17 +162,18 @@ impl TestEnvironment {
164162
/// Variant of `public_context` which allows specifying the contract address in which the public context will
165163
/// execute, which will affect note and nullifier siloing, storage access, etc.
166164
pub unconstrained fn public_context_at<Env, T>(
167-
self,
165+
_self: Self,
168166
addr: AztecAddress,
169167
f: fn[Env](&mut PublicContext) -> T,
170168
) -> T {
171-
// temporary hack until we reimplement the public context oracle and have it take this as a param
172-
let pre = txe_oracles::get_contract_address();
173-
txe_oracles::set_contract_address(addr);
174-
let ret = self.public_context(f);
175-
txe_oracles::set_contract_address(pre);
169+
txe_oracles::set_public_txe_context(Option::some(addr));
176170

177-
ret
171+
let mut context = PublicContext::new(|| 0);
172+
let ret_value = f(&mut context);
173+
174+
txe_oracles::set_top_level_txe_context();
175+
176+
ret_value
178177
}
179178

180179
/// Creates a `PrivateContext`, which allows using aztec-nr features as if inside a private contract function.
@@ -210,76 +209,58 @@ impl TestEnvironment {
210209
/// state_var.get_note()
211210
/// });
212211
/// ```
213-
pub unconstrained fn private_context<Env, T>(self, f: fn[Env](&mut PrivateContext) -> T) -> T {
214-
// merge the two oracles below - the creation of a context implies a transition to a private txe context. right
215-
// now we have them in this order because creating the private context requires reading the latest block number,
216-
// which we only allow for top level and utility
212+
pub unconstrained fn private_context<Env, T>(
213+
_self: Self,
214+
f: fn[Env](&mut PrivateContext) -> T,
215+
) -> T {
217216
let mut context = PrivateContext::new(
218-
txe_oracles::get_private_context_inputs(Option::some(self.last_block_number())),
217+
txe_oracles::set_private_txe_context(Option::none(), Option::none()),
219218
0,
220219
);
221-
txe_oracles::set_private_txe_context();
222220

223221
let ret_value = f(&mut context);
224-
txe_oracles::set_top_level_txe_context();
225222

226-
// todo: should commit the context to mine a block with the side effects of the context. we should have an
227-
// oracle that receives the context we produced probably
228-
self.mine_block();
223+
txe_oracles::set_top_level_txe_context();
229224

230225
ret_value
231226
}
232227

233228
/// Variant of `private_context` which allows specifying the contract address in which the private context will
234229
/// execute, which will affect note and nullifier siloing, storage access, etc.
235230
pub unconstrained fn private_context_at<Env, T>(
236-
self,
231+
_self: Self,
237232
addr: AztecAddress,
238233
f: fn[Env](&mut PrivateContext) -> T,
239234
) -> T {
240-
// temporary hack until we reimplement the public context oracle and have it take this as a param
241-
let pre = txe_oracles::get_contract_address();
242-
txe_oracles::set_contract_address(addr);
243-
let ret = self.private_context(f);
244-
txe_oracles::set_contract_address(pre);
235+
let mut context = PrivateContext::new(
236+
txe_oracles::set_private_txe_context(Option::some(addr), Option::none()),
237+
0,
238+
);
245239

246-
ret
240+
let ret_value = f(&mut context);
241+
242+
txe_oracles::set_top_level_txe_context();
243+
244+
ret_value
247245
}
248246

249247
/// Variant of `private_context` which allows specifying multiple configuration values via `PrivateContextOptions`.
250248
pub unconstrained fn private_context_opts<Env, T>(
251-
self,
249+
_self: Self,
252250
opts: PrivateContextOptions,
253251
f: fn[Env](&mut PrivateContext) -> T,
254252
) -> T {
255-
// temporary hack until we reimplement the public context oracle and have it take this as a param
256-
257-
let pre_contract_address = txe_oracles::get_contract_address();
258-
259-
if opts.contract_address.is_some() {
260-
txe_oracles::set_contract_address(opts.contract_address.unwrap());
261-
}
262-
263-
// merge the two oracles below - the creation of a context implies a transition to a private txe context. right
264-
// now we have them in this order because creating the private context requires reading the latest block number,
265-
// which we only allow for top level and utility
266253
let mut context = PrivateContext::new(
267-
txe_oracles::get_private_context_inputs(opts.historical_block_number.or_else(|| {
268-
Option::some(self.last_block_number())
269-
})),
254+
txe_oracles::set_private_txe_context(
255+
opts.contract_address,
256+
opts.historical_block_number,
257+
),
270258
0,
271259
);
272260

273-
txe_oracles::set_private_txe_context();
274-
275261
let ret_value = f(&mut context);
276-
txe_oracles::set_top_level_txe_context();
277-
278-
// todo: should commit the context to mine a block with the side effects of the context. we should have an
279-
// oracle that receives the context we produced probably
280-
self.mine_block();
281262

282-
txe_oracles::set_contract_address(pre_contract_address);
263+
txe_oracles::set_top_level_txe_context();
283264

284265
ret_value
285266
}
@@ -314,7 +295,7 @@ impl TestEnvironment {
314295
_self: Self,
315296
f: fn[Env](UtilityContext) -> T,
316297
) -> T {
317-
txe_oracles::set_utility_txe_context();
298+
txe_oracles::set_utility_txe_context(Option::none());
318299
let context = UtilityContext::new();
319300
let ret_value = f(context);
320301
txe_oracles::set_top_level_txe_context();
@@ -325,17 +306,16 @@ impl TestEnvironment {
325306
/// Variant of `utility_context` which allows specifying the contract address in which the utility context will
326307
/// execute, which will affect note and storage access.
327308
pub unconstrained fn utility_context_at<Env, T>(
328-
self,
309+
_self: Self,
329310
addr: AztecAddress,
330311
f: fn[Env](UtilityContext) -> T,
331312
) -> T {
332-
// temporary hack until we reimplement the utility context oracle and have it take this as a param
333-
let pre = txe_oracles::get_contract_address();
334-
txe_oracles::set_contract_address(addr);
335-
let ret = self.utility_context(f);
336-
txe_oracles::set_contract_address(pre);
313+
txe_oracles::set_utility_txe_context(Option::some(addr));
314+
let context = UtilityContext::new();
315+
let ret_value = f(context);
316+
txe_oracles::set_top_level_txe_context();
337317

338-
ret
318+
ret_value
339319
}
340320

341321
/// Returns the number of the next block to be mined.

noir-projects/aztec-nr/aztec/src/test/helpers/txe_oracles.nr

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,12 @@ pub unconstrained fn public_call_new_flow(
6565
#[oracle(txeGetLastBlockTimestamp)]
6666
pub unconstrained fn get_last_block_timestamp() -> u64 {}
6767

68-
#[oracle(txeSetContractAddress)]
69-
pub unconstrained fn set_contract_address(address: AztecAddress) {}
70-
71-
#[oracle(utilityGetContractAddress)]
72-
pub unconstrained fn get_contract_address() -> AztecAddress {}
73-
7468
#[oracle(txeAdvanceBlocksBy)]
7569
pub unconstrained fn advance_blocks_by(blocks: u32) {}
7670

7771
#[oracle(txeAdvanceTimestampBy)]
7872
pub unconstrained fn advance_timestamp_by(duration: u64) {}
7973

80-
#[oracle(txeGetPrivateContextInputs)]
81-
pub unconstrained fn get_private_context_inputs(
82-
historical_block_number: Option<u32>,
83-
) -> PrivateContextInputs {}
84-
8574
#[oracle(txeDeploy)]
8675
pub unconstrained fn deploy_oracle<let N: u32, let P: u32>(
8776
path: str<N>,
@@ -121,10 +110,13 @@ unconstrained fn public_call_new_flow_oracle(
121110
pub unconstrained fn set_top_level_txe_context() {}
122111

123112
#[oracle(txeSetPrivateTXEContext)]
124-
pub unconstrained fn set_private_txe_context() {}
113+
pub unconstrained fn set_private_txe_context(
114+
contract_address: Option<AztecAddress>,
115+
historical_block_number: Option<u32>,
116+
) -> PrivateContextInputs {}
125117

126118
#[oracle(txeSetPublicTXEContext)]
127-
pub unconstrained fn set_public_txe_context() {}
119+
pub unconstrained fn set_public_txe_context(contract_address: Option<AztecAddress>) {}
128120

129121
#[oracle(txeSetUtilityTXEContext)]
130-
pub unconstrained fn set_utility_txe_context() {}
122+
pub unconstrained fn set_utility_txe_context(contract_address: Option<AztecAddress>) {}

noir-projects/aztec-nr/aztec/src/utils/with_hash.nr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ where
120120

121121
mod test {
122122
use crate::{
123-
oracle::random::random,
124123
test::{helpers::test_environment::TestEnvironment, mocks::mock_struct::MockStruct},
125124
utils::with_hash::WithHash,
126125
};
@@ -211,7 +210,7 @@ mod test {
211210
let value = MockStruct { a: 5, b: 3 };
212211
context.storage_write(STORAGE_SLOT, value);
213212

214-
let incorrect_hash = random();
213+
let incorrect_hash = 13;
215214
let hash_storage_slot = STORAGE_SLOT + (value.pack().len() as Field);
216215
context.storage_write(hash_storage_slot, [incorrect_hash]);
217216
});

yarn-project/txe/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type TXEForeignCallInput = {
5555
inputs: ForeignCallArgs;
5656
};
5757

58+
// TODO: why does the zod validation in the txe dispatcher not reject invalid function names?
5859
const TXEForeignCallInputSchema = z.object({
5960
// eslint-disable-next-line camelcase
6061
session_id: z.number().int().nonnegative(),

0 commit comments

Comments
 (0)