Skip to content

Commit

Permalink
refactor: read function names from contract classes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Dec 16, 2024
1 parent 8699f8a commit 894542d
Show file tree
Hide file tree
Showing 17 changed files with 35 additions and 160 deletions.
15 changes: 0 additions & 15 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
isValidUnconstrainedFunctionMembershipProof,
} from '@aztec/circuits.js';
import { createEthereumChain } from '@aztec/ethereum';
import { type ContractArtifact } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { type EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
Expand Down Expand Up @@ -766,14 +765,6 @@ export class Archiver implements ArchiveSource, Traceable {
return;
}

addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
return this.store.addContractArtifact(address, artifact);
}

getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return this.store.getContractArtifact(address);
}

getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
return this.store.getContractFunctionName(address, selector);
}
Expand Down Expand Up @@ -1078,12 +1069,6 @@ class ArchiverStoreHelper
getContractClassIds(): Promise<Fr[]> {
return this.store.getContractClassIds();
}
addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
return this.store.addContractArtifact(address, contract);
}
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return this.store.getContractArtifact(address);
}
getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
return this.store.getContractFunctionName(address, selector);
}
Expand Down
8 changes: 2 additions & 6 deletions yarn-project/archiver/src/archiver/archiver_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
type PrivateLog,
type UnconstrainedFunctionWithMembershipProof,
} from '@aztec/circuits.js';
import { type ContractArtifact, type FunctionSelector } from '@aztec/foundation/abi';
import { type FunctionSelector } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';

import { type DataRetrieval } from './structs/data_retrieval.js';
Expand Down Expand Up @@ -261,11 +261,7 @@ export interface ArchiverDataStore {
/** Returns the list of all class ids known by the archiver. */
getContractClassIds(): Promise<Fr[]>;

addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void>;
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined>;

// TODO: These function names are in memory only as they are for development/debugging. They require the full contract
// artifact supplied to the node out of band. This should be reviewed and potentially removed as part of
// TODO: These function names are only used for development/debugging. This should be reviewed and potentially removed as part of
// the node api cleanup process.
getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
type PrivateLog,
type UnconstrainedFunctionWithMembershipProof,
} from '@aztec/circuits.js';
import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi';
import { FunctionSelector } from '@aztec/foundation/abi';
import { type AztecAddress } from '@aztec/foundation/aztec-address';
import { createLogger } from '@aztec/foundation/log';
import { type AztecKVStore } from '@aztec/kv-store';
Expand All @@ -26,7 +26,6 @@ import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_s
import { type DataRetrieval } from '../structs/data_retrieval.js';
import { type L1Published } from '../structs/published.js';
import { BlockStore } from './block_store.js';
import { ContractArtifactsStore } from './contract_artifacts_store.js';
import { ContractClassStore } from './contract_class_store.js';
import { ContractInstanceStore } from './contract_instance_store.js';
import { LogStore } from './log_store.js';
Expand All @@ -43,8 +42,6 @@ export class KVArchiverDataStore implements ArchiverDataStore {
#messageStore: MessageStore;
#contractClassStore: ContractClassStore;
#contractInstanceStore: ContractInstanceStore;
#contractArtifactStore: ContractArtifactsStore;
private functionNames = new Map<string, string>();

#log = createLogger('archiver:data-store');

Expand All @@ -54,27 +51,28 @@ export class KVArchiverDataStore implements ArchiverDataStore {
this.#messageStore = new MessageStore(db);
this.#contractClassStore = new ContractClassStore(db);
this.#contractInstanceStore = new ContractInstanceStore(db);
this.#contractArtifactStore = new ContractArtifactsStore(db);
this.#nullifierStore = new NullifierStore(db);
}

getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return Promise.resolve(this.#contractArtifactStore.getContractArtifact(address));
}

// TODO: These function names are in memory only as they are for development/debugging. They require the full contract
// artifact supplied to the node out of band. This should be reviewed and potentially removed as part of
// TODO: These function names are used for development/debugging. This should be reviewed and potentially removed as part of
// the node api cleanup process.
getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
return Promise.resolve(this.functionNames.get(selector.toString()));
}
const inst = this.#contractInstanceStore.getContractInstance(address);
if (!inst) {
throw new Error('Contract instance not found at address: ' + address);
}

async addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
await this.#contractArtifactStore.addContractArtifact(address, contract);
// Building tup this map of selectors to function names save expensive re-hydration of contract artifacts later
contract.functions.forEach(f => {
this.functionNames.set(FunctionSelector.fromNameAndParameters(f.name, f.parameters).toString(), f.name);
});
const cls = this.#contractClassStore.getContractClass(inst.contractClassId);
if (!cls) {
throw new Error('Contract class not found: ' + inst.contractClassId);
}

const fn = cls.publicFunctions.find(fn => fn.selector === selector);
if (!fn) {
throw new Error('Function selector not found in contract class: ' + selector);
}

return Promise.resolve(fn?.name);
}

getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,26 +730,23 @@ export class MemoryArchiverStore implements ArchiverDataStore {
});
}

public addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
this.contractArtifacts.set(address.toString(), contract);
return Promise.resolve();
}

public getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
return Promise.resolve(this.contractArtifacts.get(address.toString()));
}

async getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
const artifact = await this.getContractArtifact(address);
const inst = await this.getContractInstance(address);
if (!inst) {
throw new Error('Contract instance not found at address: ' + address);
}

if (!artifact) {
return undefined;
const cls = await this.getContractClass(inst.contractClassId);
if (!cls) {
throw new Error('Contract class not found: ' + inst.contractClassId);
}

const func = artifact.functions.find(f =>
FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }).equals(selector),
);
return Promise.resolve(func?.name);
const fn = cls.publicFunctions.find(fn => fn.selector === selector);
if (!fn) {
throw new Error('Function selector not found in contract class: ' + selector);
}

return Promise.resolve(fn?.name);
}

public estimateSize(): { mappingSize: number; actualSize: number; numItems: number } {
Expand Down
1 change: 0 additions & 1 deletion yarn-project/archiver/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ async function registerProtocolContracts(store: KVArchiverDataStore) {
privateFunctions: [],
unconstrainedFunctions: [],
};
await store.addContractArtifact(contract.address, contract.artifact);
const bytecodeCommitment = computePublicBytecodeCommitment(contractClassPublic.packedBytecode);
await store.addContractClasses([contractClassPublic], [bytecodeCommitment], blockNumber);
await store.addContractInstances([contract.instance], blockNumber);
Expand Down
6 changes: 0 additions & 6 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -903,12 +903,6 @@ export class AztecNodeService implements AztecNode, Traceable {
return this.contractDataSource.addContractClass(contractClass);
}

public addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
this.log.info(`Adding contract artifact ${artifact.name} for ${address.toString()} via API`);
// TODO: Node should validate the artifact before accepting it
return this.contractDataSource.addContractArtifact(address, artifact);
}

public flushTxs(): Promise<void> {
if (!this.sequencer) {
throw new Error(`Sequencer is not initialized`);
Expand Down
19 changes: 0 additions & 19 deletions yarn-project/circuit-types/src/interfaces/archiver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,6 @@ describe('ArchiverApiSchema', () => {
expect(result).toBe(1n);
});

it('getContractArtifact', async () => {
const result = await context.client.getContractArtifact(AztecAddress.random());
deepStrictEqual(result, artifact);
});

it('addContractArtifact', async () => {
await context.client.addContractArtifact(AztecAddress.random(), artifact);
}, 20_000);

it('getContract', async () => {
const address = AztecAddress.random();
const result = await context.client.getContract(address);
Expand Down Expand Up @@ -374,16 +365,6 @@ class MockArchiver implements ArchiverApi {
getContractClassIds(): Promise<Fr[]> {
return Promise.resolve([Fr.random()]);
}
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined> {
expect(address).toBeInstanceOf(AztecAddress);
return Promise.resolve(this.artifact);
}
addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
expect(address).toBeInstanceOf(AztecAddress);
// We use node's native assertion because jest's is too slow
deepStrictEqual(contract, this.artifact);
return Promise.resolve();
}
getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]> {
expect(blockNumber).toEqual(1n);
return Promise.resolve([Fr.random()]);
Expand Down
3 changes: 0 additions & 3 deletions yarn-project/circuit-types/src/interfaces/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
PrivateLog,
PublicFunctionSchema,
} from '@aztec/circuits.js';
import { ContractArtifactSchema } from '@aztec/foundation/abi';
import { type ApiSchemaFor, optional, schemas } from '@aztec/foundation/schemas';

import { z } from 'zod';
Expand Down Expand Up @@ -69,8 +68,6 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
getBytecodeCommitment: z.function().args(schemas.Fr).returns(schemas.Fr),
getContract: z.function().args(schemas.AztecAddress).returns(ContractInstanceWithAddressSchema.optional()),
getContractClassIds: z.function().args().returns(z.array(schemas.Fr)),
getContractArtifact: z.function().args(schemas.AztecAddress).returns(ContractArtifactSchema.optional()),
addContractArtifact: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()),
getL1ToL2Messages: z.function().args(schemas.BigInt).returns(z.array(schemas.Fr)),
getL1ToL2MessageIndex: z.function().args(schemas.Fr).returns(schemas.BigInt.optional()),
// TODO(#10007): Remove this method
Expand Down
4 changes: 0 additions & 4 deletions yarn-project/circuit-types/src/interfaces/aztec-node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,6 @@ describe('AztecNodeApiSchema', () => {
expect(response).toEqual(Object.fromEntries(ProtocolContractsNames.map(name => [name, expect.any(AztecAddress)])));
});

it('addContractArtifact', async () => {
await context.client.addContractArtifact(AztecAddress.random(), artifact);
}, 20_000);

it('getPrivateLogs', async () => {
const response = await context.client.getPrivateLogs(1, 1);
expect(response).toEqual([expect.any(PrivateLog)]);
Expand Down
10 changes: 0 additions & 10 deletions yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
ProtocolContractAddressesSchema,
} from '@aztec/circuits.js';
import { type L1ContractAddresses, L1ContractAddressesSchema } from '@aztec/ethereum';
import { type ContractArtifact, ContractArtifactSchema } from '@aztec/foundation/abi';
import type { AztecAddress } from '@aztec/foundation/aztec-address';
import type { Fr } from '@aztec/foundation/fields';
import { createSafeJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client';
Expand Down Expand Up @@ -282,13 +281,6 @@ export interface AztecNode
*/
getProtocolContractAddresses(): Promise<ProtocolContractAddresses>;

/**
* Method to add a contract artifact to the database.
* @param aztecAddress
* @param artifact
*/
addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void>;

/**
* Retrieves all private logs from up to `limit` blocks, starting from the block number `from`.
* @param from - The block number from which to begin retrieving logs.
Expand Down Expand Up @@ -533,8 +525,6 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {

getProtocolContractAddresses: z.function().returns(ProtocolContractAddressesSchema),

addContractArtifact: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()),

getPrivateLogs: z.function().args(z.number(), z.number()).returns(z.array(PrivateLog.schema)),

getUnencryptedLogs: z.function().args(LogFilterSchema).returns(GetUnencryptedLogsResponseSchema),
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/circuits.js/src/contract/contract_class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export function getContractClassFromArtifact(
const artifactPublicFunctions: ContractClass['publicFunctions'] = artifact.functions
.filter(f => f.functionType === FunctionType.PUBLIC)
.map(f => ({
// TODO: #10752 consider removing function name from contract class
name: f.name,
selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters),
bytecode: f.bytecode,
}))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const ExecutablePrivateFunctionSchema = PrivateFunctionSchema.and(

/** Public function definition within a contract class. */
export interface PublicFunction {
name?: string;
/** Selector of the function. Calculated as the hash of the method name and parameters. The specification of this is not enforced by the protocol. */
selector: FunctionSelector;
/** Public bytecode. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ export interface ContractDataSource {
*/
getContractClassIds(): Promise<Fr[]>;

/** Returns a contract artifact. */
getContractArtifact(address: AztecAddress): Promise<ContractArtifact | undefined>;

/** Returns a function's name */
getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
/** Registers a a contract artifact. */
addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void>;
}
3 changes: 0 additions & 3 deletions yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,6 @@ export class PXEService implements PXE {

await this.db.addContractArtifact(contractClassId, artifact);

// TODO: PXE may not want to broadcast the artifact to the network
await this.node.addContractArtifact(instance.address, artifact);

// TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
} else {
Expand Down
9 changes: 0 additions & 9 deletions yarn-project/txe/src/node/txe_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,15 +445,6 @@ export class TXENode implements AztecNode {
throw new Error('TXE Node method getProtocolContractAddresses not implemented');
}

/**
* Method to add a contract artifact to the database.
* @param aztecAddress
* @param artifact
*/
addContractArtifact(_address: AztecAddress, _artifact: ContractArtifact): Promise<void> {
throw new Error('TXE Node method addContractArtifact not implemented');
}

/**
* Gets unencrypted logs based on the provided filter.
* @param filter - The filter to apply to the logs.
Expand Down

0 comments on commit 894542d

Please sign in to comment.