Skip to content

Commit 20cec85

Browse files
committed
chore: re-enable some avm proving tests
1 parent a3aae5a commit 20cec85

File tree

13 files changed

+163
-114
lines changed

13 files changed

+163
-114
lines changed

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

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -881,22 +881,15 @@ pub unconstrained fn calldata_copy<let N: u32>(cdoffset: u32, copy_size: u32) ->
881881
}
882882

883883
// `success_copy` is placed immediately after the CALL opcode to get the success value
884-
//
885-
// This function is temporarily exposed publicly to be able to test it in AVMTest contract.
886-
// TODO: Refactor tests to keep this implementation detail private within the crate.
887-
pub unconstrained fn success_copy() -> bool {
884+
unconstrained fn success_copy() -> bool {
888885
success_copy_opcode()
889886
}
890887

891-
// This function is temporarily exposed publicly to be able to test it in AVMTest contract.
892-
// TODO: Refactor tests to keep this implementation detail private within the crate.
893-
pub unconstrained fn returndata_size() -> u32 {
888+
unconstrained fn returndata_size() -> u32 {
894889
returndata_size_opcode()
895890
}
896891

897-
// This function is temporarily exposed publicly to be able to test it in AVMTest contract.
898-
// TODO: Refactor tests to keep this implementation detail private within the crate.
899-
pub unconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {
892+
unconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {
900893
returndata_copy_opcode(rdoffset, copy_size)
901894
}
902895

@@ -908,10 +901,7 @@ pub unconstrained fn avm_return(returndata: [Field]) {
908901
// to do rethrows, where the revert data is the same as the original revert data.
909902
// For normal reverts, use Noir's `assert` which, on top of reverting, will also add
910903
// an error selector to the revert data.
911-
//
912-
// This function is temporarily exposed publicly to be able to test it in AVMTest contract.
913-
// TODO: Refactor tests to keep this implementation detail private within the crate.
914-
pub unconstrained fn avm_revert(revertdata: [Field]) {
904+
unconstrained fn avm_revert(revertdata: [Field]) {
915905
revert_opcode(revertdata)
916906
}
917907

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use dep::aztec::protocol_types::address::AztecAddress;
2+
3+
pub unconstrained fn call(
4+
l2_gas_allocation: u32,
5+
da_gas_allocation: u32,
6+
address: AztecAddress,
7+
args: [Field],
8+
) {
9+
call_opcode(l2_gas_allocation, da_gas_allocation, address, args)
10+
}
11+
12+
pub unconstrained fn success_copy() -> bool {
13+
success_copy_opcode()
14+
}
15+
16+
pub unconstrained fn returndata_size() -> u32 {
17+
returndata_size_opcode()
18+
}
19+
20+
pub unconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {
21+
returndata_copy_opcode(rdoffset, copy_size)
22+
}
23+
24+
pub unconstrained fn avm_return(returndata: [Field]) {
25+
return_opcode(returndata)
26+
}
27+
28+
pub unconstrained fn avm_revert(revertdata: [Field]) {
29+
revert_opcode(revertdata)
30+
}
31+
32+
#[oracle(avmOpcodeCall)]
33+
unconstrained fn call_opcode(
34+
l2_gas_allocation: u32,
35+
da_gas_allocation: u32,
36+
address: AztecAddress,
37+
args: [Field],
38+
) {}
39+
40+
#[oracle(avmOpcodeSuccessCopy)]
41+
unconstrained fn success_copy_opcode() -> bool {}
42+
43+
#[oracle(avmOpcodeReturndataSize)]
44+
unconstrained fn returndata_size_opcode() -> u32 {}
45+
46+
#[oracle(avmOpcodeReturndataCopy)]
47+
unconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}
48+
49+
#[oracle(avmOpcodeReturn)]
50+
unconstrained fn return_opcode(returndata: [Field]) {}
51+
52+
#[oracle(avmOpcodeRevert)]
53+
unconstrained fn revert_opcode(revertdata: [Field]) {}

noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod note;
2+
mod fake_public_context;
23
use dep::aztec::macros::aztec;
34

45
#[aztec]
@@ -11,12 +12,16 @@ pub contract AvmTest {
1112
0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;
1213

1314
// Libs
15+
use crate::fake_public_context::{
16+
avm_return, avm_revert, call, returndata_copy, returndata_size, success_copy,
17+
};
1418
use dep::aztec::context::gas::GasOpts;
1519
use dep::aztec::macros::{functions::{private, public}, storage::storage};
1620
use dep::aztec::oracle::get_contract_instance::{
1721
get_contract_instance_class_id_avm, get_contract_instance_deployer_avm,
1822
get_contract_instance_initialization_hash_avm,
1923
};
24+
use dep::aztec::protocol_types::abis::function_selector::FunctionSelector;
2025
use dep::aztec::protocol_types::{
2126
address::{AztecAddress, EthAddress},
2227
point::Point,
@@ -26,7 +31,7 @@ pub contract AvmTest {
2631
constants::{GRUMPKIN_ONE_X, GRUMPKIN_ONE_Y, MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS},
2732
contract_class_id::ContractClassId,
2833
storage::map::derive_storage_slot_in_map,
29-
traits::{Empty, FromField},
34+
traits::{Empty, FromField, ToField},
3035
};
3136
use dep::aztec::state_vars::Map;
3237
use dep::aztec::state_vars::PublicMutable;
@@ -267,35 +272,34 @@ pub contract AvmTest {
267272
let _ = AvmTest::at(context.this_address()).divide_by_zero().call(&mut context);
268273
}
269274

270-
// TODO(#16099): Re-enable this test
271-
// #[public]
272-
// fn external_call_to_divide_by_zero_recovers() {
273-
// // Be sure to allocate ~200k+ gas to this function~
274-
275-
// // Get the gas remaining and allocate some smaller amount to nested call.
276-
// // We don't want to allocate too much to the nested call
277-
// // since it will all be consumed on exceptional halt.
278-
// let l2_gas_left = context.l2_gas_left();
279-
// let da_gas_left = context.da_gas_left();
280-
// let selector = FunctionSelector::from_signature("divide_by_zero()");
281-
282-
// // Call without capturing a return value since call no longer returns success
283-
// call(
284-
// l2_gas_left - 200_000,
285-
// da_gas_left - 200_000,
286-
// context.this_address(),
287-
// &[selector.to_field()],
288-
// );
289-
290-
// // Use SUCCESSCOPY to get the success status
291-
// let success = success_copy();
292-
293-
// assert(!success, "Nested CALL instruction should return failure on exceptional halt");
294-
// assert(
295-
// returndata_size() == 0,
296-
// "Returndata should be empty when nested call exceptionally halts",
297-
// );
298-
// }
275+
#[public]
276+
fn external_call_to_divide_by_zero_recovers() {
277+
// Be sure to allocate ~200k+ gas to this function~
278+
279+
// Get the gas remaining and allocate some smaller amount to nested call.
280+
// We don't want to allocate too much to the nested call
281+
// since it will all be consumed on exceptional halt.
282+
let l2_gas_left = context.l2_gas_left();
283+
let da_gas_left = context.da_gas_left();
284+
let selector = FunctionSelector::from_signature("divide_by_zero()");
285+
286+
// Call without capturing a return value since call no longer returns success
287+
call(
288+
l2_gas_left - 200_000,
289+
da_gas_left - 200_000,
290+
context.this_address(),
291+
&[selector.to_field()],
292+
);
293+
294+
// Use SUCCESSCOPY to get the success status
295+
let success = success_copy();
296+
297+
assert(!success, "Nested CALL instruction should return failure on exceptional halt");
298+
assert(
299+
returndata_size() == 0,
300+
"Returndata should be empty when nested call exceptionally halts",
301+
);
302+
}
299303

300304
#[public]
301305
fn debug_logging() {
@@ -321,20 +325,20 @@ pub contract AvmTest {
321325
#[public]
322326
fn returndata_copy_oracle() {
323327
let _ = AvmTest::at(context.this_address()).return_oracle().call(&mut context);
324-
let returndatasize = dep::aztec::context::public_context::returndata_size();
325-
let returndata = dep::aztec::context::public_context::returndata_copy(0, returndatasize);
328+
let returndatasize = returndata_size();
329+
let returndata = returndata_copy(0, returndatasize);
326330
assert(returndata == &[1, 2, 3], "Returndata copy failed");
327331
}
328332

329333
#[public]
330334
fn return_oracle() -> [Field; 3] {
331-
dep::aztec::context::public_context::avm_return([1, 2, 3]);
335+
avm_return([1, 2, 3]);
332336
[4, 5, 6] // Should not get here.
333337
}
334338

335339
#[public]
336340
fn revert_oracle() -> [Field; 3] {
337-
dep::aztec::context::public_context::avm_revert([1, 2, 3]);
341+
avm_revert([1, 2, 3]);
338342
[4, 5, 6] // Should not get here.
339343
}
340344

@@ -557,17 +561,16 @@ pub contract AvmTest {
557561
AvmTest::at(garbageAddress).nested_call_to_nothing().call(&mut context)
558562
}
559563

560-
// TODO(#16099): Re-enable this test
561-
// #[public]
562-
// fn nested_call_to_nothing_recovers() {
563-
// let garbageAddress = AztecAddress::from_field(42);
564-
// call(1, 1, garbageAddress, &[]);
565-
// let success = success_copy();
566-
// assert(
567-
// !success,
568-
// "Nested CALL instruction should return failure if target contract does not exist",
569-
// );
570-
// }
564+
#[public]
565+
fn nested_call_to_nothing_recovers() {
566+
let garbageAddress = AztecAddress::from_field(42);
567+
call(1, 1, garbageAddress, &[]);
568+
let success = success_copy();
569+
assert(
570+
!success,
571+
"Nested CALL instruction should return failure if target contract does not exist",
572+
);
573+
}
571574

572575
#[public]
573576
fn nested_call_to_add_with_gas(

yarn-project/bb-prover/src/avm_proving_tests/avm_bulk.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ describe('AVM proven bulk test', () => {
3434
it(
3535
'Prove and verify',
3636
async () => {
37-
await bulkTest(tester, logger, AvmTestContractArtifact, (b: boolean) => expect(b).toBe(true));
37+
const result = await bulkTest(tester, logger, AvmTestContractArtifact);
38+
expect(result.revertCode.isOK()).toBe(true);
3839
},
3940
TIMEOUT,
4041
);

yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit1.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { AvmProvingTester } from './avm_proving_tester.js';
1414

1515
const TIMEOUT = 30_000;
1616

17-
describe.skip('AVM check-circuit – unhappy paths 1', () => {
17+
describe('AVM check-circuit – unhappy paths 1', () => {
1818
let avmTestContractInstance: ContractInstanceWithAddress;
1919
let tester: AvmProvingTester;
2020

yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit2.test.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('AVM check-circuit – unhappy paths 2', () => {
2121
);
2222
});
2323

24-
it.skip(
24+
it(
2525
'an exceptional halt due to a nested call to non-existent contract is propagated to top-level',
2626
async () => {
2727
await tester.simProveVerifyAppLogic(
@@ -32,38 +32,44 @@ describe('AVM check-circuit – unhappy paths 2', () => {
3232
TIMEOUT,
3333
);
3434

35-
// TODO(#16099): Re-enable this test
36-
// it(
37-
// 'an exceptional halt due to a nested call to non-existent contract is recovered from in caller',
38-
// async () => {
39-
// await tester.simProveVerifyAppLogic(
40-
// { address: avmTestContractInstance.address, fnName: 'nested_call_to_nothing_recovers', args: [] },
41-
// /*expectRevert=*/ false,
42-
// );
43-
// },
44-
// TIMEOUT,
45-
// );
35+
it(
36+
'an exceptional halt due to a nested call to non-existent contract is recovered from in caller',
37+
async () => {
38+
await tester.simProveVerifyAppLogic(
39+
{ address: avmTestContractInstance.address, fnName: 'nested_call_to_nothing_recovers', args: [] },
40+
/*expectRevert=*/ false,
41+
);
42+
},
43+
TIMEOUT,
44+
);
4645

47-
it.skip('top-level exceptional halts due to a non-existent contract in app-logic and teardown', async () => {
46+
it('top-level exceptional halts due to a non-existent contract in app-logic and teardown', async () => {
4847
// don't insert contracts into trees, and make sure retrieval fails
4948
const tester = await AvmProvingTester.new(/*checkCircuitOnly=*/ true);
49+
// Note: we need to specify the contract artifacts here because we intentionally skip registration,
50+
// so the tester can't retrieve them on its own.
5051
await tester.simProveVerify(
5152
sender,
5253
/*setupCalls=*/ [],
5354
/*appCalls=*/ [
54-
{ address: avmTestContractInstance.address, fnName: 'add_args_return', args: [new Fr(1), new Fr(2)] },
55+
{
56+
address: avmTestContractInstance.address,
57+
fnName: 'add_args_return',
58+
args: [new Fr(1), new Fr(2)],
59+
contractArtifact: AvmTestContractArtifact,
60+
},
5561
],
5662
/*teardownCall=*/ {
5763
address: avmTestContractInstance.address,
5864
fnName: 'add_args_return',
5965
args: [new Fr(1), new Fr(2)],
66+
contractArtifact: AvmTestContractArtifact,
6067
},
6168
/*expectRevert=*/ true,
6269
);
6370
});
6471

65-
// TODO: unskip once internalcall constraints are fixed (DEFAULT_PROPAGATE_CALL_ID in particular)
66-
it.skip(
72+
it(
6773
'enqueued calls in every phase, with enqueued calls that depend on each other',
6874
async () => {
6975
await tester.simProveVerify(
@@ -86,7 +92,7 @@ describe('AVM check-circuit – unhappy paths 2', () => {
8692
},
8793
TIMEOUT,
8894
);
89-
it.skip(
95+
it(
9096
'Should prove and verify a TX that reverts in teardown',
9197
async () => {
9298
await tester.simProveVerify(

yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit3.test.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AvmProvingTester } from './avm_proving_tester.js';
77

88
const TIMEOUT = 100_000;
99

10-
describe.skip('AVM check-circuit – unhappy paths 3', () => {
10+
describe('AVM check-circuit – unhappy paths 3', () => {
1111
const sender = AztecAddress.fromNumber(42);
1212
let avmTestContractInstance: ContractInstanceWithAddress;
1313
let tester: AvmProvingTester;
@@ -77,15 +77,14 @@ describe.skip('AVM check-circuit – unhappy paths 3', () => {
7777
TIMEOUT,
7878
);
7979

80-
// TODO(#16099): Re-enable this test
81-
// it(
82-
// 'a nested exceptional halt is recovered from in caller',
83-
// async () => {
84-
// await tester.simProveVerifyAppLogic(
85-
// { address: avmTestContractInstance.address, fnName: 'external_call_to_divide_by_zero_recovers', args: [] },
86-
// /*expectRevert=*/ false,
87-
// );
88-
// },
89-
// TIMEOUT,
90-
// );
80+
it(
81+
'a nested exceptional halt is recovered from in caller',
82+
async () => {
83+
await tester.simProveVerifyAppLogic(
84+
{ address: avmTestContractInstance.address, fnName: 'external_call_to_divide_by_zero_recovers', args: [] },
85+
/*expectRevert=*/ false,
86+
);
87+
},
88+
TIMEOUT,
89+
);
9190
});

yarn-project/bb-prover/src/avm_proving_tests/avm_check_circuit_amm.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import path from 'path';
88

99
import { AvmProvingTester } from './avm_proving_tester.js';
1010

11-
const TIMEOUT = 300_000;
11+
const TIMEOUT = 60_000;
1212

1313
describe('AVM proven AMM', () => {
1414
const logger = createLogger('avm-proven-tests-amm');

yarn-project/bb-prover/src/avm_proving_tests/avm_mega_bulk.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ describe.skip('AVM proven MEGA bulk test', () => {
3535
it(
3636
'Prove and verify mega bulk test',
3737
async () => {
38-
await megaBulkTest(tester, logger, AvmTestContractArtifact, (b: boolean) => expect(b).toBe(true));
38+
const result = await megaBulkTest(tester, logger, AvmTestContractArtifact);
39+
expect(result.revertCode.isOK()).toBe(true);
3940
},
4041
TIMEOUT,
4142
);

0 commit comments

Comments
 (0)