Skip to content

Commit ad58ec4

Browse files
committed
feat!: merge the txe session state transition oracles, redo the internal wiring, introduce context handlers
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`.
1 parent 87fc924 commit ad58ec4

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
@@ -144,13 +144,11 @@ impl TestEnvironment {
144144
_self: Self,
145145
f: fn[Env](&mut PublicContext) -> T,
146146
) -> T {
147-
txe_oracles::set_public_txe_context();
147+
txe_oracles::set_public_txe_context(Option::none());
148148

149149
let mut context = PublicContext::new(|| 0);
150150
let ret_value = f(&mut context);
151151

152-
// merge calls below into 'exit public txe context' -> this mines a block
153-
txe_oracles::advance_blocks_by(1);
154152
txe_oracles::set_top_level_txe_context();
155153

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

172-
ret
166+
let mut context = PublicContext::new(|| 0);
167+
let ret_value = f(&mut context);
168+
169+
txe_oracles::set_top_level_txe_context();
170+
171+
ret_value
173172
}
174173

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

218216
let ret_value = f(&mut context);
219-
txe_oracles::set_top_level_txe_context();
220217

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

225220
ret_value
226221
}
227222

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

241-
ret
235+
let ret_value = f(&mut context);
236+
237+
txe_oracles::set_top_level_txe_context();
238+
239+
ret_value
242240
}
243241

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

268-
txe_oracles::set_private_txe_context();
269-
270256
let ret_value = f(&mut context);
271-
txe_oracles::set_top_level_txe_context();
272-
273-
// todo: should commit the context to mine a block with the side effects of the context. we should have an
274-
// oracle that receives the context we produced probably
275-
self.mine_block();
276257

277-
txe_oracles::set_contract_address(pre_contract_address);
258+
txe_oracles::set_top_level_txe_context();
278259

279260
ret_value
280261
}
@@ -309,7 +290,7 @@ impl TestEnvironment {
309290
_self: Self,
310291
f: fn[Env](UtilityContext) -> T,
311292
) -> T {
312-
txe_oracles::set_utility_txe_context();
293+
txe_oracles::set_utility_txe_context(Option::none());
313294
let context = UtilityContext::new();
314295
let ret_value = f(context);
315296
txe_oracles::set_top_level_txe_context();
@@ -320,17 +301,16 @@ impl TestEnvironment {
320301
/// Variant of `utility_context` which allows specifying the contract address in which the utility context will
321302
/// execute, which will affect note and storage access.
322303
pub unconstrained fn utility_context_at<Env, T>(
323-
self,
304+
_self: Self,
324305
addr: AztecAddress,
325306
f: fn[Env](UtilityContext) -> T,
326307
) -> T {
327-
// temporary hack until we reimplement the utility context oracle and have it take this as a param
328-
let pre = txe_oracles::get_contract_address();
329-
txe_oracles::set_contract_address(addr);
330-
let ret = self.utility_context(f);
331-
txe_oracles::set_contract_address(pre);
308+
txe_oracles::set_utility_txe_context(Option::some(addr));
309+
let context = UtilityContext::new();
310+
let ret_value = f(context);
311+
txe_oracles::set_top_level_txe_context();
332312

333-
ret
313+
ret_value
334314
}
335315

336316
/// 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)