Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ pub contract ContractClassRegisterer {
artifact_hash: Field,
private_functions_root: Field,
public_bytecode_commitment: Field,
emit: bool,
) {
// TODO: Validate public_bytecode_commitment is the correct commitment of packed_public_bytecode
// TODO: We should be able to remove public_bytecode_commitment from the input if it's calculated in this function
Expand Down Expand Up @@ -103,18 +102,14 @@ pub contract ContractClassRegisterer {
],
);

// TODO(#10007): Drop this conditional and always emit the bytecode. We allow skipping the broadcast
// as a stopgap solution to allow txs to fit in Sepolia when we broadcast public bytecode.
if emit {
let event = ContractClassRegistered {
contract_class_id,
version: 1,
artifact_hash,
private_functions_root,
packed_public_bytecode,
};
emit_contract_class_log(&mut context, event.serialize_non_standard());
}
let event = ContractClassRegistered {
contract_class_id,
version: 1,
artifact_hash,
private_functions_root,
packed_public_bytecode,
};
emit_contract_class_log(&mut context, event.serialize_non_standard());
}

#[private]
Expand Down
1 change: 0 additions & 1 deletion yarn-project/archiver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
"@aztec/foundation": "workspace:^",
"@aztec/kv-store": "workspace:^",
"@aztec/l1-artifacts": "workspace:^",
"@aztec/noir-contracts.js": "workspace:^",
"@aztec/noir-protocol-circuits-types": "workspace:^",
"@aztec/protocol-contracts": "workspace:^",
"@aztec/stdlib": "workspace:^",
Expand Down
19 changes: 0 additions & 19 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,16 +825,6 @@ export class Archiver extends EventEmitter implements ArchiveSource, Traceable {
return this.store.getContractClassIds();
}

// TODO(#10007): Remove this method
async addContractClass(contractClass: ContractClassPublic): Promise<void> {
await this.store.addContractClasses(
[contractClass],
[await computePublicBytecodeCommitment(contractClass.packedBytecode)],
0,
);
return;
}

registerContractFunctionSignatures(address: AztecAddress, signatures: string[]): Promise<void> {
return this.store.registerContractFunctionSignatures(address, signatures);
}
Expand Down Expand Up @@ -916,15 +906,6 @@ class ArchiverStoreHelper

constructor(private readonly store: ArchiverDataStore) {}

// TODO(#10007): Remove this method
addContractClasses(
contractClasses: ContractClassPublic[],
bytecodeCommitments: Fr[],
blockNum: number,
): Promise<boolean> {
return this.store.addContractClasses(contractClasses, bytecodeCommitments, blockNum);
}

/**
* Extracts and stores contract classes out of ContractClassRegistered events emitted by the class registerer contract.
* @param allLogs - All logs emitted in a bunch of blocks.
Expand Down
28 changes: 1 addition & 27 deletions yarn-project/archiver/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@ import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
import { createLogger } from '@aztec/foundation/log';
import type { DataStoreConfig } from '@aztec/kv-store/config';
import { createStore } from '@aztec/kv-store/lmdb-v2';
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
import { TokenBridgeContractArtifact } from '@aztec/noir-contracts.js/TokenBridge';
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
import { protocolContractNames, protocolContractTreeRoot } from '@aztec/protocol-contracts';
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
import type { L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
import {
type ContractClassPublic,
computePublicBytecodeCommitment,
getContractClassFromArtifact,
} from '@aztec/stdlib/contract';
import { type ContractClassPublic, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
import type { ArchiverApi, Service } from '@aztec/stdlib/interfaces/server';
import { getComponentsVersionsFromConfig } from '@aztec/stdlib/versioning';
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
Expand Down Expand Up @@ -45,7 +39,6 @@ export async function createArchiver(
);
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
await registerProtocolContracts(archiverStore);
await registerCommonContracts(archiverStore);
return Archiver.createAndSync(config, archiverStore, { telemetry, blobSinkClient }, opts.blockUntilSync);
}

Expand Down Expand Up @@ -86,22 +79,3 @@ async function registerProtocolContracts(store: KVArchiverDataStore) {
await store.addContractInstances([contract.instance], blockNumber);
}
}

// TODO(#10007): Remove this method. We are explicitly registering these contracts
// here to ensure they are available to all nodes and all prover nodes, since the PXE
// was tweaked to automatically push contract classes to the node it is registered,
// but other nodes in the network may require the contract classes to be registered as well.
// TODO(#10007): Remove the dependency on noir-contracts.js from this package once we remove this.
async function registerCommonContracts(store: KVArchiverDataStore) {
const blockNumber = 0;
const artifacts = [TokenBridgeContractArtifact, TokenContractArtifact];
const classes = await Promise.all(
artifacts.map(async artifact => ({
...(await getContractClassFromArtifact(artifact)),
privateFunctions: [],
unconstrainedFunctions: [],
})),
);
const bytecodeCommitments = await Promise.all(classes.map(x => computePublicBytecodeCommitment(x.packedBytecode)));
await store.addContractClasses(classes, bytecodeCommitments, blockNumber);
}
3 changes: 0 additions & 3 deletions yarn-project/archiver/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
{
"path": "../l1-artifacts"
},
{
"path": "../noir-contracts.js"
},
{
"path": "../noir-protocol-circuits-types"
},
Expand Down
32 changes: 4 additions & 28 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
type NOTE_HASH_TREE_HEIGHT,
type NULLIFIER_TREE_HEIGHT,
type PUBLIC_DATA_TREE_HEIGHT,
REGISTERER_CONTRACT_ADDRESS,
} from '@aztec/constants';
import { EpochCache } from '@aztec/epoch-cache';
import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum';
Expand Down Expand Up @@ -49,7 +48,7 @@ import type {
ProtocolContractAddresses,
} from '@aztec/stdlib/contract';
import type { GasFees } from '@aztec/stdlib/gas';
import { computePublicDataTreeLeafSlot, siloNullifier } from '@aztec/stdlib/hash';
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
import type {
AztecNode,
AztecNodeAdmin,
Expand All @@ -69,8 +68,8 @@ import {
import type { LogFilter, PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
import { P2PClientType } from '@aztec/stdlib/p2p';
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
import type { NullifierLeafPreimage, PublicDataTreeLeaf, PublicDataTreeLeafPreimage } from '@aztec/stdlib/trees';
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
import {
type BlockHeader,
PublicSimulationOutput,
Expand Down Expand Up @@ -369,25 +368,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
return Promise.resolve(this.l1ChainId);
}

public async getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
const klazz = await this.contractDataSource.getContractClass(id);

// TODO(#10007): Remove this check. This is needed only because we're manually registering
// some contracts in the archiver so they are available to all nodes (see `registerCommonContracts`
// in `archiver/src/factory.ts`), but we still want clients to send the registration tx in order
// to emit the corresponding nullifier, which is now being checked. Note that this method
// is only called by the PXE to check if a contract is publicly registered.
if (klazz) {
const classNullifier = await siloNullifier(AztecAddress.fromNumber(REGISTERER_CONTRACT_ADDRESS), id);
const worldState = await this.#getWorldState('latest');
const [index] = await worldState.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [classNullifier.toBuffer()]);
this.log.debug(`Registration nullifier ${classNullifier} for contract class ${id} found at index ${index}`);
if (index === undefined) {
return undefined;
}
}

return klazz;
public getContractClass(id: Fr): Promise<ContractClassPublic | undefined> {
return this.contractDataSource.getContractClass(id);
}

public getContract(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
Expand Down Expand Up @@ -951,12 +933,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
});
}

// TODO(#10007): Remove this method
public addContractClass(contractClass: ContractClassPublic): Promise<void> {
this.log.info(`Adding contract class via API ${contractClass.id}`);
return this.contractDataSource.addContractClass(contractClass);
}

public registerContractFunctionSignatures(_address: AztecAddress, signatures: string[]): Promise<void> {
return this.contractDataSource.registerContractFunctionSignatures(_address, signatures);
}
Expand Down
3 changes: 0 additions & 3 deletions yarn-project/aztec.js/src/contract/deploy_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
public async request(options: DeployOptions = {}): Promise<Omit<ExecutionRequestInit, 'fee'>> {
const deployment = await this.getDeploymentFunctionCalls(options);

// NOTE: MEGA HACK. Remove with #10007
// register the contract after generating deployment function calls in order to publicly register the class and (optioanlly) emit its bytecode
//
// TODO: Should we add the contracts to the DB here, or once the tx has been sent or mined?
// Note that we need to run this registerContract here so it's available when computeFeeOptionsFromEstimatedGas
// runs, since it needs the contract to have been registered in order to estimate gas for its initialization,
Expand Down
14 changes: 1 addition & 13 deletions yarn-project/aztec.js/src/deployment/register_class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,15 @@ import type { ContractFunctionInteraction } from '../contract/contract_function_
import { getRegistererContract } from '../contract/protocol_contracts.js';
import type { Wallet } from '../wallet/index.js';

const defaultEmitPublicBytecode =
// guard against `process` not being defined (e.g. in the browser)
typeof process === 'object' && typeof process.env === 'object'
? ['1', 'true', 'yes', ''].includes(process.env.AZTEC_EMIT_PUBLIC_BYTECODE ?? '')
: true;

/** Sets up a call to register a contract class given its artifact. */
export async function registerContractClass(
wallet: Wallet,
artifact: ContractArtifact,
emitPublicBytecode = defaultEmitPublicBytecode,
): Promise<ContractFunctionInteraction> {
const { artifactHash, privateFunctionsRoot, publicBytecodeCommitment, packedBytecode } =
await getContractClassFromArtifact(artifact);
const registerer = await getRegistererContract(wallet);
const fn = registerer.methods.register(
artifactHash,
privateFunctionsRoot,
publicBytecodeCommitment,
emitPublicBytecode,
);
const fn = registerer.methods.register(artifactHash, privateFunctionsRoot, publicBytecodeCommitment);

const encodedBytecode = bufferAsFields(packedBytecode, MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS);
fn.addCapsule(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { AztecNodeService } from '@aztec/aztec-node';
import {
AztecAddress,
type AztecNode,
Expand All @@ -24,7 +23,6 @@ import {
import { writeTestData } from '@aztec/foundation/testing/files';
import { StatefulTestContract } from '@aztec/noir-contracts.js/StatefulTest';
import { TestContract } from '@aztec/noir-contracts.js/Test';
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
import type { ContractClassIdPreimage } from '@aztec/stdlib/contract';
import { PublicKeys } from '@aztec/stdlib/keys';
Expand Down Expand Up @@ -52,49 +50,25 @@ describe('e2e_deploy_contract contract class registration', () => {

beforeAll(async () => {
artifact = StatefulTestContract.artifact;
registrationTxReceipt = await registerContractClass(wallet, artifact, false).then(c => c.send().wait());
registrationTxReceipt = await registerContractClass(wallet, artifact).then(c => c.send().wait());
contractClass = await getContractClassFromArtifact(artifact);

// TODO(#10007) Remove this call. Node should get the bytecode from the event broadcast.
expect(await aztecNode.getContractClass(contractClass.id)).toBeUndefined();
await aztecNode.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
expect(await aztecNode.getContractClass(contractClass.id)).toBeDefined();
});

describe('registering a contract class', () => {
it('optionally emits public bytecode', async () => {
const registrationTxReceipt = await registerContractClass(wallet, TestContract.artifact, true).then(c =>
it('emits public bytecode', async () => {
const registrationTxReceipt = await registerContractClass(wallet, TestContract.artifact).then(c =>
c.send().wait(),
);
const logs = await aztecNode.getContractClassLogs({ txHash: registrationTxReceipt.txHash });
expect(logs.logs.length).toEqual(1);

// TODO(#10007): The below is temporary as it's commented out on a below test
const logData = logs.logs[0].log.toBuffer();
writeTestData('yarn-project/protocol-contracts/fixtures/ContractClassRegisteredEventData.hex', logData);
});

// TODO(#10007) Remove this test. We should always broadcast public bytecode.
it('bypasses broadcast if exceeds bytecode limit for event size', async () => {
const logs = await aztecNode.getContractClassLogs({ txHash: registrationTxReceipt.txHash });
expect(logs.logs.length).toEqual(0);
});

// TODO(#10007) Remove this test as well.
it('starts archiver with pre-registered common contracts', async () => {
const { id: classId } = await getContractClassFromArtifact(TokenContractArtifact);
// The node checks the registration nullifier
expect(await aztecNode.getContractClass(classId)).toBeUndefined();
// But the archiver does not
const archiver = (aztecNode as AztecNodeService).getContractDataSource();
expect(await archiver.getContractClass(classId)).toBeDefined();
});

it('registers the contract class on the node', async () => {
// TODO(#10007) Enable this.
// const logs = await aztecNode.getContractClassLogs({ txHash: registrationTxReceipt.txHash });
// expect(logs.logs.length).toEqual(1);
// const logData = logs.logs[0].log.toBuffer();
// writeTestData('yarn-project/protocol-contracts/fixtures/ContractClassRegisteredEventData.hex', logData);
const logs = await aztecNode.getContractClassLogs({ txHash: registrationTxReceipt.txHash });
expect(logs.logs.length).toEqual(1);
const logData = logs.logs[0].log.toBuffer();
writeTestData('yarn-project/protocol-contracts/fixtures/ContractClassRegisteredEventData.hex', logData);

const registeredClass = await aztecNode.getContractClass(contractClass.id);
expect(registeredClass).toBeDefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
type PXE,
type Wallet,
createPXEClient,
getContractClassFromArtifact,
makeFetch,
} from '@aztec/aztec.js';
import { CounterContract } from '@aztec/noir-contracts.js/Counter';
Expand Down Expand Up @@ -56,15 +55,6 @@ describe('e2e_deploy_contract deploy method', () => {
).toBeTrue();
});

// TODO(#10007): Remove this test. Common contracts (ie token contracts) are only distinguished
// because we're manually adding them to the archiver to support provernet.
it('registers a contract class for a common contract', async () => {
const { id: tokenContractClass } = await getContractClassFromArtifact(TokenContract.artifact);
expect((await pxe.getContractClassMetadata(tokenContractClass)).isContractClassPubliclyRegistered).toBeFalse();
await TokenContract.deploy(wallet, wallet.getAddress(), 'TOKEN', 'TKN', 18n).send().deployed();
expect((await pxe.getContractClassMetadata(tokenContractClass)).isContractClassPubliclyRegistered).toBeTrue();
});

it('publicly universally deploys and initializes a contract', async () => {
const owner = wallet.getAddress();
const opts = { universalDeploy: true };
Expand Down
12 changes: 8 additions & 4 deletions yarn-project/end-to-end/src/e2e_deploy_contract/legacy.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AztecAddress,
ContractDeployer,
type DeployOptions,
Fr,
type Logger,
type PXE,
Expand Down Expand Up @@ -84,16 +85,19 @@ describe('e2e_deploy_contract legacy', () => {
await expect(deployer.deploy().send({ contractAddressSalt }).wait()).rejects.toThrow(/dropped/);
});

// TODO(#10007): Reenable this test.
it.skip('should not deploy a contract which failed the public part of the execution', async () => {
it('should not deploy a contract which failed the public part of the execution', async () => {
// This test requires at least another good transaction to go through in the same block as the bad one.
const artifact = TokenContractArtifact;
const initArgs = ['TokenName', 'TKN', 18] as const;
const goodDeploy = StatefulTestContract.deploy(wallet, wallet.getAddress(), wallet.getAddress(), 42);
const badDeploy = new ContractDeployer(artifact, wallet).deploy(AztecAddress.ZERO, ...initArgs);

const firstOpts = { skipPublicSimulation: true, skipClassRegistration: true, skipInstanceDeploy: true };
const secondOpts = { skipPublicSimulation: true };
const firstOpts: DeployOptions = {
skipPublicSimulation: true,
skipClassRegistration: true,
skipPublicDeployment: true,
};
const secondOpts: DeployOptions = { skipPublicSimulation: true };

await Promise.all([goodDeploy.prove(firstOpts), badDeploy.prove(secondOpts)]);
const [goodTx, badTx] = [goodDeploy.send(firstOpts), badDeploy.send(secondOpts)];
Expand Down
5 changes: 0 additions & 5 deletions yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,6 @@ export class PXEService implements PXE {
.filter(fn => fn.functionType === FunctionType.PUBLIC)
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
await this.node.registerContractFunctionSignatures(instance.address, publicFunctionSignatures);

// TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
} else {
// Otherwise, make sure there is an artifact already registered for that class id
artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
Expand Down Expand Up @@ -421,8 +418,6 @@ export class PXEService implements PXE {
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
await this.node.registerContractFunctionSignatures(contractAddress, publicFunctionSignatures);

// TODO(#10007): Node should get public contract class from the registration event, not from PXE registration
await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] });
currentInstance.currentContractClassId = contractClass.id;
await this.contractDataProvider.addContractInstance(currentInstance);
this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
Expand Down
Loading