Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Skip emitting public bytecode
Browse files Browse the repository at this point in the history
Skips emitting the event with the contract public bytecode when
registering the contract class. This allows for smaller L1 txs so they
fit in Sepolia. This is a temporary hack to be reverted.

To get bytecode into the nodes, we push it forcefully from the PXE
whenever we register a new contract. However, this only gets the
bytecode into the node that the PXE is connected to. To avoid nodes or
prover nodes from missing bytecode that is to be used for known
deployments, such as the token or token bridge contracts, we now
manually register them on initialization.

Reverting this is logged as issue #10007

Fixes #10000
spalladino committed Nov 15, 2024
1 parent cae7279 commit ce8db73
Showing 17 changed files with 195 additions and 74 deletions.
8 changes: 4 additions & 4 deletions noir-projects/noir-contracts/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -15,9 +15,9 @@ if [ -n "$CMD" ]; then
fi
fi

echo "Compiling contracts..."
NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo}
$NARGO compile --silence-warnings --inliner-aggressiveness 0
# echo "Compiling contracts..."
# NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo}
# $NARGO compile --silence-warnings --inliner-aggressiveness 0

echo "Transpiling contracts..."
scripts/transpile.sh
@@ -28,6 +28,6 @@ echo Using BB hash $BB_HASH
tempDir="./target/tmp"
mkdir -p $tempDir

for artifactPath in "./target"/*.json; do
for artifactPath in "./target"/contract_class_registerer_contract-ContractClassRegisterer.json; do
BB_HASH=$BB_HASH node ./scripts/postprocess_contract.js "$artifactPath" "$tempDir"
done
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
use dep::aztec::protocol_types::{
constants::{
MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE,
REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE,
},
contract_class_id::ContractClassId,
traits::Serialize,
};

// #[event]
// TODO(#10007): Use MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS instead
pub global MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: u32 = 100;

pub struct ContractClassRegistered {
contract_class_id: ContractClassId,
version: Field,
artifact_hash: Field,
private_functions_root: Field,
packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS],
packed_public_bytecode: [Field; MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS],
}

impl Serialize<MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5> for ContractClassRegistered {
fn serialize(self: Self) -> [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5] {
let mut packed = [0; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5];
impl Serialize<MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5> for ContractClassRegistered {
fn serialize(
self: Self,
) -> [Field; MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5] {
let mut packed = [0; MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS + 5];
packed[0] = REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE;
packed[1] = self.contract_class_id.to_field();
packed[2] = self.version;
packed[3] = self.artifact_hash;
packed[4] = self.private_functions_root;
for i in 0..MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS {
for i in 0..MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS {
packed[i + 5] = self.packed_public_bytecode[i];
}
packed
Original file line number Diff line number Diff line change
@@ -22,7 +22,9 @@ contract ContractClassRegisterer {
};

use crate::events::{
class_registered::ContractClassRegistered,
class_registered::{
ContractClassRegistered, MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS,
},
private_function_broadcasted::{
ClassPrivateFunctionBroadcasted, InnerPrivateFunction, PrivateFunction,
},
@@ -81,13 +83,6 @@ contract ContractClassRegisterer {
);

// Emit the contract class id as a nullifier to be able to prove that this class has been (not) registered
let event = ContractClassRegistered {
contract_class_id,
version: 1,
artifact_hash,
private_functions_root,
packed_public_bytecode,
};
context.push_nullifier(contract_class_id.to_field());

// Broadcast class info including public bytecode
@@ -100,7 +95,24 @@ contract ContractClassRegisterer {
public_bytecode_commitment,
],
);
emit_contract_class_log(&mut context, event.serialize());

// 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 bytecode_length_in_fields <= MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS {
let mut event_public_bytecode =
[0; MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS];
for i in 0..MAX_BROADCASTEABLE_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS {
event_public_bytecode[i] = packed_public_bytecode[i];
}
let event = ContractClassRegistered {
contract_class_id,
version: 1,
artifact_hash,
private_functions_root,
packed_public_bytecode: event_public_bytecode,
};
emit_contract_class_log(&mut context, event.serialize());
}
}

#[private]
2 changes: 1 addition & 1 deletion yarn-project/archiver/package.json
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@
"@aztec/foundation": "workspace:^",
"@aztec/kv-store": "workspace:^",
"@aztec/l1-artifacts": "workspace:^",
"@aztec/noir-contracts.js": "workspace:^",
"@aztec/protocol-contracts": "workspace:^",
"@aztec/telemetry-client": "workspace:^",
"@aztec/types": "workspace:^",
@@ -83,7 +84,6 @@
"ws": "^8.13.0"
},
"devDependencies": {
"@aztec/noir-contracts.js": "workspace:^",
"@jest/globals": "^29.5.0",
"@types/debug": "^4.1.7",
"@types/jest": "^29.5.0",
12 changes: 11 additions & 1 deletion yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
@@ -712,6 +712,12 @@ export class Archiver implements ArchiveSource {
return this.store.getContractClassIds();
}

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

addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
return this.store.addContractArtifact(address, artifact);
}
@@ -764,7 +770,6 @@ class ArchiverStoreHelper
ArchiverDataStore,
| 'addLogs'
| 'deleteLogs'
| 'addContractClasses'
| 'deleteContractClasses'
| 'addContractInstances'
| 'deleteContractInstances'
@@ -775,6 +780,11 @@ class ArchiverStoreHelper

constructor(private readonly store: ArchiverDataStore) {}

// TODO(#10007): Remove this method
addContractClasses(contractClasses: ContractClassPublic[], blockNum: number): Promise<boolean> {
return this.store.addContractClasses(contractClasses, 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.
24 changes: 21 additions & 3 deletions yarn-project/archiver/src/factory.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { type ArchiverApi, type Service } from '@aztec/circuit-types';
import { type ContractClassPublic } from '@aztec/circuits.js';
import { type ContractClassPublic, getContractClassFromArtifact } from '@aztec/circuits.js';
import { createDebugLogger } from '@aztec/foundation/log';
import { type Maybe } from '@aztec/foundation/types';
import { createStore } from '@aztec/kv-store/utils';
import { TokenBridgeContractArtifact, TokenContractArtifact } from '@aztec/noir-contracts.js';
import { getCanonicalProtocolContract, protocolContractNames } from '@aztec/protocol-contracts';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
@@ -20,14 +21,15 @@ export async function createArchiver(
if (!config.archiverUrl) {
const store = await createStore('archiver', config, createDebugLogger('aztec:archiver:lmdb'));
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
await initWithProtocolContracts(archiverStore);
await registerProtocolContracts(archiverStore);
await registerCommonContracts(archiverStore);
return Archiver.createAndSync(config, archiverStore, telemetry, opts.blockUntilSync);
} else {
return createArchiverClient(config.archiverUrl);
}
}

async function initWithProtocolContracts(store: KVArchiverDataStore) {
async function registerProtocolContracts(store: KVArchiverDataStore) {
const blockNumber = 0;
for (const name of protocolContractNames) {
const contract = getCanonicalProtocolContract(name);
@@ -41,3 +43,19 @@ async function initWithProtocolContracts(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 = artifacts.map(artifact => ({
...getContractClassFromArtifact(artifact),
privateFunctions: [],
unconstrainedFunctions: [],
}));
await store.addContractClasses(classes, blockNumber);
}
6 changes: 3 additions & 3 deletions yarn-project/archiver/tsconfig.json
Original file line number Diff line number Diff line change
@@ -24,6 +24,9 @@
{
"path": "../l1-artifacts"
},
{
"path": "../noir-contracts.js"
},
{
"path": "../protocol-contracts"
},
@@ -32,9 +35,6 @@
},
{
"path": "../types"
},
{
"path": "../noir-contracts.js"
}
],
"include": ["src"]
6 changes: 6 additions & 0 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
@@ -819,7 +819,13 @@ export class AztecNodeService implements AztecNode {
});
}

// TODO(#10007): Remove this method
public addContractClass(contractClass: ContractClassPublic): Promise<void> {
return this.contractDataSource.addContractClass(contractClass);
}

public addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise<void> {
// TODO: Node should validate the artifact before accepting it
return this.contractDataSource.addContractArtifact(address, artifact);
}

12 changes: 12 additions & 0 deletions yarn-project/circuit-types/src/interfaces/archiver.test.ts
Original file line number Diff line number Diff line change
@@ -232,6 +232,15 @@ describe('ArchiverApiSchema', () => {
version: 1,
});
});

it('addContractClass', async () => {
const contractClass = getContractClassFromArtifact(artifact);
await context.client.addContractClass({
...omit(contractClass, 'publicBytecodeCommitment'),
unconstrainedFunctions: [],
privateFunctions: [],
});
});
});

class MockArchiver implements ArchiverApi {
@@ -362,4 +371,7 @@ class MockArchiver implements ArchiverApi {
expect(l1ToL2Message).toBeInstanceOf(Fr);
return Promise.resolve(1n);
}
addContractClass(_contractClass: ContractClassPublic): Promise<void> {
return Promise.resolve();
}
}
2 changes: 2 additions & 0 deletions yarn-project/circuit-types/src/interfaces/archiver.ts
Original file line number Diff line number Diff line change
@@ -70,4 +70,6 @@ export const ArchiverApiSchema: ApiSchemaFor<ArchiverApi> = {
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
addContractClass: z.function().args(ContractClassPublicSchema).returns(z.void()),
};
8 changes: 8 additions & 0 deletions yarn-project/circuit-types/src/interfaces/aztec-node.test.ts
Original file line number Diff line number Diff line change
@@ -313,6 +313,11 @@ describe('AztecNodeApiSchema', () => {
const response = await context.client.getEpochProofQuotes(1n);
expect(response).toEqual([expect.any(EpochProofQuote)]);
});

it('addContractClass', async () => {
const contractClass = getContractClassFromArtifact(artifact);
await context.client.addContractClass({ ...contractClass, unconstrainedFunctions: [], privateFunctions: [] });
});
});

class MockAztecNode implements AztecNode {
@@ -538,4 +543,7 @@ class MockAztecNode implements AztecNode {
expect(epoch).toEqual(1n);
return Promise.resolve([EpochProofQuote.random()]);
}
addContractClass(_contractClass: ContractClassPublic): Promise<void> {
return Promise.resolve();
}
}
10 changes: 10 additions & 0 deletions yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
@@ -391,6 +391,13 @@ export interface AztecNode extends ProverCoordination {
* @param epoch - The epoch for which to get the quotes
*/
getEpochProofQuotes(epoch: bigint): Promise<EpochProofQuote[]>;

/**
* Adds a contract class bypassing the registerer.
* TODO(#10007): Remove this method.
* @param contractClass - The class to register.
*/
addContractClass(contractClass: ContractClassPublic): Promise<void>;
}

export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
@@ -514,6 +521,9 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
addEpochProofQuote: z.function().args(EpochProofQuote.schema).returns(z.void()),

getEpochProofQuotes: z.function().args(schemas.BigInt).returns(z.array(EpochProofQuote.schema)),

// TODO(#10007): Remove this method
addContractClass: z.function().args(ContractClassPublicSchema).returns(z.void()),
};

export function createAztecNodeClient(url: string, fetch = defaultFetch): AztecNode {
Original file line number Diff line number Diff line change
@@ -26,6 +26,12 @@ export interface ContractDataSource {
*/
getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;

/**
* Adds a contract class to the database.
* TODO(#10007): Remove this method
*/
addContractClass(contractClass: ContractClassPublic): Promise<void>;

/**
* Returns a publicly deployed contract instance given its address.
* @param address - Address of the deployed contract.
Original file line number Diff line number Diff line change
@@ -5,8 +5,10 @@ import {
type ContractClassWithId,
type ContractInstanceWithAddress,
type DebugLogger,
type FieldsOf,
Fr,
type PXE,
type TxReceipt,
TxStatus,
type Wallet,
getContractClassFromArtifact,
@@ -18,10 +20,10 @@ import {
deployInstance,
registerContractClass,
} from '@aztec/aztec.js/deployment';
import { type ContractClassIdPreimage, PublicKeys } from '@aztec/circuits.js';
import { type ContractClassIdPreimage, PublicKeys, computeContractClassId } from '@aztec/circuits.js';
import { FunctionSelector, FunctionType } from '@aztec/foundation/abi';
import { writeTestData } from '@aztec/foundation/testing';
import { StatefulTestContract } from '@aztec/noir-contracts.js';
import { StatefulTestContract, TokenContractArtifact } from '@aztec/noir-contracts.js';
import { TestContract } from '@aztec/noir-contracts.js/Test';

import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js';
@@ -43,56 +45,74 @@ describe('e2e_deploy_contract contract class registration', () => {

let artifact: ContractArtifact;
let contractClass: ContractClassWithId & ContractClassIdPreimage;
let registrationTxReceipt: FieldsOf<TxReceipt>;

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

it('registers the contract class on the node', async () => {
const registeredClass = await aztecNode.getContractClass(contractClass.id);
expect(registeredClass).toBeDefined();
expect(registeredClass!.artifactHash.toString()).toEqual(contractClass.artifactHash.toString());
expect(registeredClass!.privateFunctionsRoot.toString()).toEqual(contractClass.privateFunctionsRoot.toString());
expect(registeredClass!.packedBytecode.toString('hex')).toEqual(contractClass.packedBytecode.toString('hex'));
expect(registeredClass!.publicFunctions).toEqual(contractClass.publicFunctions);
expect(registeredClass!.privateFunctions).toEqual([]);
// 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: [] });
});

it('broadcasts a private function', async () => {
const constructorArtifact = artifact.functions.find(fn => fn.name == 'constructor');
if (!constructorArtifact) {
// If this gets thrown you've probably modified the StatefulTestContract to no longer include constructor.
// If that's the case you should update this test to use a private function which fits into the bytecode size
// limit.
throw new Error('No constructor found in the StatefulTestContract artifact. Does it still exist?');
}
const selector = FunctionSelector.fromNameAndParameters(constructorArtifact.name, constructorArtifact.parameters);

const tx = await (await broadcastPrivateFunction(wallet, artifact, selector)).send().wait();
const logs = await pxe.getContractClassLogs({ txHash: tx.txHash });
const logData = logs.logs[0].log.data;
writeTestData('yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex', logData);

const fetchedClass = await aztecNode.getContractClass(contractClass.id);
const fetchedFunction = fetchedClass!.privateFunctions[0]!;
expect(fetchedFunction).toBeDefined();
expect(fetchedFunction.selector).toEqual(selector);
});
describe('registering a contract class', () => {
// 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 classId = computeContractClassId(getContractClassFromArtifact(TokenContractArtifact));
expect(await aztecNode.getContractClass(classId)).not.toBeUndefined();
});

it('broadcasts an unconstrained function', async () => {
const functionArtifact = artifact.functions.find(fn => fn.functionType === FunctionType.UNCONSTRAINED)!;
const selector = FunctionSelector.fromNameAndParameters(functionArtifact);
const tx = await (await broadcastUnconstrainedFunction(wallet, artifact, selector)).send().wait();
const logs = await pxe.getContractClassLogs({ txHash: tx.txHash });
const logData = logs.logs[0].log.data;
writeTestData('yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex', logData);

const fetchedClass = await aztecNode.getContractClass(contractClass.id);
const fetchedFunction = fetchedClass!.unconstrainedFunctions[0]!;
expect(fetchedFunction).toBeDefined();
expect(fetchedFunction.selector).toEqual(selector);
it('registers the contract class on the node', async () => {
const registeredClass = await aztecNode.getContractClass(contractClass.id);
expect(registeredClass).toBeDefined();
expect(registeredClass!.artifactHash.toString()).toEqual(contractClass.artifactHash.toString());
expect(registeredClass!.privateFunctionsRoot.toString()).toEqual(contractClass.privateFunctionsRoot.toString());
expect(registeredClass!.packedBytecode.toString('hex')).toEqual(contractClass.packedBytecode.toString('hex'));
expect(registeredClass!.publicFunctions).toEqual(contractClass.publicFunctions);
expect(registeredClass!.privateFunctions).toEqual([]);
});

it('broadcasts a private function', async () => {
const constructorArtifact = artifact.functions.find(fn => fn.name == 'constructor');
if (!constructorArtifact) {
// If this gets thrown you've probably modified the StatefulTestContract to no longer include constructor.
// If that's the case you should update this test to use a private function which fits into the bytecode size limit.
throw new Error('No constructor found in the StatefulTestContract artifact. Does it still exist?');
}
const selector = FunctionSelector.fromNameAndParameters(constructorArtifact.name, constructorArtifact.parameters);

const tx = await (await broadcastPrivateFunction(wallet, artifact, selector)).send().wait();
const logs = await pxe.getContractClassLogs({ txHash: tx.txHash });
const logData = logs.logs[0].log.data;
writeTestData('yarn-project/circuits.js/fixtures/PrivateFunctionBroadcastedEventData.hex', logData);

const fetchedClass = await aztecNode.getContractClass(contractClass.id);
const fetchedFunction = fetchedClass!.privateFunctions[0]!;
expect(fetchedFunction).toBeDefined();
expect(fetchedFunction.selector).toEqual(selector);
});

it('broadcasts an unconstrained function', async () => {
const functionArtifact = artifact.functions.find(fn => fn.functionType === FunctionType.UNCONSTRAINED)!;
const selector = FunctionSelector.fromNameAndParameters(functionArtifact);
const tx = await (await broadcastUnconstrainedFunction(wallet, artifact, selector)).send().wait();
const logs = await pxe.getContractClassLogs({ txHash: tx.txHash });
const logData = logs.logs[0].log.data;
writeTestData('yarn-project/circuits.js/fixtures/UnconstrainedFunctionBroadcastedEventData.hex', logData);

const fetchedClass = await aztecNode.getContractClass(contractClass.id);
const fetchedFunction = fetchedClass!.unconstrainedFunctions[0]!;
expect(fetchedFunction).toBeDefined();
expect(fetchedFunction.selector).toEqual(selector);
});
});

const testDeployingAnInstance = (how: string, deployFn: (toDeploy: ContractInstanceWithAddress) => Promise<void>) =>
Original file line number Diff line number Diff line change
@@ -84,7 +84,8 @@ describe('e2e_deploy_contract legacy', () => {
await expect(deployer.deploy().send({ contractAddressSalt }).wait()).rejects.toThrow(/dropped/);
});

it('should not deploy a contract which failed the public part of the execution', async () => {
// TODO(#10007): Reenable this test.
it.skip('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;
8 changes: 7 additions & 1 deletion yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
@@ -242,7 +242,8 @@ export class PXEService implements PXE {

if (artifact) {
// If the user provides an artifact, validate it against the expected class id and register it
const contractClassId = computeContractClassId(getContractClassFromArtifact(artifact));
const contractClass = getContractClassFromArtifact(artifact);
const contractClassId = computeContractClassId(contractClass);
if (!contractClassId.equals(instance.contractClassId)) {
throw new Error(
`Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.contractClassId})`,
@@ -256,7 +257,12 @@ 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 {
// Otherwise, make sure there is an artifact already registered for that class id
artifact = await this.db.getContractArtifact(instance.contractClassId);
6 changes: 6 additions & 0 deletions yarn-project/txe/src/util/txe_public_contract_data_source.ts
Original file line number Diff line number Diff line change
@@ -71,4 +71,10 @@ export class TXEPublicContractDataSource implements ContractDataSource {
addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise<void> {
return this.txeOracle.addContractArtifact(contract);
}

// TODO(#10007): Remove this method.
addContractClass(_contractClass: ContractClassPublic): Promise<void> {
// We don't really need to do anything for the txe here
return Promise.resolve();
}
}

0 comments on commit ce8db73

Please sign in to comment.