Skip to content

Commit

Permalink
failure case
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Dec 14, 2023
1 parent a542d70 commit 1517700
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 11 deletions.
5 changes: 5 additions & 0 deletions yarn-project/aztec-nr/aztec/src/history/contract_inclusion.nr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ use crate::{
oracle::get_membership_witness::get_contract_membership_witness,
};

// Proves that the contract address, portal address and function tree root form a valid contract preimage of a leaf
// which exists at block `block_number`.
// Note: This can be used to approximate a factory pattern --> a factory contract could perform this proof and that
// way verify that a contract at a given address is what it expects. Then it could store it in an internal
// map of contracts (like what Uniswap Factory does with pool contracts - it stores them in a mapping).
pub fn prove_contract_inclusion(
contract_address: AztecAddress,
portal_contract_address: EthAddress,
Expand Down
49 changes: 40 additions & 9 deletions yarn-project/end-to-end/src/e2e_inclusion_proofs_contract.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { AccountWallet, AztecAddress, CompleteAddress, Fr, INITIAL_L2_BLOCK_NUM, PXE } from '@aztec/aztec.js';
import { FunctionSelector, generateFunctionLeaves } from '@aztec/circuits.js';
import {
AccountWallet,
AztecAddress,
CompleteAddress,
Fr,
FunctionSelector,
INITIAL_L2_BLOCK_NUM,
PXE,
} from '@aztec/aztec.js';
import { generateFunctionLeaves } from '@aztec/circuits.js';
import { computeFunctionTreeRoot } from '@aztec/circuits.js/abis';
import { InclusionProofsContract } from '@aztec/noir-contracts/types';

Expand All @@ -23,6 +31,7 @@ describe('e2e_inclusion_proofs_contract', () => {
let contract: InclusionProofsContract;
let deploymentBlockNumber: number;
const publicValue = 236n;
let contractFunctionTreeRoot: Fr;

beforeAll(async () => {
({ pxe, teardown, wallets, accounts } = await setup(1));
Expand Down Expand Up @@ -167,20 +176,30 @@ describe('e2e_inclusion_proofs_contract', () => {

const contractAddress = contract.address;
const portalContractAddress = contract.portalContract;

const functions = contract.artifact.functions.map(f => ({
...f,
selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters),
}));
const functionLeaves = generateFunctionLeaves(functions);
const functionTreeRoot = computeFunctionTreeRoot(functionLeaves);
const functionTreeRoot = getContractFunctionTreeRoot();

await contract.methods
.test_contract_inclusion_proof(contractAddress, portalContractAddress, functionTreeRoot, blockNumber)
.send()
.wait();
});

it('contract existence failure case', async () => {
// This should fail because we choose a block number before the contract was deployed
const blockNumber = deploymentBlockNumber - 1;

const contractAddress = contract.address;
const portalContractAddress = contract.portalContract;
const functionTreeRoot = getContractFunctionTreeRoot();

await expect(
contract.methods
.test_contract_inclusion_proof(contractAddress, portalContractAddress, functionTreeRoot, blockNumber)
.send()
.wait(),
).rejects.toThrow(/Leaf value: 0x[0-9a-fA-F]+ not found in CONTRACT_TREE/);
});

const getRandomBlockNumberSinceDeployment = async () => {
const currentBlockNumber = await pxe.getBlockNumber();
return deploymentBlockNumber + Math.floor(Math.random() * (currentBlockNumber - deploymentBlockNumber));
Expand All @@ -190,4 +209,16 @@ describe('e2e_inclusion_proofs_contract', () => {
const currentBlockNumber = await pxe.getBlockNumber();
return deploymentBlockNumber + Math.floor(Math.random() * (currentBlockNumber - INITIAL_L2_BLOCK_NUM));
};

const getContractFunctionTreeRoot = () => {
if (!contractFunctionTreeRoot) {
const functions = contract.artifact.functions.map(f => ({
...f,
selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters),
}));
const functionLeaves = generateFunctionLeaves(functions);
contractFunctionTreeRoot = computeFunctionTreeRoot(functionLeaves);
}
return contractFunctionTreeRoot;
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ contract InclusionProofs {
// Proves that the contract address, portal address and function tree root form a valid contract preimage of a leaf
// which exists at block `block_number`.
// Note: This can be used to approximate a factory pattern --> a factory contract could perform this proof and that
// way verify that a contract at a given address is what it expects. Then it could store in an internal map
// of contracts (similarily to what Uniswap Factory does with pool contracts).
// way verify that a contract at a given address is what it expects. Then it could store it in an internal
// map of contracts (like what Uniswap Factory does with pool contracts - it stores them in a mapping).
#[aztec(private)]
fn test_contract_inclusion_proof(
contract_address: AztecAddress,
Expand Down

0 comments on commit 1517700

Please sign in to comment.