Skip to content

Commit 10eb33e

Browse files
author
sklppy88
committed
init
1 parent 3d61bdf commit 10eb33e

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

yarn-project/circuit-types/src/interfaces/pxe.ts

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
type CompleteAddress,
44
type Fq,
55
type Fr,
6+
type L1_TO_L2_MSG_TREE_HEIGHT,
67
type PartialAddress,
78
type Point,
89
} from '@aztec/circuits.js';
@@ -19,6 +20,7 @@ import { type L2Block } from '../l2_block.js';
1920
import { type GetUnencryptedLogsResponse, type L1EventPayload, type LogFilter } from '../logs/index.js';
2021
import { type IncomingNotesFilter } from '../notes/incoming_notes_filter.js';
2122
import { type ExtendedNote, type OutgoingNotesFilter, type UniqueNote } from '../notes/index.js';
23+
import { type SiblingPath } from '../sibling_path/sibling_path.js';
2224
import { type NoteProcessorStats } from '../stats/stats.js';
2325
import { type SimulatedTx, type Tx, type TxHash, type TxReceipt } from '../tx/index.js';
2426
import { type TxEffect } from '../tx_effect.js';
@@ -239,6 +241,12 @@ export interface PXE {
239241
*/
240242
getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]>;
241243

244+
getL1ToL2MembershipWitness(
245+
contractAddress: AztecAddress,
246+
messageHash: Fr,
247+
secret: Fr,
248+
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined>;
249+
242250
/**
243251
* Gets outgoing notes of accounts registered in this PXE based on the provided filter.
244252
* @param filter - The filter to apply to the notes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { type AztecAddress, type Fr, createCompatibleClient } from '@aztec/aztec.js';
2+
import { type DebugLogger, type LogFn } from '@aztec/foundation/log';
3+
4+
export async function getL1ToL2MessageWitness(
5+
rpcUrl: string,
6+
contractAddress: AztecAddress,
7+
messageHash: Fr,
8+
secret: Fr,
9+
debugLogger: DebugLogger,
10+
log: LogFn,
11+
) {
12+
const client = await createCompatibleClient(rpcUrl, debugLogger);
13+
const messageWitness = await client.getL1ToL2MembershipWitness(contractAddress, messageHash, secret);
14+
15+
log(
16+
messageWitness === undefined
17+
? `
18+
L1 to L2 Message not found.
19+
`
20+
: `
21+
L1 to L2 message index: ${messageWitness[0]}
22+
L1 to L2 message sibling path: ${messageWitness[1]}
23+
`,
24+
);
25+
}

yarn-project/cli/src/cmds/pxe/index.ts

+13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
logJson,
88
parseAztecAddress,
99
parseEthereumAddress,
10+
parseField,
1011
parseFieldFromHexString,
1112
parseOptionalAztecAddress,
1213
parseOptionalInteger,
@@ -165,6 +166,18 @@ export function injectCommands(program: Command, log: LogFn, debugLogger: DebugL
165166
await blockNumber(options.rpcUrl, debugLogger, log);
166167
});
167168

169+
program
170+
.command('get-l1-to-l2-message-witness')
171+
.description('Gets a L1 to L2 message witness.')
172+
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.', parseAztecAddress)
173+
.requiredOption('--message-hash <messageHash>', 'The message hash.', parseField)
174+
.requiredOption('-secret <secret>', 'The secret used to claim the L1 to L2 message', parseField)
175+
.addOption(pxeOption)
176+
.action(async ({ contractAddress, messageHash, secret, rpcUrl }) => {
177+
const { getL1ToL2MessageWitness } = await import('./get_l1_to_l2_message_witness.js');
178+
await getL1ToL2MessageWitness(rpcUrl, contractAddress, messageHash, secret, debugLogger, log);
179+
});
180+
168181
program
169182
.command('get-node-info')
170183
.description('Gets the information of an aztec node at a URL.')

yarn-project/pxe/src/pxe_service/pxe_service.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
type PXE,
1818
type PXEInfo,
1919
type PrivateKernelProver,
20+
type SiblingPath,
2021
SimulatedTx,
2122
SimulationError,
2223
TaggedLog,
@@ -32,11 +33,12 @@ import {
3233
import {
3334
AztecAddress,
3435
type CompleteAddress,
36+
type L1_TO_L2_MSG_TREE_HEIGHT,
3537
type PartialAddress,
3638
computeContractClassId,
3739
getContractClassFromArtifact,
3840
} from '@aztec/circuits.js';
39-
import { computeNoteHashNonce, siloNullifier } from '@aztec/circuits.js/hash';
41+
import { computeL1ToL2MessageNullifier, computeNoteHashNonce, siloNullifier } from '@aztec/circuits.js/hash';
4042
import {
4143
type ContractArtifact,
4244
type DecodedReturn,
@@ -56,6 +58,7 @@ import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contract
5658
import {
5759
type AcirSimulator,
5860
type ExecutionResult,
61+
MessageLoadOracleInputs,
5962
accumulateReturnValues,
6063
collectEnqueuedPublicFunctionCalls,
6164
collectPublicTeardownFunctionCall,
@@ -355,6 +358,35 @@ export class PXEService implements PXE {
355358
return Promise.all(extendedNotes);
356359
}
357360

361+
async getL1ToL2MembershipWitness(
362+
contractAddress: AztecAddress,
363+
messageHash: Fr,
364+
secret: Fr,
365+
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
366+
let nullifierIndex: bigint | undefined;
367+
let messageIndex = 0n;
368+
let startIndex = 0n;
369+
let siblingPath: SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>;
370+
371+
// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> we need to check
372+
// for nullifiers because messages can have duplicates.
373+
do {
374+
const response = await this.node.getL1ToL2MessageMembershipWitness('latest', messageHash, startIndex);
375+
if (!response) {
376+
throw new Error(`No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}`);
377+
}
378+
[messageIndex, siblingPath] = response;
379+
380+
const messageNullifier = computeL1ToL2MessageNullifier(contractAddress, messageHash, secret, messageIndex);
381+
382+
nullifierIndex = await this.node.findLeafIndex('latest', MerkleTreeId.NULLIFIER_TREE, messageNullifier);
383+
384+
startIndex = messageIndex + 1n;
385+
} while (nullifierIndex !== undefined);
386+
387+
return [messageIndex, siblingPath];
388+
}
389+
358390
public async addNote(note: ExtendedNote, scope?: AztecAddress) {
359391
const owner = await this.db.getCompleteAddress(note.owner);
360392
if (!owner) {

0 commit comments

Comments
 (0)