Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: addNote api #2535

Merged
merged 3 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>;
}