diff --git a/bootstrap.sh b/bootstrap.sh index a59713e7386a..a24890080c9c 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -58,6 +58,7 @@ PROJECTS=( "yarn-project/kernel-prover:yarn build" "yarn-project/aztec-rpc:yarn build" "yarn-project/aztec.js:yarn build" + "yarn-project/noir-contracts:yarn build" ) for E in "${PROJECTS[@]}"; do diff --git a/yarn-project/acir-simulator/package.json b/yarn-project/acir-simulator/package.json index f16e40391455..170a065e2d7b 100644 --- a/yarn-project/acir-simulator/package.json +++ b/yarn-project/acir-simulator/package.json @@ -29,6 +29,7 @@ "rootDir": "./src" }, "dependencies": { + "@aztec/circuits.js": "workspace:^", "tslib": "^2.4.0" }, "devDependencies": { diff --git a/yarn-project/acir-simulator/src/acvm.ts b/yarn-project/acir-simulator/src/acvm.ts index 2c2f5daabe24..a80dc2d88eec 100644 --- a/yarn-project/acir-simulator/src/acvm.ts +++ b/yarn-project/acir-simulator/src/acvm.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CallContext, ContractDeploymentData } from './circuits.js'; +import { AztecAddress, CallContext, ContractDeploymentData } from '@aztec/circuits.js'; import { NoteLoadOracleInputs } from './db_oracle.js'; export interface ACIRCallback { diff --git a/yarn-project/acir-simulator/src/circuits.ts b/yarn-project/acir-simulator/src/circuits.ts deleted file mode 100644 index 917b55cc08a2..000000000000 --- a/yarn-project/acir-simulator/src/circuits.ts +++ /dev/null @@ -1,229 +0,0 @@ -// See aztec3/constants.hpp -// Copied here for prototyping purposes -// In future: structured serialization? -export const ARGS_LENGTH = 8; -export const RETURN_VALUES_LENGTH = 4; -export const EMITTED_EVENTS_LENGTH = 4; - -export const NEW_COMMITMENTS_LENGTH = 4; -export const NEW_NULLIFIERS_LENGTH = 4; - -export const STATE_TRANSITIONS_LENGTH = 4; -export const STATE_READS_LENGTH = 4; - -export const PRIVATE_CALL_STACK_LENGTH = 4; -export const PUBLIC_CALL_STACK_LENGTH = 4; -export const L1_MSG_STACK_LENGTH = 2; - -export const KERNEL_NEW_COMMITMENTS_LENGTH = 16; -export const KERNEL_NEW_NULLIFIERS_LENGTH = 16; -export const KERNEL_NEW_CONTRACTS_LENGTH = 8; -export const KERNEL_PRIVATE_CALL_STACK_LENGTH = 8; -export const KERNEL_PUBLIC_CALL_STACK_LENGTH = 8; -export const KERNEL_L1_MSG_STACK_LENGTH = 4; -export const KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH = 4; - -export const VK_TREE_HEIGHT = 3; -export const CONTRACT_TREE_HEIGHT = 4; -export const PRIVATE_DATA_TREE_HEIGHT = 8; -export const NULLIFIER_TREE_HEIGHT = 8; - -export const PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT = 8; -export const CONTRACT_TREE_ROOTS_TREE_HEIGHT = 8; - -export const FUNCTION_SELECTOR_NUM_BYTES = 31; - -/** - * Assert a member is a certain length. - * @param obj - An object. - * @param member - A member string. - * @param length - The length. - */ -export function assertLength( - obj: T, - member: F, - length: number, -) { - if (obj[member].length !== length) { - throw new Error(`Expected ${member} to have length ${length}! Was: ${obj[member].length}`); - } -} - -export class Fr { - public static ZERO = new Fr(Buffer.alloc(32)); - - constructor(public readonly buffer: Buffer) {} -} - -export class AztecAddress { - public static SIZE = 64; - - public static ZERO = new AztecAddress(Buffer.alloc(AztecAddress.SIZE)); - - constructor(public readonly buffer: Buffer) {} - - public equals(rhs: AztecAddress) { - return this.buffer.equals(rhs.buffer); - } -} - -export class EthAddress { - public static ZERO = new EthAddress(Buffer.alloc(20)); - - constructor(public readonly buffer: Buffer) {} -} - -/** - * Call context. - * @see abis/call_context.hpp - */ -export class CallContext { - constructor( - public msgSender: AztecAddress, - public storageContractAddress: AztecAddress, - public portalContractAddress: EthAddress, - public isDelegateCall: boolean, - public isStaticCall: boolean, - public isContractDeployment: boolean, - ) {} -} - -/** - * Contract deployment data in a @TxContext. - * cpp/src/aztec3/circuits/abis/contract_deployment_data.hpp - */ -export class ContractDeploymentData { - constructor( - public constructorVkHash: Fr, - public functionTreeRoot: Fr, - public contractAddressSalt: Fr, - public portalContractAddress: EthAddress, - ) {} -} - -/** - * Public inputs to a private circuit. - * @see abis/private_circuit_public_inputs.hpp. - */ -export class PrivateCircuitPublicInputs { - constructor( - // NOTE: Must have same order as CPP. - public callContext: CallContext, - public args: Fr[], - public returnValues: Fr[], - public emittedEvents: Fr[], - public newCommitments: Fr[], - public newNullifiers: Fr[], - public privateCallStack: Fr[], - public publicCallStack: Fr[], - public l1MsgStack: Fr[], - public historicPrivateDataTreeRoot: Fr, - public historicPrivateNullifierTreeRoot: Fr, - public historicContractTreeRoot: Fr, - public contractDeploymentData: ContractDeploymentData, - ) { - assertLength(this, 'args', ARGS_LENGTH); - assertLength(this, 'returnValues', RETURN_VALUES_LENGTH); - assertLength(this, 'emittedEvents', EMITTED_EVENTS_LENGTH); - assertLength(this, 'newCommitments', NEW_COMMITMENTS_LENGTH); - assertLength(this, 'newNullifiers', NEW_NULLIFIERS_LENGTH); - assertLength(this, 'privateCallStack', PRIVATE_CALL_STACK_LENGTH); - assertLength(this, 'publicCallStack', PUBLIC_CALL_STACK_LENGTH); - assertLength(this, 'l1MsgStack', L1_MSG_STACK_LENGTH); - } -} - -export class TxContext { - constructor( - public readonly isFeePaymentTx: boolean, - public readonly isRebatePaymentTx: boolean, - public readonly isContractDeploymentTx: boolean, - public readonly contractDeploymentData: ContractDeploymentData, - ) {} -} - -export interface FunctionData { - functionSelector: Buffer; - isSecret: boolean; - isContructor: boolean; -} - -export class TxRequest { - constructor( - public readonly from: AztecAddress, - public readonly to: AztecAddress, - public readonly functionData: FunctionData, - public readonly args: Fr[], - public readonly txContext: TxContext, - public readonly nonce: Fr, - public readonly chainId: Fr, - ) {} - - toBuffer() { - return Buffer.alloc(0); - } -} - -export class PrivateCallStackItem { - constructor( - public readonly contractAddress: AztecAddress, - public readonly functionSelector: Buffer, - public readonly publicInputs: PrivateCircuitPublicInputs, - ) {} -} - -export class OldTreeRoots { - constructor( - public privateDataTreeRoot: Fr, - public nullifierTreeRoot: Fr, - public contractTreeRoot: Fr, - public privateKernelVkTreeRoot: Fr, // future enhancement - ) {} -} - -export class ConstantData { - constructor(public oldTreeRoots: OldTreeRoots, public txContext: TxContext) {} -} - -export class AggregationObject {} - -export class NewContractData { - constructor( - public readonly contractAddress: AztecAddress, - public readonly portalContractAddress: EthAddress, - public readonly functionTreeRoot: Fr, - ) {} -} - -export class OptionallyRevealedData {} - -export class AccumulatedTxData { - constructor( - public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations - - public privateCallCount: Fr, - - public newCommitments: Fr[], - public newNullifiers: Fr[], - - public privateCallStack: Fr[], - public publicCallStack: Fr[], - public l1MsgStack: Fr[], - - public newContracts: NewContractData[], - - public optionallyRevealedData: OptionallyRevealedData[], - ) { - assertLength(this, 'newCommitments', KERNEL_NEW_COMMITMENTS_LENGTH); - assertLength(this, 'newNullifiers', KERNEL_NEW_NULLIFIERS_LENGTH); - assertLength(this, 'privateCallStack', KERNEL_PRIVATE_CALL_STACK_LENGTH); - assertLength(this, 'publicCallStack', KERNEL_PUBLIC_CALL_STACK_LENGTH); - assertLength(this, 'l1MsgStack', KERNEL_L1_MSG_STACK_LENGTH); - assertLength(this, 'newContracts', KERNEL_NEW_CONTRACTS_LENGTH); - assertLength(this, 'optionallyRevealedData', KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH); - } -} - -export class PrivateKernelPublicInputs { - constructor(public end: AccumulatedTxData, public constants: ConstantData, public isPrivateKernel: true) {} -} diff --git a/yarn-project/acir-simulator/src/db_oracle.ts b/yarn-project/acir-simulator/src/db_oracle.ts index ae006a01f950..521664e2c400 100644 --- a/yarn-project/acir-simulator/src/db_oracle.ts +++ b/yarn-project/acir-simulator/src/db_oracle.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress } from './circuits.js'; +import { AztecAddress, EthAddress, PrivateCircuitPublicInputs } from '@aztec/circuits.js'; export interface NoteLoadOracleInputs { note: Buffer; @@ -14,3 +14,11 @@ export interface DBOracle { getProvingKey(contractAddress: AztecAddress, functionSelector: string): Promise; getPortalContractAddress(contractAddress: AztecAddress): Promise; } + +export class PrivateCallStackItem { + constructor( + public readonly contractAddress: AztecAddress, + public readonly functionSelector: number, + public readonly publicInputs: PrivateCircuitPublicInputs, + ) {} +} diff --git a/yarn-project/acir-simulator/src/simulator.ts b/yarn-project/acir-simulator/src/simulator.ts index 0716d462c694..ed3cdc159c0d 100644 --- a/yarn-project/acir-simulator/src/simulator.ts +++ b/yarn-project/acir-simulator/src/simulator.ts @@ -2,11 +2,20 @@ import { ExecutionPreimages } from './acvm.js'; import { CallContext, PrivateCircuitPublicInputs, - TxRequest, EthAddress, - PrivateCallStackItem, OldTreeRoots, -} from './circuits.js'; + Fr, + ARGS_LENGTH, + EMITTED_EVENTS_LENGTH, + NEW_COMMITMENTS_LENGTH, + NEW_NULLIFIERS_LENGTH, + PRIVATE_CALL_STACK_LENGTH, + PUBLIC_CALL_STACK_LENGTH, + L1_MSG_STACK_LENGTH, + RETURN_VALUES_LENGTH, + TxRequest, +} from '@aztec/circuits.js'; +import { PrivateCallStackItem } from './db_oracle.js'; export interface ExecutionResult { // Needed for prover @@ -36,19 +45,25 @@ export class AcirSimulator { portalContractAddress, false, false, - request.functionData.isContructor, + request.functionData.isConstructor, ); + const randomFields = (num: number) => { + return Array(num) + .fill(0) + .map(() => new Fr(0)); + }; + const publicInputs = new PrivateCircuitPublicInputs( callContext, - request.args, - [], // returnValues, - [], // emittedEvents, - [], // newCommitments, - [], // newNullifiers, - [], // privateCallStack, - [], // publicCallStack, - [], // l1MsgStack, + request.args.concat(randomFields(ARGS_LENGTH - request.args.length)), + randomFields(RETURN_VALUES_LENGTH), // returnValues, + randomFields(EMITTED_EVENTS_LENGTH), // emittedEvents, + randomFields(NEW_COMMITMENTS_LENGTH), // newCommitments, + randomFields(NEW_NULLIFIERS_LENGTH), // newNullifiers, + randomFields(PRIVATE_CALL_STACK_LENGTH), // privateCallStack, + randomFields(PUBLIC_CALL_STACK_LENGTH), // publicCallStack, + randomFields(L1_MSG_STACK_LENGTH), // l1MsgStack, oldRoots.privateDataTreeRoot, oldRoots.nullifierTreeRoot, oldRoots.contractTreeRoot, diff --git a/yarn-project/acir-simulator/tsconfig.dest.json b/yarn-project/acir-simulator/tsconfig.dest.json index 965aaa1c433e..924fe6549e6a 100644 --- a/yarn-project/acir-simulator/tsconfig.dest.json +++ b/yarn-project/acir-simulator/tsconfig.dest.json @@ -1,4 +1,9 @@ { "extends": ".", - "exclude": ["**/*.test.*", "**/fixtures/*"] + "exclude": ["**/*.test.*", "**/fixtures/*"], + "references": [ + { + "path": "../circuits.js/tsconfig.dest.json" + } + ] } diff --git a/yarn-project/acir-simulator/tsconfig.json b/yarn-project/acir-simulator/tsconfig.json index f67ddec9fd6b..687c3e5874f2 100644 --- a/yarn-project/acir-simulator/tsconfig.json +++ b/yarn-project/acir-simulator/tsconfig.json @@ -5,5 +5,10 @@ "rootDir": "src", "tsBuildInfoFile": ".tsbuildinfo" }, + "references": [ + { + "path": "../circuits.js/tsconfig.dest.json" + } + ], "include": ["src"] } diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index 298c535dea55..418843ea1d74 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -224,7 +224,7 @@ export class Archiver implements L2BlockSource { if (from > this.l2Blocks.length) { return Promise.resolve([]); } - const startIndex = from - 1; + const startIndex = from - INITIAL_ROLLUP_ID; const endIndex = startIndex + take; return Promise.resolve(this.l2Blocks.slice(startIndex, endIndex)); } diff --git a/yarn-project/aztec-node/src/aztec-node/fixtures.ts b/yarn-project/aztec-node/src/aztec-node/fixtures.ts index 77ad85fa0689..a3a4bd79805f 100644 --- a/yarn-project/aztec-node/src/aztec-node/fixtures.ts +++ b/yarn-project/aztec-node/src/aztec-node/fixtures.ts @@ -29,27 +29,6 @@ import { AztecAddress, randomBytes } from '@aztec/foundation'; import { Rollup, Yeeter } from '@aztec/l1-contracts'; import { Tx } from '@aztec/tx'; -// REFACTOR: Move deployment logic to l1-contracts package, and refactor it out of other integration tests (archiver, sequencer) -export const deployRollupContract = async (provider: WalletProvider, ethRpc: EthereumRpc) => { - const deployAccount = provider.getAccount(0); - const contract = new Rollup(ethRpc, undefined, { from: deployAccount, gas: 1000000 }); - await contract.deploy().send().getReceipt(); - return contract.address; -}; - -export const deployYeeterContract = async (provider: WalletProvider, ethRpc: EthereumRpc) => { - const deployAccount = provider.getAccount(0); - const contract = new Yeeter(ethRpc, undefined, { from: deployAccount, gas: 1000000 }); - await contract.deploy().send().getReceipt(); - return contract.address; -}; - -export const createProvider = (host: string, mnemonic: string, accounts: number) => { - const walletProvider = WalletProvider.fromHost(host); - walletProvider.addAccountsFromMnemonic(mnemonic, accounts); - return walletProvider; -}; - // REFACTOR: Use @aztec/circuit.js/factories where possible export const createCircuitEthAddress = () => { return new CircuitEthAddress(randomBytes(20)); diff --git a/yarn-project/aztec-rpc/src/account_state/account_state.ts b/yarn-project/aztec-rpc/src/account_state/account_state.ts index ade77279b980..84889fe73206 100644 --- a/yarn-project/aztec-rpc/src/account_state/account_state.ts +++ b/yarn-project/aztec-rpc/src/account_state/account_state.ts @@ -1,6 +1,5 @@ +import { AztecAddress } from '@aztec/circuits.js'; import { TxHash } from '@aztec/tx'; - -import { AztecAddress } from '../circuits.js'; import { Database } from '../database/index.js'; export class AccountState { diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_client/aztec_rpc_client.ts b/yarn-project/aztec-rpc/src/aztec_rpc_client/aztec_rpc_client.ts index 74a776d54ae0..31e459d1da4e 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_client/aztec_rpc_client.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_client/aztec_rpc_client.ts @@ -1,5 +1,6 @@ +import { AztecAddress, EthAddress, Fr, TxRequest } from '@aztec/circuits.js'; import { Tx, TxHash } from '@aztec/tx'; -import { AztecAddress, EthAddress, Fr, Signature, TxRequest } from '../circuits.js'; +import { Signature } from '../circuits.js'; import { ContractAbi } from '../noir.js'; import { TxReceipt } from '../tx/index.js'; diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts index d98b30e62370..b5d509ae9a5c 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts @@ -1,39 +1,48 @@ import { AcirSimulator } from '@aztec/acir-simulator'; import { AztecNode } from '@aztec/aztec-node'; -import { UInt8Vector } from '@aztec/circuits.js'; +import { ARGS_LENGTH, TxRequest, UInt8Vector } from '@aztec/circuits.js'; import { KernelProver } from '@aztec/kernel-prover'; import { Tx, TxHash } from '@aztec/tx'; - import { generateFunctionSelector } from '../abi_coder/index.js'; import { AztecRPCClient } from '../aztec_rpc_client/index.js'; import { AztecAddress, ContractDeploymentData, EthAddress, - Fr, - generateContractAddress, + FunctionData, OldTreeRoots, - Signature, TxContext, - TxRequest, -} from '../circuits.js'; -import { ContractDao, ContractDataSource } from '../contract_data_source/index.js'; +} from '@aztec/circuits.js'; +import { ContractDao } from '../contract_data_source/index.js'; import { KeyStore } from '../key_store/index.js'; import { ContractAbi } from '../noir.js'; import { Synchroniser } from '../synchroniser/index.js'; +import { generateContractAddress, selectorToNumber, Signature, ZERO_FR } from '../circuits.js'; +import { createDebugLogger, randomBytes, Fr } from '@aztec/foundation'; +import { Database } from '../database/database.js'; +import { TxDao } from '../database/tx_dao.js'; export class AztecRPCServer implements AztecRPCClient { + private synchroniser: Synchroniser; constructor( private keyStore: KeyStore, - private synchroniser: Synchroniser, private acirSimulator: AcirSimulator, private kernelProver: KernelProver, private node: AztecNode, - private db: ContractDataSource, - ) {} + private db: Database, + private log = createDebugLogger('aztec:rpc_server'), + ) { + this.synchroniser = new Synchroniser(node, db); + this.synchroniser.start(); + } + + public async stop() { + await this.synchroniser.stop(); + } public async addAccount() { const accountPublicKey = await this.keyStore.addAccount(); + this.log(`adding account ${accountPublicKey.toString()}`); await this.synchroniser.addAccount(accountPublicKey); return accountPublicKey; } @@ -43,7 +52,7 @@ export class AztecRPCServer implements AztecRPCClient { } public getStorageAt(contract: AztecAddress, storageSlot: Fr) { - return Promise.resolve(); + return Promise.resolve([[0]]); } public getCode(contract: AztecAddress, functionSelector?: Buffer) { @@ -62,33 +71,41 @@ export class AztecRPCServer implements AztecRPCClient { throw new Error('Cannot find constructor in the ABI.'); } - const functionData = { - functionSelector: generateFunctionSelector(constructorAbi.name, constructorAbi.parameters), - isSecret: true, - isContructor: true, - }; + const functionData = new FunctionData( + selectorToNumber(generateFunctionSelector(constructorAbi.name, constructorAbi.parameters)), + true, + true, + ); - const constructorVkHash = Fr.ZERO; - const functionTreeRoot = Fr.ZERO; + const constructorVkHash = ZERO_FR; + const functionTreeRoot = ZERO_FR; const contractDeploymentData = new ContractDeploymentData( constructorVkHash, functionTreeRoot, contractAddressSalt, portalContract, ); - const txContext = new TxContext(false, false, false, contractDeploymentData); + const txContext = new TxContext(false, false, true, contractDeploymentData); - const contractAddress = generateContractAddress(from, contractAddressSalt, args); + const fromAddress = from.toBuffer().equals(ZERO_FR.toBuffer()) ? (await this.keyStore.getAccounts())[0] : from; + + const contractAddress = generateContractAddress(fromAddress, contractAddressSalt, args); await this.db.addContract(contractAddress, portalContract, abi, false); + const txRequestArgs = args.concat( + Array(ARGS_LENGTH - args.length) + .fill(0) + .map(() => new Fr(0)), + ); + return new TxRequest( - from, - AztecAddress.ZERO, // to + fromAddress, + contractAddress, functionData, - args, + txRequestArgs, + new Fr(randomBytes(Fr.SIZE_IN_BYTES)), // nonce txContext, - Fr.random(), // nonce - Fr.ZERO, // chainId + ZERO_FR, // chainId ); } @@ -100,22 +117,27 @@ export class AztecRPCServer implements AztecRPCClient { const functionDao = this.findFunction(contract, functionSelector); - const functionData = { - functionSelector, - isSecret: functionDao.isSecret, - isContructor: false, - }; + const functionData = new FunctionData( + functionSelector.readUint32BE(), + functionDao.isSecret as any, // TODO: remove as any + false as any, // TODO: remove as any + ); - const txContext = new TxContext(false, false, false, ContractDeploymentData.EMPTY); + const txContext = new TxContext( + false, + false, + true, + new ContractDeploymentData(ZERO_FR, ZERO_FR, ZERO_FR, new EthAddress(Buffer.alloc(EthAddress.SIZE_IN_BYTES))), + ); return new TxRequest( from, to, functionData, args, + new Fr(randomBytes(Fr.SIZE_IN_BYTES)), // nonce txContext, - Fr.random(), // nonce - Fr.ZERO, // chainId + ZERO_FR, // chainId ); } @@ -126,7 +148,7 @@ export class AztecRPCServer implements AztecRPCClient { public async createTx(txRequest: TxRequest, signature: Signature) { let contractAddress; - if (txRequest.to.equals(AztecAddress.ZERO)) { + if (txRequest.to.toBuffer().equals(ZERO_FR.toBuffer())) { contractAddress = generateContractAddress( txRequest.from, txRequest.txContext.contractDeploymentData.contractAddressSalt, @@ -142,9 +164,12 @@ export class AztecRPCServer implements AztecRPCClient { throw new Error('Unknown contract.'); } - const functionDao = this.findFunction(contract, txRequest.functionData.functionSelector); + const selector = Buffer.alloc(4); + selector.writeUint32BE(txRequest.functionData.functionSelector); + + const functionDao = this.findFunction(contract, selector); - const oldRoots = new OldTreeRoots(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); // TODO - get old roots from the database/node + const oldRoots = new OldTreeRoots(ZERO_FR, ZERO_FR, ZERO_FR, ZERO_FR); // TODO - get old roots from the database/node const executionResult = await this.acirSimulator.run( txRequest, Buffer.from(functionDao.bytecode, 'base64'), @@ -157,8 +182,18 @@ export class AztecRPCServer implements AztecRPCClient { executionResult, oldRoots as any, // TODO - remove `as any` ); - // TODO I think the TX should include all the data from the publicInputs + proof - return new Tx(publicInputs, new UInt8Vector(Buffer.alloc(0))); + const tx = new Tx(publicInputs, new UInt8Vector(Buffer.alloc(0))); + const dao: TxDao = new TxDao( + new TxHash(tx.txId), + undefined, + undefined, + txRequest.from, + undefined, + txRequest.to, + '', + ); + await this.db.addOrUpdateTx(dao); + return tx; } public async sendTx(tx: Tx) { diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/create_aztec_rpc_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/create_aztec_rpc_server.ts index 06c0ea900081..4527834ea170 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/create_aztec_rpc_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/create_aztec_rpc_server.ts @@ -3,7 +3,6 @@ import { AztecNode } from '@aztec/aztec-node'; import { KernelProver } from '@aztec/kernel-prover'; import { MemoryDB } from '../database/index.js'; import { KeyStore, TestKeyStore } from '../key_store/index.js'; -import { Synchroniser } from '../synchroniser/index.js'; import { AztecRPCServer } from './aztec_rpc_server.js'; export async function createAztecRPCServer( @@ -11,22 +10,19 @@ export async function createAztecRPCServer( { keyStore, db, - synchroniser, acirSimulator, kernelProver, }: { keyStore?: KeyStore; db?: MemoryDB; - synchroniser?: Synchroniser; acirSimulator?: AcirSimulator; kernelProver?: KernelProver; } = {}, ) { keyStore = keyStore || new TestKeyStore(); db = db || new MemoryDB(); - synchroniser = synchroniser || new Synchroniser(aztecNode, db); acirSimulator = acirSimulator || new AcirSimulator(); kernelProver = kernelProver || new KernelProver(); - return await Promise.resolve(new AztecRPCServer(keyStore, synchroniser, acirSimulator, kernelProver, aztecNode, db)); + return await Promise.resolve(new AztecRPCServer(keyStore, acirSimulator, kernelProver, aztecNode, db)); } diff --git a/yarn-project/aztec-rpc/src/circuits.ts b/yarn-project/aztec-rpc/src/circuits.ts index 7360897095fc..7ad35d3c635a 100644 --- a/yarn-project/aztec-rpc/src/circuits.ts +++ b/yarn-project/aztec-rpc/src/circuits.ts @@ -1,114 +1,18 @@ -import { randomBytes } from './foundation.js'; +import { AztecAddress, Fr } from '@aztec/circuits.js'; +import { randomBytes } from '@aztec/foundation'; -export class Fr { - public static ZERO = new Fr(Buffer.alloc(32)); - - public static random() { - return new Fr(randomBytes(32)); - } - - constructor(public readonly buffer: Buffer) {} -} - -export class EthAddress { - public static ZERO = new EthAddress(Buffer.alloc(20)); - - public static random() { - return new EthAddress(randomBytes(20)); - } - - public static fromString(address: string) { - return new EthAddress(Buffer.from(address.replace(/^0x/i, ''), 'hex')); - } - - constructor(public readonly buffer: Buffer) {} -} - -export class AztecAddress { - public static SIZE = 64; - - public static ZERO = new AztecAddress(Buffer.alloc(AztecAddress.SIZE)); - - public static random() { - return new AztecAddress(randomBytes(AztecAddress.SIZE)); - } - - constructor(public readonly buffer: Buffer) {} - - public equals(rhs: AztecAddress) { - return this.buffer.equals(rhs.buffer); - } -} +export const ZERO_FR = new Fr(Buffer.alloc(Fr.SIZE_IN_BYTES)); export class Signature { public static SIZE = 64; public static random() { - return new EthAddress(randomBytes(Signature.SIZE)); + return new Signature(randomBytes(Signature.SIZE)); } constructor(public readonly buffer: Buffer) {} } -export interface FunctionData { - functionSelector: Buffer; - isSecret: boolean; - isContructor: boolean; -} - -/** - * Contract deployment data in a TxContext - * cpp/src/aztec3/circuits/abis/contract_deployment_data.hpp - */ -export class ContractDeploymentData { - public static EMPTY = new ContractDeploymentData(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); - - constructor( - public constructorVkHash: Fr, - public functionTreeRoot: Fr, - public contractAddressSalt: Fr, - public portalContractAddress: EthAddress, - ) {} -} - -export class TxContext { - constructor( - public readonly isFeePaymentTx: boolean, - public readonly isRebatePaymentTx: boolean, - public readonly isContractDeploymentTx: boolean, - public readonly contractDeploymentData: ContractDeploymentData, - ) {} -} - -export class TxRequest { - constructor( - public readonly from: AztecAddress, - public readonly to: AztecAddress, - public readonly functionData: FunctionData, - public readonly args: Fr[], - public readonly txContext: TxContext, - public readonly nonce: Fr, - public readonly chainId: Fr, - ) {} - - toBuffer() { - return Buffer.alloc(0); - } -} - -export class PreviousKernelData {} - -export class PrivateCallData {} - -export class KernelPrivateInputs { - constructor( - public readonly txRequest: TxRequest, - public readonly signature: Signature, - public readonly previousKernelData: PreviousKernelData, - public readonly privateCallData: PrivateCallData, - ) {} -} - export function generateContractAddress( deployerAddress: AztecAddress, salt: Fr, @@ -118,50 +22,6 @@ export function generateContractAddress( return AztecAddress.random(); } -export class OldTreeRoots { - constructor( - public privateDataTreeRoot: Fr, - public nullifierTreeRoot: Fr, - public contractTreeRoot: Fr, - public privateKernelVkTreeRoot: Fr, // future enhancement - ) {} -} - -export class ConstantData { - constructor(public oldTreeRoots: OldTreeRoots, public txContext: TxContext) {} -} - -export class AggregationObject {} - -export class NewContractData { - constructor( - public readonly contractAddress: AztecAddress, - public readonly portalContractAddress: EthAddress, - public readonly functionTreeRoot: Fr, - ) {} -} - -export class OptionallyRevealedData {} - -export class AccumulatedTxData { - constructor( - public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations - - public privateCallCount: Fr, - - public newCommitments: Fr[], - public newNullifiers: Fr[], - - public privateCallStack: Fr[], - public publicCallStack: Fr[], - public l1MsgStack: Fr[], - - public newContracts: NewContractData[], - - public optionallyRevealedData: OptionallyRevealedData[], - ) {} -} - -export class PrivateKernelPublicInputs { - constructor(public end: AccumulatedTxData, public constants: ConstantData, public isPrivateKernel: true) {} +export function selectorToNumber(selector: Buffer) { + return selector.readUInt32BE(); } diff --git a/yarn-project/aztec-rpc/src/contract_data_source/contract_dao.ts b/yarn-project/aztec-rpc/src/contract_data_source/contract_dao.ts index ae3f167c3985..dfc4b1f5a677 100644 --- a/yarn-project/aztec-rpc/src/contract_data_source/contract_dao.ts +++ b/yarn-project/aztec-rpc/src/contract_data_source/contract_dao.ts @@ -1,5 +1,5 @@ import { generateFunctionSelector } from '../abi_coder/index.js'; -import { AztecAddress, EthAddress } from '../circuits.js'; +import { AztecAddress, EthAddress } from '@aztec/circuits.js'; import { ContractAbi, FunctionAbi } from '../noir.js'; export interface ContractFunctionDao extends FunctionAbi { @@ -14,10 +14,9 @@ export interface ContractDao extends ContractAbi { } export function functionAbiToFunctionDao(abi: FunctionAbi) { - const selector = generateFunctionSelector(abi.name, abi.parameters); return { ...abi, - selector, + selector: generateFunctionSelector(abi.name, abi.parameters), }; } diff --git a/yarn-project/aztec-rpc/src/contract_data_source/contract_data_source.ts b/yarn-project/aztec-rpc/src/contract_data_source/contract_data_source.ts index 917884b8dd05..db336b2a16d7 100644 --- a/yarn-project/aztec-rpc/src/contract_data_source/contract_data_source.ts +++ b/yarn-project/aztec-rpc/src/contract_data_source/contract_data_source.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress } from '../circuits.js'; +import { AztecAddress, EthAddress } from '@aztec/circuits.js'; import { ContractAbi } from '../noir.js'; import { ContractDao } from './contract_dao.js'; diff --git a/yarn-project/aztec-rpc/src/contract_data_source/memory_contract_data_source.ts b/yarn-project/aztec-rpc/src/contract_data_source/memory_contract_data_source.ts index e342908b14bc..f1783e109941 100644 --- a/yarn-project/aztec-rpc/src/contract_data_source/memory_contract_data_source.ts +++ b/yarn-project/aztec-rpc/src/contract_data_source/memory_contract_data_source.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress } from '../circuits.js'; +import { AztecAddress, EthAddress } from '@aztec/circuits.js'; import { ContractAbi } from '../noir.js'; import { contractAbiToContractDao, ContractDao } from './contract_dao.js'; import { ContractDataSource } from './contract_data_source.js'; @@ -26,7 +26,7 @@ export class MemoryContractDataSource implements ContractDataSource { } public getContract(address: AztecAddress) { - return Promise.resolve(this.contracts.find(c => c.address.equals(address))); + return Promise.resolve(this.contracts.find(c => c.address.toBuffer().equals(address.toBuffer()))); } public async getCode(contractAddress: AztecAddress, functionSelector: Buffer) { diff --git a/yarn-project/aztec-rpc/src/database/database.ts b/yarn-project/aztec-rpc/src/database/database.ts index 9f3ba7888c1d..f3041a1c9445 100644 --- a/yarn-project/aztec-rpc/src/database/database.ts +++ b/yarn-project/aztec-rpc/src/database/database.ts @@ -5,4 +5,5 @@ import { TxDao } from './tx_dao.js'; export interface Database extends ContractDataSource { getTx(txHash: TxHash): Promise; + addOrUpdateTx(tx: TxDao): Promise; } diff --git a/yarn-project/aztec-rpc/src/database/memory_db.ts b/yarn-project/aztec-rpc/src/database/memory_db.ts index 8663ea0f1060..16b0b104c75e 100644 --- a/yarn-project/aztec-rpc/src/database/memory_db.ts +++ b/yarn-project/aztec-rpc/src/database/memory_db.ts @@ -10,4 +10,14 @@ export class MemoryDB extends MemoryContractDataSource implements Database { public getTx(txHash: TxHash) { return Promise.resolve(this.txs.find(tx => tx.txHash.equals(txHash))); } + + public addOrUpdateTx(tx: TxDao): Promise { + const index = this.txs.findIndex(t => t.txHash.equals(tx.txHash)); + if (index === -1) { + this.txs.push(tx); + } else { + this.txs[index] = tx; + } + return Promise.resolve(); + } } diff --git a/yarn-project/aztec-rpc/src/database/tx_dao.ts b/yarn-project/aztec-rpc/src/database/tx_dao.ts index 0445468428f8..bc5642a6a5d1 100644 --- a/yarn-project/aztec-rpc/src/database/tx_dao.ts +++ b/yarn-project/aztec-rpc/src/database/tx_dao.ts @@ -1,12 +1,11 @@ import { TxHash } from '@aztec/tx'; - -import { AztecAddress } from '../circuits.js'; +import { AztecAddress } from '@aztec/circuits.js'; export class TxDao { constructor( public readonly txHash: TxHash, - public readonly blockHash: Buffer, - public readonly blockNumber: number, + public blockHash: Buffer | undefined, + public blockNumber: number | undefined, public readonly from: AztecAddress, public readonly to: AztecAddress | undefined, public readonly contractAddress: AztecAddress | undefined, diff --git a/yarn-project/aztec-rpc/src/index.ts b/yarn-project/aztec-rpc/src/index.ts index f485eb0fa61d..072b28c28988 100644 --- a/yarn-project/aztec-rpc/src/index.ts +++ b/yarn-project/aztec-rpc/src/index.ts @@ -7,3 +7,5 @@ export { Tx, TxHash } from '@aztec/tx'; // TODO - only export necessary stuffs export * from './circuits.js'; export * from './noir.js'; + +export { Fr, TxRequest, AztecAddress, EthAddress } from '@aztec/circuits.js'; diff --git a/yarn-project/aztec-rpc/src/key_store/key_pair.ts b/yarn-project/aztec-rpc/src/key_store/key_pair.ts index c0c7c9077a3b..a31df0b33b69 100644 --- a/yarn-project/aztec-rpc/src/key_store/key_pair.ts +++ b/yarn-project/aztec-rpc/src/key_store/key_pair.ts @@ -1,4 +1,5 @@ -import { AztecAddress, Signature } from '../circuits.js'; +import { AztecAddress, Fr } from '@aztec/circuits.js'; +import { Signature } from '../circuits.js'; import { randomBytes } from '../foundation.js'; export interface KeyPair { diff --git a/yarn-project/aztec-rpc/src/key_store/key_store.ts b/yarn-project/aztec-rpc/src/key_store/key_store.ts index e9fd0a684311..d3b15f1f8d34 100644 --- a/yarn-project/aztec-rpc/src/key_store/key_store.ts +++ b/yarn-project/aztec-rpc/src/key_store/key_store.ts @@ -1,4 +1,5 @@ -import { AztecAddress, Signature, TxRequest } from '../circuits.js'; +import { AztecAddress, TxRequest } from '@aztec/circuits.js'; +import { Signature } from '../circuits.js'; export interface KeyStore { addAccount(): Promise; diff --git a/yarn-project/aztec-rpc/src/key_store/test_key_store.ts b/yarn-project/aztec-rpc/src/key_store/test_key_store.ts index a95423a7013d..3aa3d8a366fa 100644 --- a/yarn-project/aztec-rpc/src/key_store/test_key_store.ts +++ b/yarn-project/aztec-rpc/src/key_store/test_key_store.ts @@ -1,13 +1,12 @@ -import { TxRequest } from '../circuits.js'; +import { TxRequest } from '@aztec/circuits.js'; +import { ZERO_FR } from '../circuits.js'; import { ConstantKeyPair, KeyPair } from './key_pair.js'; import { KeyStore } from './key_store.js'; export class TestKeyStore implements KeyStore { private accounts: KeyPair[] = []; - constructor() { - this.accounts.push(ConstantKeyPair.random()); - } + constructor() {} public addAccount() { const keyPair = ConstantKeyPair.random(); @@ -24,7 +23,9 @@ export class TestKeyStore implements KeyStore { } signTxRequest(txRequest: TxRequest) { - const account = this.accounts.find(a => a.getPublicKey().equals(txRequest.from)); + const account = txRequest.from.toBuffer().equals(ZERO_FR.toBuffer()) + ? this.accounts[0] + : this.accounts.find(a => a.getPublicKey().toBuffer().equals(txRequest.from.toBuffer())); if (!account) { throw new Error('Unknown account.'); } diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts index b01835946570..48dd11f6e03c 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts @@ -1,10 +1,18 @@ import { TxHash } from '@aztec/tx'; import { AztecNode } from '@aztec/aztec-node'; -import { InterruptableSleep } from '@aztec/foundation'; +import { createDebugLogger, InterruptableSleep } from '@aztec/foundation'; import { AccountState } from '../account_state/index.js'; -import { AztecAddress, EthAddress } from '../circuits.js'; -import { Database } from '../database/index.js'; +import { + AztecAddress, + EthAddress, + KERNEL_NEW_COMMITMENTS_LENGTH, + KERNEL_NEW_CONTRACTS_LENGTH, + KERNEL_NEW_NULLIFIERS_LENGTH, +} from '@aztec/circuits.js'; +import { Database, TxDao } from '../database/index.js'; import { ContractAbi } from '../noir.js'; +import { L2Block } from '@aztec/l2-block'; +import { keccak } from '@aztec/foundation'; export class Synchroniser { private runningPromise?: Promise; @@ -12,9 +20,13 @@ export class Synchroniser { private interruptableSleep = new InterruptableSleep(); private running = false; - constructor(private node: AztecNode, private db: Database) {} + constructor( + private node: AztecNode, + private db: Database, + private log = createDebugLogger('aztec:aztec_rps_synchroniser'), + ) {} - public start(from = 0, take = 1, retryInterval = 10000) { + public start(from = 1, take = 1, retryInterval = 1000) { if (this.running) { return; } @@ -31,11 +43,7 @@ export class Synchroniser { continue; } - const contractAddresses = blocks - .map(b => b.newContractData.map(d => d.aztecAddress)) - .flat() - .map(fr => new AztecAddress(fr.toBuffer())); - await this.db.confirmContractsDeployed(contractAddresses); + await this.decodeBlocks(blocks); from += blocks.length; } catch (err) { @@ -46,12 +54,14 @@ export class Synchroniser { }; this.runningPromise = run(); + this.log('Started'); } public async stop() { this.running = false; this.interruptableSleep.interrupt(); await this.runningPromise; + this.log('Stopped'); } public async addAccount(account: AztecAddress) { @@ -60,7 +70,7 @@ export class Synchroniser { } public getAccount(account: AztecAddress) { - return this.accountStates.find(as => as.publicKey.equals(account)); + return this.accountStates.find(as => as.publicKey.toBuffer().equals(account.toBuffer())); } public getAccounts() { @@ -76,6 +86,9 @@ export class Synchroniser { if (!tx) { return; } + if (!tx.blockHash) { + return; + } const account = this.getAccount(tx.from); if (!account) { @@ -93,4 +106,39 @@ export class Synchroniser { status: !tx.error, }; } + + private async decodeBlocks(l2Blocks: L2Block[]) { + for (const block of l2Blocks) { + let i = 0; + const numTxs = Math.floor(block.newCommitments.length / KERNEL_NEW_COMMITMENTS_LENGTH); + while (i < numTxs) { + const dataToHash = Buffer.concat( + [ + block.newCommitments + .slice( + i * KERNEL_NEW_COMMITMENTS_LENGTH, + i * KERNEL_NEW_COMMITMENTS_LENGTH + KERNEL_NEW_COMMITMENTS_LENGTH, + ) + .map(x => x.toBuffer()), + block.newNullifiers + .slice(i * KERNEL_NEW_NULLIFIERS_LENGTH, i * KERNEL_NEW_NULLIFIERS_LENGTH + KERNEL_NEW_NULLIFIERS_LENGTH) + .map(x => x.toBuffer()), + block.newContracts + .slice(i * KERNEL_NEW_CONTRACTS_LENGTH, i * KERNEL_NEW_CONTRACTS_LENGTH + KERNEL_NEW_CONTRACTS_LENGTH) + .map(x => x.toBuffer()), + ].flat(), + ); + const txDao: TxDao | undefined = await this.db.getTx(new TxHash(keccak(dataToHash))); + if (txDao !== undefined) { + txDao.blockHash = keccak(block.encode()); + txDao.blockNumber = block.number; + await this.db.addOrUpdateTx(txDao); + } + i++; + } + const contractAddresses = block.newContractData.map(d => new AztecAddress(d.aztecAddress.toBuffer())).flat(); + await this.db.confirmContractsDeployed(contractAddresses); + this.log(`Synched block ${block.number}`); + } + } } diff --git a/yarn-project/aztec-rpc/src/tx/tx_receipt.ts b/yarn-project/aztec-rpc/src/tx/tx_receipt.ts index 922112b5798c..9f1ab20dd837 100644 --- a/yarn-project/aztec-rpc/src/tx/tx_receipt.ts +++ b/yarn-project/aztec-rpc/src/tx/tx_receipt.ts @@ -1,11 +1,11 @@ import { TxHash } from '@aztec/tx'; -import { AztecAddress } from '../circuits.js'; +import { AztecAddress } from '@aztec/circuits.js'; export interface TxReceipt { txHash: TxHash; // txIndex: number; - blockHash: Buffer; - blockNumber: number; + blockHash: Buffer | undefined; + blockNumber: number | undefined; from: AztecAddress; to?: AztecAddress; contractAddress?: AztecAddress; diff --git a/yarn-project/aztec.js/package.json b/yarn-project/aztec.js/package.json index c0ac7b65354c..eef2a1985592 100644 --- a/yarn-project/aztec.js/package.json +++ b/yarn-project/aztec.js/package.json @@ -45,4 +45,4 @@ "ts-node": "^10.9.1", "typescript": "^4.9.5" } -} \ No newline at end of file +} diff --git a/yarn-project/aztec.js/src/contract/call_method.ts b/yarn-project/aztec.js/src/contract/call_method.ts index cf2b550a6da9..5d5ca68df910 100644 --- a/yarn-project/aztec.js/src/contract/call_method.ts +++ b/yarn-project/aztec.js/src/contract/call_method.ts @@ -1,4 +1,5 @@ -import { AztecAddress, AztecRPCClient } from '@aztec/aztec-rpc'; +import { AztecRPCClient } from '@aztec/aztec-rpc'; +import { AztecAddress } from '@aztec/circuits.js'; import { ContractFunction } from './contract_function.js'; export interface CallMethodOptions { diff --git a/yarn-project/aztec.js/src/contract/contract.ts b/yarn-project/aztec.js/src/contract/contract.ts index 12df2ae042f5..81d4fb70e297 100644 --- a/yarn-project/aztec.js/src/contract/contract.ts +++ b/yarn-project/aztec.js/src/contract/contract.ts @@ -1,4 +1,5 @@ -import { AztecAddress, AztecRPCClient, ContractAbi } from '@aztec/aztec-rpc'; +import { AztecRPCClient, ContractAbi } from '@aztec/aztec-rpc'; +import { AztecAddress } from '@aztec/circuits.js'; import { CallMethodOptions } from './call_method.js'; import { SendMethodOptions } from './send_method.js'; import { SentTx } from './sent_tx.js'; diff --git a/yarn-project/aztec.js/src/contract/send_method.ts b/yarn-project/aztec.js/src/contract/send_method.ts index c3e094552dee..89c3ece625e7 100644 --- a/yarn-project/aztec.js/src/contract/send_method.ts +++ b/yarn-project/aztec.js/src/contract/send_method.ts @@ -1,4 +1,5 @@ -import { AztecAddress, AztecRPCClient, Fr, Signature, Tx, TxHash, TxRequest } from '@aztec/aztec-rpc'; +import { AztecRPCClient, Signature, Tx, TxHash, TxRequest } from '@aztec/aztec-rpc'; +import { AztecAddress, Fr } from '@aztec/circuits.js'; import { ContractFunction } from './contract_function.js'; import { SentTx } from './sent_tx.js'; diff --git a/yarn-project/aztec.js/src/contract_deployer/constructor_method.ts b/yarn-project/aztec.js/src/contract_deployer/constructor_method.ts index 033c148c67c9..454e3e0329db 100644 --- a/yarn-project/aztec.js/src/contract_deployer/constructor_method.ts +++ b/yarn-project/aztec.js/src/contract_deployer/constructor_method.ts @@ -1,4 +1,6 @@ -import { AztecAddress, AztecRPCClient, ContractAbi, EthAddress, Fr } from '@aztec/aztec-rpc'; +import { AztecRPCClient, ContractAbi } from '@aztec/aztec-rpc'; +import { EthAddress, Fr } from '@aztec/circuits.js'; +import { AztecAddress, randomBytes } from '@aztec/foundation'; import { ContractFunction, SendMethod, SendMethodOptions } from '../contract/index.js'; export interface ConstructorOptions extends SendMethodOptions { @@ -29,8 +31,8 @@ export class ConstructorMethod extends SendMethod { this.txRequest = await this.arc.createDeploymentTxRequest( this.abi, this.entry.encodeParameters(this.args).map(p => new Fr(p)), - portalContract || EthAddress.ZERO, - contractAddressSalt || Fr.random(), + portalContract || new EthAddress(Buffer.alloc(EthAddress.SIZE_IN_BYTES)), + contractAddressSalt || new Fr(randomBytes(Fr.SIZE_IN_BYTES)), from || AztecAddress.ZERO, ); return this.txRequest; diff --git a/yarn-project/aztec.js/src/contract_deployer/contract_deployer.test.ts b/yarn-project/aztec.js/src/contract_deployer/contract_deployer.test.ts index dc67db329c8b..0172372e5603 100644 --- a/yarn-project/aztec.js/src/contract_deployer/contract_deployer.test.ts +++ b/yarn-project/aztec.js/src/contract_deployer/contract_deployer.test.ts @@ -1,18 +1,9 @@ import { mock } from 'jest-mock-extended'; -import { - AztecAddress, - AztecRPCClient, - ContractAbi, - EthAddress, - Fr, - Signature, - Tx, - TxHash, - TxReceipt, - TxRequest, -} from '@aztec/aztec-rpc'; +import { AztecRPCClient, ContractAbi, Signature, Tx, TxHash, TxReceipt, TxRequest } from '@aztec/aztec-rpc'; import { ContractDeployer } from './contract_deployer.js'; +import { AztecAddress, EthAddress, Fr } from '@aztec/circuits.js'; +import { randomBytes } from 'crypto'; describe('Contract Deployer', () => { let arc: ReturnType>; @@ -30,8 +21,8 @@ describe('Contract Deployer', () => { ], }; - const portalContract = EthAddress.random(); - const contractAddressSalt = Fr.random(); + const portalContract = new EthAddress(randomBytes(EthAddress.SIZE_IN_BYTES)); + const contractAddressSalt = new Fr(randomBytes(Fr.SIZE_IN_BYTES)); const account = AztecAddress.random(); const mockTxRequest = { type: 'TxRequest' } as any as TxRequest; @@ -104,12 +95,12 @@ describe('Contract Deployer', () => { expect(arc.createDeploymentTxRequest).toHaveBeenCalledWith( abi, [], - EthAddress.ZERO, // portalContract + new EthAddress(Buffer.alloc(EthAddress.SIZE_IN_BYTES)), // portalContract expect.anything(), // contractAddressSalt - AztecAddress.ZERO, // account + new Fr(0), // account ); const defaultContractAddressSalt = arc.createDeploymentTxRequest.mock.calls[0][3]; expect(defaultContractAddressSalt).not.toEqual(contractAddressSalt); - expect(defaultContractAddressSalt).not.toEqual(Fr.ZERO); + expect(defaultContractAddressSalt).not.toEqual(new Fr(0)); }); }); diff --git a/yarn-project/circuits.js/package.json b/yarn-project/circuits.js/package.json index 307dfb750a53..806b14990498 100644 --- a/yarn-project/circuits.js/package.json +++ b/yarn-project/circuits.js/package.json @@ -55,4 +55,4 @@ "ts-node": "^10.9.1", "typescript": "^4.9.5" } -} \ No newline at end of file +} diff --git a/yarn-project/circuits.js/tsconfig.dest.json b/yarn-project/circuits.js/tsconfig.dest.json index 08a9c1ff256e..2baca8002657 100644 --- a/yarn-project/circuits.js/tsconfig.dest.json +++ b/yarn-project/circuits.js/tsconfig.dest.json @@ -1,4 +1,9 @@ { "extends": "./tsconfig.json", - "exclude": ["**/*.test.*", "**/fixtures/*"] + "exclude": ["**/*.test.*", "**/fixtures/*"], + "references": [ + { + "path": "../foundation/tsconfig.dest.json" + } + ] } diff --git a/yarn-project/circuits.js/tsconfig.json b/yarn-project/circuits.js/tsconfig.json index 41d839cd823e..7feb7e3a6265 100644 --- a/yarn-project/circuits.js/tsconfig.json +++ b/yarn-project/circuits.js/tsconfig.json @@ -18,5 +18,10 @@ "rootDir": "src", "tsBuildInfoFile": ".tsbuildinfo" }, - "include": ["src"] + "include": ["src"], + "references": [ + { + "path": "../foundation/tsconfig.dest.json" + } + ] } diff --git a/yarn-project/end-to-end/jest.integration.config.json b/yarn-project/end-to-end/jest.integration.config.json new file mode 100644 index 000000000000..d9dc9cf2dbb9 --- /dev/null +++ b/yarn-project/end-to-end/jest.integration.config.json @@ -0,0 +1,13 @@ +{ + "preset": "ts-jest/presets/default-esm", + "globals": { + "ts-jest": { + "useESM": true + } + }, + "moduleNameMapper": { + "^(\\.{1,2}/.*)\\.js$": "$1" + }, + "testRegex": "./src/.*\\.test\\.ts$", + "rootDir": "./src" +} diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 48f0261d1995..e6d9863a59df 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -7,7 +7,9 @@ "build": "yarn clean && tsc -b tsconfig.json", "clean": "rm -rf ./dest .tsbuildinfo", "formatting": "run -T prettier --check ./src && run -T eslint --max-warnings 0 ./src", - "test": "./scripts/start_e2e.sh" + "test": "./scripts/start_e2e.sh", + "test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test:integration:run\" \"anvil\"", + "test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --config jest.integration.config.json" }, "jest": { "preset": "ts-jest/presets/default-esm", @@ -25,6 +27,7 @@ "dependencies": { "@aztec/aztec-node": "workspace:^", "@aztec/aztec.js": "workspace:^", + "@aztec/ethereum.js": "workspace:^", "@aztec/noir-contracts": "workspace:^", "@types/jest": "^29.4.0", "jest": "^28.1.3", @@ -36,6 +39,7 @@ "@jest/globals": "^29.4.3", "@rushstack/eslint-patch": "^1.1.4", "@types/node": "^18.7.23", + "concurrently": "^7.6.0", "ts-node": "^10.9.1" } } diff --git a/yarn-project/end-to-end/scripts/docker-compose.yml b/yarn-project/end-to-end/scripts/docker-compose.yml index 025e24c74dfb..4419208947b0 100644 --- a/yarn-project/end-to-end/scripts/docker-compose.yml +++ b/yarn-project/end-to-end/scripts/docker-compose.yml @@ -1,5 +1,14 @@ version: '3' services: + fork: + image: ghcr.io/foundry-rs/foundry:nightly-a44aa13cfc23491ba32aaedc093e9488c1a6db43 + entrypoint: 'anvil -p 8545 --host 0.0.0.0 --chain-id 1337' + ports: + - '8545:8545' + end-to-end: image: aztecprotocol/end-to-end:latest + environment: + DEBUG: 'aztec:*' + ETHEREUM_HOST: http://fork:8545 command: ${TEST:-./src/e2e_deploy_contract.test.ts} diff --git a/yarn-project/end-to-end/scripts/start_e2e.sh b/yarn-project/end-to-end/scripts/start_e2e.sh index ef6959c4e38b..617982ba7e80 100755 --- a/yarn-project/end-to-end/scripts/start_e2e.sh +++ b/yarn-project/end-to-end/scripts/start_e2e.sh @@ -2,4 +2,4 @@ set -eu export NODE_NO_WARNINGS=1 -node ${NODE_ARGS-} --openssl-legacy-provider --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand $1 \ No newline at end of file +node ${NODE_ARGS-} --openssl-legacy-provider --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --passWithNoTests $@ \ No newline at end of file diff --git a/yarn-project/end-to-end/src/create_aztec_node.ts b/yarn-project/end-to-end/src/create_aztec_node.ts index 4444d3a667ae..23fd642c23f6 100644 --- a/yarn-project/end-to-end/src/create_aztec_node.ts +++ b/yarn-project/end-to-end/src/create_aztec_node.ts @@ -1,20 +1,21 @@ -import { AztecNode } from '@aztec/aztec-node'; -import { EthAddress } from '@aztec/aztec.js'; +import { AztecNode, AztecNodeConfig } from '@aztec/aztec-node'; +import { EthAddress } from '@aztec/ethereum.js/eth_address'; -const { - ETHEREUM_HOST = 'http://localhost:8545', - ROLLUP_ADDRESS = '0x5FbDB2315678afecb367f032d93F642f64180aa3', - YEETER_ADDRESS = '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512', -} = process.env; - -export async function createAztecNode() { - return await AztecNode.createAndSync({ - rpcUrl: ETHEREUM_HOST, - rollupContract: EthAddress.fromString(ROLLUP_ADDRESS) as any, - yeeterContract: EthAddress.fromString(YEETER_ADDRESS) as any, - retryIntervalMs: 10000, - publisherPrivateKey: Buffer.alloc(64), +export const createAztecNode = async ( + rollupContract: EthAddress, + yeeterContract: EthAddress, + rpcUrl: string, + publisherPrivateKey: Buffer, +) => { + const config: AztecNodeConfig = { + rollupContract, + yeeterContract, + rpcUrl, + publisherPrivateKey, + retryIntervalMs: 1000, requiredConfirmations: 1, transactionPollingInterval: 1000, - }); -} + archiverPollingInterval: 1000, + }; + return await AztecNode.createAndSync(config); +}; diff --git a/yarn-project/end-to-end/src/create_aztec_rpc_client.ts b/yarn-project/end-to-end/src/create_aztec_rpc_client.ts index 5729472d966e..ce1edbce1e62 100644 --- a/yarn-project/end-to-end/src/create_aztec_rpc_client.ts +++ b/yarn-project/end-to-end/src/create_aztec_rpc_client.ts @@ -1,10 +1,8 @@ import { AztecNode } from '@aztec/aztec-node'; import { createAztecRPCServer } from '@aztec/aztec.js'; -import { createAztecNode } from './create_aztec_node.js'; -export async function createAztecRPCClient(numberOfAccounts = 1, aztecNode?: AztecNode) { - const node = aztecNode || (await createAztecNode()); - const arc = await createAztecRPCServer(node); +export async function createAztecRpcServer(numberOfAccounts = 1, aztecNode: AztecNode) { + const arc = await createAztecRPCServer(aztecNode); for (let i = 0; i < numberOfAccounts; ++i) { await arc.addAccount(); diff --git a/yarn-project/end-to-end/src/deploy_l1_contracts.ts b/yarn-project/end-to-end/src/deploy_l1_contracts.ts new file mode 100644 index 000000000000..8a9c57edca36 --- /dev/null +++ b/yarn-project/end-to-end/src/deploy_l1_contracts.ts @@ -0,0 +1,23 @@ +import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc'; +import { WalletProvider } from '@aztec/ethereum.js/provider'; +import { Rollup, Yeeter } from '@aztec/l1-contracts'; + +export const deployRollupContract = async (provider: WalletProvider, ethRpc: EthereumRpc) => { + const deployAccount = provider.getAccount(0); + const contract = new Rollup(ethRpc, undefined, { from: deployAccount, gas: 1000000 }); + await contract.deploy().send().getReceipt(); + return contract.address; +}; + +export const deployYeeterContract = async (provider: WalletProvider, ethRpc: EthereumRpc) => { + const deployAccount = provider.getAccount(0); + const contract = new Yeeter(ethRpc, undefined, { from: deployAccount, gas: 1000000 }); + await contract.deploy().send().getReceipt(); + return contract.address; +}; + +export const createProvider = (host: string, mnemonic: string, accounts: number) => { + const walletProvider = WalletProvider.fromHost(host); + walletProvider.addAccountsFromMnemonic(mnemonic, accounts); + return walletProvider; +}; diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index bdc57008293a..2bc7732379f5 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -1,24 +1,57 @@ -import { AztecAddress, AztecRPCClient, ContractDeployer, Fr } from '@aztec/aztec.js'; +import { AztecNode } from '@aztec/aztec-node'; +import { AztecAddress, AztecRPCServer, ContractDeployer, Fr } from '@aztec/aztec.js'; +import { EthAddress } from '@aztec/ethereum.js/eth_address'; +import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc'; +import { WalletProvider } from '@aztec/ethereum.js/provider'; +import { createDebugLogger, randomBytes } from '@aztec/foundation'; import { TestContractAbi } from '@aztec/noir-contracts/examples'; -import { createAztecRPCClient } from './create_aztec_rpc_client.js'; +import { createAztecNode } from './create_aztec_node.js'; +import { createAztecRpcServer } from './create_aztec_rpc_client.js'; +import { createProvider, deployRollupContract, deployYeeterContract } from './deploy_l1_contracts.js'; + +const { ETHEREUM_HOST = 'http://localhost:8545' } = process.env; +const MNEMONIC = 'test test test test test test test test test test test junk'; + +const logger = createDebugLogger('aztec:e2e_deploy_contract'); describe('e2e_deploy_contract', () => { - let arc: AztecRPCClient; + let provider: WalletProvider; + let node: AztecNode; + let aztecRpcServer: AztecRPCServer; + let rollupAddress: EthAddress; + let yeeterAddress: EthAddress; let accounts: AztecAddress[]; const abi = TestContractAbi; + beforeAll(async () => { + provider = createProvider(ETHEREUM_HOST, MNEMONIC, 1); + const ethRpc = new EthereumRpc(provider); + logger('Deploying contracts...'); + rollupAddress = await deployRollupContract(provider, ethRpc); + yeeterAddress = await deployYeeterContract(provider, ethRpc); + logger('Deployed contracts...'); + }); + beforeEach(async () => { - arc = await createAztecRPCClient(1); - accounts = await arc.getAccounts(); + node = await createAztecNode(rollupAddress, yeeterAddress, ETHEREUM_HOST, provider.getPrivateKey(0)!); + aztecRpcServer = await createAztecRpcServer(1, node); + accounts = await aztecRpcServer.getAccounts(); + }); + + afterEach(async () => { + await node.stop(); + await aztecRpcServer.stop(); }); /** * Milestone 1.1 * https://hackmd.io/ouVCnacHQRq2o1oRc5ksNA#Interfaces-and-Responsibilities */ - it.skip('should deploy a contract', async () => { - const deployer = new ContractDeployer(abi, arc); - const receipt = await deployer.deploy().send().getReceipt(); + it('should deploy a contract', async () => { + const deployer = new ContractDeployer(abi, aztecRpcServer); + const tx = deployer.deploy().send(); + logger(`Tx sent!`); + const receipt = await tx.getReceipt(); expect(receipt).toEqual( expect.objectContaining({ from: accounts[0], @@ -27,20 +60,21 @@ describe('e2e_deploy_contract', () => { error: '', }), ); + logger(`Receipt received`); const contractAddress = receipt.contractAddress!; const constructor = abi.functions.find(f => f.name === 'constructor')!; - const bytecode = await arc.getCode(contractAddress); + const bytecode = await aztecRpcServer.getCode(contractAddress); expect(bytecode).toEqual(constructor.bytecode); - }); + }, 30_000); /** * Milestone 1.2 * https://hackmd.io/-a5DjEfHTLaMBR49qy6QkA */ it.skip('should not deploy a contract with the same salt twice', async () => { - const contractAddressSalt = Fr.random(); - const deployer = new ContractDeployer(abi, arc, { contractAddressSalt }); + const contractAddressSalt = new Fr(randomBytes(32)); + const deployer = new ContractDeployer(abi, aztecRpcServer, { contractAddressSalt }); { const receipt = await deployer.deploy().send().getReceipt(); diff --git a/yarn-project/end-to-end/src/e2e_zk_token_contract.test.ts b/yarn-project/end-to-end/src/e2e_zk_token_contract.test.ts index bfc7d00773f5..18b38c0afda3 100644 --- a/yarn-project/end-to-end/src/e2e_zk_token_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_zk_token_contract.test.ts @@ -1,38 +1,69 @@ -import { AztecAddress, AztecRPCClient, Contract, ContractDeployer, Fr } from '@aztec/aztec.js'; +import { AztecNode } from '@aztec/aztec-node'; +import { AztecAddress, AztecRPCServer, Contract, ContractDeployer, ZERO_FR } from '@aztec/aztec.js'; +import { EthAddress } from '@aztec/ethereum.js/eth_address'; +import { EthereumRpc } from '@aztec/ethereum.js/eth_rpc'; +import { WalletProvider } from '@aztec/ethereum.js/provider'; +import { createDebugLogger } from '@aztec/foundation'; import { ZkTokenContractAbi } from '@aztec/noir-contracts/examples'; -import { createAztecRPCClient } from './create_aztec_rpc_client.js'; +import { createAztecNode } from './create_aztec_node.js'; +import { createAztecRpcServer } from './create_aztec_rpc_client.js'; +import { createProvider, deployRollupContract, deployYeeterContract } from './deploy_l1_contracts.js'; + +const ETHEREUM_HOST = 'http://localhost:8545'; +const MNEMONIC = 'test test test test test test test test test test test junk'; + +const logger = createDebugLogger('aztec:e2e_zk_token_contract'); describe('e2e_zk_token_contract', () => { - let arc: AztecRPCClient; + let provider: WalletProvider; + let node: AztecNode; + let aztecRpcServer: AztecRPCServer; + let rollupAddress: EthAddress; + let yeeterAddress: EthAddress; let accounts: AztecAddress[]; let contract: Contract; + beforeAll(async () => { + provider = createProvider(ETHEREUM_HOST, MNEMONIC, 1); + const ethRpc = new EthereumRpc(provider); + logger('Deploying contracts...'); + rollupAddress = await deployRollupContract(provider, ethRpc); + yeeterAddress = await deployYeeterContract(provider, ethRpc); + logger('Deployed contracts...'); + }); + + beforeEach(async () => { + node = await createAztecNode(rollupAddress, yeeterAddress, ETHEREUM_HOST, provider.getPrivateKey(0)!); + aztecRpcServer = await createAztecRpcServer(1, node); + accounts = await aztecRpcServer.getAccounts(); + }); + + afterEach(async () => { + await node.stop(); + await aztecRpcServer.stop(); + }); + const expectStorageSlot = async (accountIdx: number, expectedBalance: bigint) => { // We only generate 1 note in each test. Balance is the first field of the only note. // TBD - how to calculate storage slot? - const storageSlot = Fr.ZERO; - const [[balance]] = await arc.getStorageAt(contract.address, storageSlot); - console.log(`Account ${accountIdx} balance: ${balance}`); + const storageSlot = ZERO_FR; + const [[balance]] = await aztecRpcServer.getStorageAt(contract.address, storageSlot); + logger(`Account ${accountIdx} balance: ${balance}`); expect(balance).toBe(expectedBalance); }; const expectBalance = async (accountIdx: number, expectedBalance: bigint) => { const balance = await contract.methods.getBalance().call({ from: accounts[accountIdx] }); - console.log(`Account ${accountIdx} balance: ${balance}`); + logger(`Account ${accountIdx} balance: ${balance}`); expect(balance).toBe(expectedBalance); }; const deployContract = async (initialBalance = 0n) => { - const deployer = new ContractDeployer(ZkTokenContractAbi, arc); + const deployer = new ContractDeployer(ZkTokenContractAbi, aztecRpcServer); const receipt = await deployer.deploy(initialBalance).send().getReceipt(); - return new Contract(receipt.contractAddress!, ZkTokenContractAbi, arc); + return new Contract(receipt.contractAddress!, ZkTokenContractAbi, aztecRpcServer); }; - beforeEach(async () => { - arc = await createAztecRPCClient(2); - accounts = await arc.getAccounts(); - }); - /** * Milestone 1.3 * https://hackmd.io/AG5rb9DyTRu3y7mBptWauA diff --git a/yarn-project/kernel-prover/package.json b/yarn-project/kernel-prover/package.json index d5a11bba87e9..0af5858f8c08 100644 --- a/yarn-project/kernel-prover/package.json +++ b/yarn-project/kernel-prover/package.json @@ -31,6 +31,7 @@ "dependencies": { "@aztec/acir-simulator": "workspace:^", "@aztec/circuits.js": "workspace:^", + "@aztec/foundation": "workspace:^", "tslib": "^2.4.0" }, "devDependencies": { diff --git a/yarn-project/kernel-prover/src/circuits.ts b/yarn-project/kernel-prover/src/circuits.ts deleted file mode 100644 index 5bbd42b113f3..000000000000 --- a/yarn-project/kernel-prover/src/circuits.ts +++ /dev/null @@ -1,26 +0,0 @@ -// See aztec3/constants.hpp -// Copied here for prototyping purposes - -import { AztecAddress, Fr, FunctionData, TxContext } from '@aztec/circuits.js'; - -export class TxRequest { - constructor( - public readonly from: AztecAddress, - public readonly to: AztecAddress, - public readonly functionData: FunctionData, - public readonly args: Fr[], - public readonly txContext: TxContext, - public readonly nonce: Fr, - public readonly chainId: Fr, - ) {} - - toBuffer() { - return Buffer.alloc(0); - } -} - -export class Signature { - public static SIZE = 64; - - constructor(public readonly buffer: Buffer) {} -} diff --git a/yarn-project/kernel-prover/src/index.ts b/yarn-project/kernel-prover/src/index.ts index 79318c291e61..996bb87393f7 100644 --- a/yarn-project/kernel-prover/src/index.ts +++ b/yarn-project/kernel-prover/src/index.ts @@ -1,22 +1,46 @@ import { ExecutionResult } from '@aztec/acir-simulator'; import { AccumulatedData, + AffineElement, AggregationObject, + AztecAddress, ConstantData, + EMITTED_EVENTS_LENGTH, + EthAddress, + Fq, Fr, + FunctionData, + KERNEL_L1_MSG_STACK_LENGTH, + KERNEL_NEW_COMMITMENTS_LENGTH, + KERNEL_NEW_CONTRACTS_LENGTH, + KERNEL_NEW_NULLIFIERS_LENGTH, + KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, + KERNEL_PRIVATE_CALL_STACK_LENGTH, + KERNEL_PUBLIC_CALL_STACK_LENGTH, NewContractData, OldTreeRoots, + OptionallyRevealedData, PrivateKernelPublicInputs, + TxRequest, } from '@aztec/circuits.js'; -import { Signature, TxRequest } from './circuits.js'; +import { randomBytes } from 'crypto'; + export class KernelProver { prove( txRequest: TxRequest, - txSignature: Signature, + txSignature: unknown, executionResult: ExecutionResult, oldRoots: OldTreeRoots, ): Promise<{ publicInputs: PrivateKernelPublicInputs; proof: Buffer }> { // TODO: implement this + const createRandomFields = (num: number) => { + return Array(num) + .fill(0) + .map(() => new Fr(randomBytes(32))); + }; + const createRandomContractData = () => { + return new NewContractData(AztecAddress.random(), new EthAddress(randomBytes(20)), createRandomFields(1)[0]); + }; const newContracts = []; if (txRequest.functionData.isConstructor) { newContracts.push( @@ -27,16 +51,45 @@ export class KernelProver { ), ); } + newContracts.push( + ...Array(KERNEL_NEW_CONTRACTS_LENGTH - newContracts.length) + .fill(0) + .map(() => createRandomContractData()), + ); + + const aggregationObject = new AggregationObject( + new AffineElement(new Fq(0), new Fq(0)), + new AffineElement(new Fq(0), new Fq(0)), + [], + [], + false, + ); + const createOptionallyRevealedData = () => { + const optionallyRevealedData = new OptionallyRevealedData( + createRandomFields(1)[0], + new FunctionData(1, true, true), + createRandomFields(EMITTED_EVENTS_LENGTH), + createRandomFields(1)[0], + new EthAddress(randomBytes(20)), + true, + true, + true, + true, + ); + return optionallyRevealedData; + }; const accumulatedTxData = new AccumulatedData( - AggregationObject.fromBuffer(Buffer.alloc(0)), // TODO - Fix this. - new Fr(Buffer.from([1])), - [], // newCommitments - [], // newNullifiers - [], // privateCallStack - [], // publicCallStack - [], // l1MsgStack + aggregationObject, + new Fr(0), + createRandomFields(KERNEL_NEW_COMMITMENTS_LENGTH), + createRandomFields(KERNEL_NEW_NULLIFIERS_LENGTH), + createRandomFields(KERNEL_PRIVATE_CALL_STACK_LENGTH), + createRandomFields(KERNEL_PUBLIC_CALL_STACK_LENGTH), + createRandomFields(KERNEL_L1_MSG_STACK_LENGTH), newContracts, - [], // optionallyRevealedData + Array(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH) + .fill(0) + .map(() => createOptionallyRevealedData()), ); const publicInputs = new PrivateKernelPublicInputs( diff --git a/yarn-project/sequencer-client/src/sequencer/block_builder.ts b/yarn-project/sequencer-client/src/sequencer/block_builder.ts index f3dfd6d6cc71..d61b9e72873a 100644 --- a/yarn-project/sequencer-client/src/sequencer/block_builder.ts +++ b/yarn-project/sequencer-client/src/sequencer/block_builder.ts @@ -9,6 +9,7 @@ import { } from '@aztec/circuits.js'; import { MerkleTreeId, MerkleTreeOperations } from '@aztec/world-state'; import { Tx } from '@aztec/tx'; +import { createDebugLogger } from '@aztec/foundation'; const mapContractData = (n: NewContractData) => { const contractData = new ContractData(new Fr(n.contractAddress.toBuffer()), n.portalContractAddress); @@ -20,7 +21,12 @@ export class BlockBuilder { private nullifierTreeLeaves: Buffer[] = []; private contractTreeLeaves: Buffer[] = []; - constructor(private db: MerkleTreeOperations, private nextRollupId: number, private tx: Tx) { + constructor( + private db: MerkleTreeOperations, + private nextRollupId: number, + private tx: Tx, + private log = createDebugLogger('aztec:block_builder'), + ) { this.dataTreeLeaves = tx.data.end.newCommitments.map((x: Fr) => x.toBuffer()); this.nullifierTreeLeaves = tx.data.end.newNullifiers.map((x: Fr) => x.toBuffer()); this.contractTreeLeaves = tx.data.end.newContracts.map((x: NewContractData) => x.functionTreeRoot.toBuffer()); @@ -46,6 +52,7 @@ export class BlockBuilder { const endTreeOfHistoricContractTreeRootsSnapshot = await this.getTreeSnapshot( MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, ); + this.log(`contract address ${this.tx.data.end.newContracts[0].contractAddress.toString()}`); const l2block = L2Block.fromFields({ number: this.nextRollupId, diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index f7540c104464..3aa404738d3c 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -19,6 +19,7 @@ __metadata: version: 0.0.0-use.local resolution: "@aztec/acir-simulator@workspace:acir-simulator" dependencies: + "@aztec/circuits.js": "workspace:^" "@jest/globals": ^29.4.3 "@noir-lang/noir-source-resolver": ^1.1.0 "@noir-lang/noir_wasm": 0.3.2-29b1f7df @@ -222,11 +223,13 @@ __metadata: dependencies: "@aztec/aztec-node": "workspace:^" "@aztec/aztec.js": "workspace:^" + "@aztec/ethereum.js": "workspace:^" "@aztec/noir-contracts": "workspace:^" "@jest/globals": ^29.4.3 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.4.0 "@types/node": ^18.7.23 + concurrently: ^7.6.0 jest: ^28.1.3 ts-jest: ^28.0.7 ts-node: ^10.9.1 @@ -333,6 +336,7 @@ __metadata: dependencies: "@aztec/acir-simulator": "workspace:^" "@aztec/circuits.js": "workspace:^" + "@aztec/foundation": "workspace:^" "@jest/globals": ^29.4.3 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.4.0