Skip to content

Commit

Permalink
feat: addNote api (#2535)
Browse files Browse the repository at this point in the history
Closes #1432 

Usage of this api will be added to an e2e test in a later PR where we
remove `Set.check_note_hash_exists`.

# Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if
the PR is ready to merge.
- [ ] If the pull request requires a cryptography review (e.g.
cryptographic algorithm implementations) I have added the 'crypto' tag.
- [ ] I have reviewed my diff in github, line by line and removed
unexpected formatting changes, testing logs, or commented-out code.
- [ ] Every change is related to the PR description.
- [ ] I have
[linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)
this pull request to relevant issues (if any exist).
  • Loading branch information
LeilaWang authored Sep 26, 2023
1 parent a90a185 commit bb004f4
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 3 deletions.
10 changes: 10 additions & 0 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,16 @@ export class AztecNodeService implements AztecNode {
return committedDb.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, leafIndex);
}

/**
* Find the index of the given nullifier.
* @param nullifier - The nullifier to search for.
* @returns The index of the given leaf in the nullifier tree or undefined if not found.
*/
public async findNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
const committedDb = await this.#getWorldState();
return committedDb.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
}

/**
* Gets the storage value at the given contract slot.
* @param contract - Address of the contract to query.
Expand Down
41 changes: 40 additions & 1 deletion yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
PartialAddress,
PublicCallRequest,
} from '@aztec/circuits.js';
import { computeCommitmentNonce } from '@aztec/circuits.js/abis';
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/abis';
import { encodeArguments } from '@aztec/foundation/abi';
import { padArrayEnd } from '@aztec/foundation/collection';
import { Fr, Point } from '@aztec/foundation/fields';
Expand All @@ -41,6 +41,7 @@ import {
LogType,
NodeInfo,
NotePreimage,
PublicKey,
SimulationError,
Tx,
TxExecutionRequest,
Expand Down Expand Up @@ -198,6 +199,44 @@ export class AztecRPCServer implements AztecRPC {
return ownerNotes.map(n => n.notePreimage);
}

public async addNote(
contractAddress: AztecAddress,
storageSlot: Fr,
preimage: NotePreimage,
nonce: Fr,
account: PublicKey,
) {
const { innerNoteHash, siloedNoteHash, uniqueSiloedNoteHash, innerNullifier } =
await this.simulator.computeNoteHashAndNullifier(contractAddress, nonce, storageSlot, preimage.items);

// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
// This can always be `uniqueSiloedNoteHash` once notes added from public also include nonces.
const noteHashToLookUp = nonce.isZero() ? siloedNoteHash : uniqueSiloedNoteHash;
const index = await this.node.findCommitmentIndex(noteHashToLookUp.toBuffer());
if (index === undefined) {
throw new Error('Note does not exist.');
}

const wasm = await CircuitsWasm.get();
const siloedNullifier = siloNullifier(wasm, contractAddress, innerNullifier!);
const nullifierIndex = await this.node.findNullifierIndex(siloedNullifier);
if (nullifierIndex !== undefined) {
throw new Error('The note has been destroyed.');
}

// TODO - Should not modify the db while syncing.
await this.db.addNoteSpendingInfo({
contractAddress,
storageSlot,
notePreimage: preimage,
nonce,
innerNoteHash,
siloedNullifier,
index,
publicKey: account,
});
}

public async getNoteNonces(
contractAddress: AztecAddress,
storageSlot: Fr,
Expand Down
5 changes: 4 additions & 1 deletion yarn-project/aztec.js/src/wallet/base_wallet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AztecAddress, Fr, GrumpkinPrivateKey, PartialAddress } from '@aztec/circuits.js';
import { AztecAddress, Fr, GrumpkinPrivateKey, PartialAddress, Point } from '@aztec/circuits.js';
import {
AuthWitness,
AztecRPC,
Expand Down Expand Up @@ -74,6 +74,9 @@ export abstract class BaseWallet implements Wallet {
getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise<any> {
return this.rpc.getPublicStorageAt(contract, storageSlot);
}
addNote(contract: AztecAddress, storageSlot: Fr, preimage: NotePreimage, nonce: Fr, account: Point): Promise<void> {
return this.rpc.addNote(contract, storageSlot, preimage, nonce, account);
}
getNoteNonces(contract: AztecAddress, storageSlot: Fr, preimage: NotePreimage, txHash: TxHash): Promise<Fr[]> {
return this.rpc.getNoteNonces(contract, storageSlot, preimage, txHash);
}
Expand Down
7 changes: 6 additions & 1 deletion yarn-project/types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ import {
Tx,
TxHash,
} from '../index.js';
import { NullifierProvider } from './nullifier_provider.js';

/**
* The aztec node.
* We will probably implement the additional interfaces by means other than Aztec Node as it's currently a privacy leak
*/
export interface AztecNode extends DataCommitmentProvider, L1ToL2MessageProvider, ContractCommitmentProvider {
export interface AztecNode
extends DataCommitmentProvider,
L1ToL2MessageProvider,
ContractCommitmentProvider,
NullifierProvider {
/**
* Method to determine if the node is ready to accept transactions.
* @returns - Flag indicating the readiness for tx submission.
Expand Down
17 changes: 17 additions & 0 deletions yarn-project/types/src/interfaces/aztec_rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
L2BlockL2Logs,
L2Tx,
NotePreimage,
PublicKey,
Tx,
TxExecutionRequest,
TxHash,
Expand Down Expand Up @@ -169,6 +170,22 @@ export interface AztecRPC {
*/
getPublicStorageAt(contract: AztecAddress, storageSlot: Fr): Promise<Buffer | undefined>;

/**
* Adds a note to the database. Throw if the note hash of the note doesn't exist in the tree.
* @param contract - The contract address of the note.
* @param storageSlot - The storage slot of the note.
* @param preimage - The note preimage.
* @param nonce - The nonce of the note.
* @param account - The public key of the account the note is associated with.
*/
addNote(
contract: AztecAddress,
storageSlot: Fr,
preimage: NotePreimage,
nonce: Fr,
account: PublicKey,
): Promise<void>;

/**
* Finds the nonce(s) for a note in a tx with given preimage at a specified contract address and storage slot.
* @param contract - The contract address of the note.
Expand Down
13 changes: 13 additions & 0 deletions yarn-project/types/src/interfaces/nullifier_provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Fr } from '@aztec/foundation/fields';

/**
* Interface for providing information about nullifiers within the nullifier tree.
*/
export interface NullifierProvider {
/**
* Find the index of the given nullifier.
* @param nullifier - The nullifier to search for.
* @returns The index of the given leaf of undefined if not found.
*/
findNullifierIndex(nullifier: Fr): Promise<bigint | undefined>;
}

0 comments on commit bb004f4

Please sign in to comment.