Skip to content

Commit

Permalink
refactor: temp add new contract in current tx only
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Sep 28, 2023
1 parent e38d31b commit f89dbec
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 39 deletions.
2 changes: 1 addition & 1 deletion yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ export class AztecNodeService implements AztecNode {
this.contractDataSource,
this.l1ToL2MessageSource,
);
const processor = await publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables, tx.newContracts);
const processor = await publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
const [, failedTxs] = await processor.process([tx]);
if (failedTxs.length) {
throw failedTxs[0].error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ import times from 'lodash.times';

import { PublicProver } from '../prover/index.js';
import { PublicKernelCircuitSimulator } from '../simulator/index.js';
import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js';
import { WasmPublicKernelCircuitSimulator } from '../simulator/public_kernel.js';
import { PublicProcessor } from './public_processor.js';

describe('public_processor', () => {
let db: MockProxy<MerkleTreeOperations>;
let publicExecutor: MockProxy<PublicExecutor>;
let publicProver: MockProxy<PublicProver>;
let publicContractsDB: MockProxy<ContractsDataSourcePublicDB>;

let proof: Proof;
let root: Buffer;
Expand All @@ -52,6 +54,7 @@ describe('public_processor', () => {
db = mock<MerkleTreeOperations>();
publicExecutor = mock<PublicExecutor>();
publicProver = mock<PublicProver>();
publicContractsDB = mock<ContractsDataSourcePublicDB>();

proof = makeEmptyProof();
root = Buffer.alloc(32, 5);
Expand All @@ -73,6 +76,7 @@ describe('public_processor', () => {
publicProver,
GlobalVariables.empty(),
HistoricBlockData.empty(),
publicContractsDB,
);
});

Expand Down Expand Up @@ -128,6 +132,7 @@ describe('public_processor', () => {
publicProver,
GlobalVariables.empty(),
HistoricBlockData.empty(),
publicContractsDB,
);
});

Expand Down
26 changes: 9 additions & 17 deletions yarn-project/sequencer-client/src/sequencer/public_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,14 @@ import { computeCallStackItemHash, computeVarArgsHash } from '@aztec/circuits.js
import { arrayNonEmptyLength, isArrayEmpty, padArrayEnd, padArrayStart } from '@aztec/foundation/collection';
import { createDebugLogger } from '@aztec/foundation/log';
import { Tuple, mapTuple, to2Fields } from '@aztec/foundation/serialize';
import {
ContractDataSource,
ExtendedContractData,
FunctionL2Logs,
L1ToL2MessageSource,
MerkleTreeId,
Tx,
} from '@aztec/types';
import { ContractDataSource, FunctionL2Logs, L1ToL2MessageSource, MerkleTreeId, Tx } from '@aztec/types';
import { MerkleTreeOperations } from '@aztec/world-state';

import { getVerificationKeys } from '../index.js';
import { EmptyPublicProver } from '../prover/empty.js';
import { PublicProver } from '../prover/index.js';
import { PublicKernelCircuitSimulator } from '../simulator/index.js';
import { getPublicExecutor } from '../simulator/public_executor.js';
import { ContractsDataSourcePublicDB, getPublicExecutor } from '../simulator/public_executor.js';
import { WasmPublicKernelCircuitSimulator } from '../simulator/public_kernel.js';
import { FailedTx, ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js';
import { getHistoricBlockData } from './utils.js';
Expand All @@ -80,22 +73,17 @@ export class PublicProcessorFactory {
public async create(
prevGlobalVariables: GlobalVariables,
globalVariables: GlobalVariables,
newContracts: ExtendedContractData[] = [],
): Promise<PublicProcessor> {
const blockData = await getHistoricBlockData(this.merkleTree, prevGlobalVariables);
const publicContractsDB = new ContractsDataSourcePublicDB(this.contractDataSource);
return new PublicProcessor(
this.merkleTree,
getPublicExecutor(
this.merkleTree,
this.contractDataSource,
this.l1Tol2MessagesDataSource,
blockData,
newContracts,
),
getPublicExecutor(this.merkleTree, publicContractsDB, this.l1Tol2MessagesDataSource, blockData),
new WasmPublicKernelCircuitSimulator(),
new EmptyPublicProver(),
globalVariables,
blockData,
publicContractsDB,
);
}
}
Expand All @@ -112,6 +100,7 @@ export class PublicProcessor {
protected publicProver: PublicProver,
protected globalVariables: GlobalVariables,
protected blockData: HistoricBlockData,
protected publicContractsDB: ContractsDataSourcePublicDB,

private log = createDebugLogger('aztec:sequencer:public-processor'),
) {}
Expand All @@ -130,13 +119,16 @@ export class PublicProcessor {
for (const tx of txs) {
this.log(`Processing tx ${await tx.getTxHash()}`);
try {
await this.publicContractsDB.addNewContracts(tx);
result.push(await this.processTx(tx));
} catch (err) {
this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`);
failed.push({
tx,
error: err instanceof Error ? err : new Error('Unknown error'),
});
} finally {
await this.publicContractsDB.clearTxContracts();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('sequencer', () => {
});

publicProcessorFactory = mock<PublicProcessorFactory>({
create: (_a, _b_, _c) => Promise.resolve(publicProcessor),
create: (_a, _b_) => Promise.resolve(publicProcessor),
});

l2BlockSource = mock<L2BlockSource>({
Expand Down
6 changes: 1 addition & 5 deletions yarn-project/sequencer-client/src/sequencer/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,7 @@ export class Sequencer {

// Process txs and drop the ones that fail processing
// We create a fresh processor each time to reset any cached state (eg storage writes)
const processor = await this.publicProcessorFactory.create(
prevGlobalVariables,
newGlobalVariables,
validTxs.flatMap(tx => tx.newContracts),
);
const processor = await this.publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
const [processedTxs, failedTxs] = await processor.process(validTxs);
if (failedTxs.length > 0) {
const failedTxData = failedTxs.map(fail => fail.tx);
Expand Down
51 changes: 36 additions & 15 deletions yarn-project/sequencer-client/src/simulator/public_executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
PublicStateDB,
} from '@aztec/acir-simulator';
import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js';
import { ContractDataSource, ExtendedContractData, L1ToL2MessageSource, MerkleTreeId } from '@aztec/types';
import { ContractDataSource, ExtendedContractData, L1ToL2MessageSource, MerkleTreeId, Tx } from '@aztec/types';
import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/world-state';

/**
Expand All @@ -17,14 +17,13 @@ import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/wor
*/
export function getPublicExecutor(
merkleTree: MerkleTreeOperations,
contractDataSource: ContractDataSource,
publicContractsDB: PublicContractsDB,
l1toL2MessageSource: L1ToL2MessageSource,
blockData: HistoricBlockData,
newContracts: ExtendedContractData[] = [],
) {
return new PublicExecutor(
new WorldStatePublicDB(merkleTree),
new ContractsDataSourcePublicDB(contractDataSource, newContracts),
publicContractsDB,
new WorldStateDB(merkleTree, l1toL2MessageSource),
blockData,
);
Expand All @@ -33,24 +32,46 @@ export function getPublicExecutor(
/**
* Implements the PublicContractsDB using a ContractDataSource and a set of new contracts.
*/
class ContractsDataSourcePublicDB implements PublicContractsDB {
constructor(private db: ContractDataSource, private newContracts: ExtendedContractData[] = []) {}
export class ContractsDataSourcePublicDB implements PublicContractsDB {
cache = new Map<string, ExtendedContractData>();

constructor(private db: ContractDataSource) {}

/**
* Add new contracts from a transaction
* @param tx - The transaction to add contracts from.
*/
public addNewContracts(tx: Tx): Promise<void> {
for (const contract of tx.newContracts) {
this.cache.set(contract.contractData.contractAddress.toString(), contract);
}

return Promise.resolve();
}

/**
* Removes new contracts added from transactions
*/
public clearTxContracts(): Promise<void> {
this.cache.clear();
return Promise.resolve();
}

async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
const contractData = await this.#getContractData(address);
return contractData?.getPublicFunction(selector)?.bytecode;
const contract = await this.#getContract(address);
return contract?.getPublicFunction(selector)?.bytecode;
}
async getIsInternal(address: AztecAddress, selector: FunctionSelector): Promise<boolean | undefined> {
const contractData = await this.#getContractData(address);
return contractData?.getPublicFunction(selector)?.isInternal;
const contract = await this.#getContract(address);
return contract?.getPublicFunction(selector)?.isInternal;
}
async getPortalContractAddress(address: AztecAddress): Promise<EthAddress | undefined> {
const contractData = await this.#getContractData(address);
return contractData?.contractData.portalContractAddress;
const contract = await this.#getContract(address);
return contract?.contractData.portalContractAddress;
}

#getContractData(contractAddress: AztecAddress): Promise<ExtendedContractData | undefined> {
const contract = this.newContracts.find(c => c.contractData.contractAddress.equals(contractAddress));
return Promise.resolve(contract ?? this.db.getExtendedContractData(contractAddress));
async #getContract(address: AztecAddress): Promise<ExtendedContractData | undefined> {
return this.cache.get(address.toString()) ?? (await this.db.getExtendedContractData(address));
}
}

Expand Down

0 comments on commit f89dbec

Please sign in to comment.