Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions yarn-project/simulator/src/avm/avm_simulator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
import { keccak256, keccakf1600, pedersenCommit, pedersenHash, poseidon2Hash, sha256 } from '@aztec/foundation/crypto';
import { Fq, Fr, Point } from '@aztec/foundation/fields';
import { type Fieldable } from '@aztec/foundation/serialize';
import { openTmpStore } from '@aztec/kv-store/lmdb';
import { getTelemetryClient } from '@aztec/telemetry-client';
import { MerkleTrees } from '@aztec/world-state';
import { NativeWorldStateService } from '@aztec/world-state';

import { randomInt } from 'crypto';
import { mock } from 'jest-mock-extended';
Expand Down Expand Up @@ -1129,9 +1127,7 @@ describe('AVM simulator: transpiled Noir contracts', () => {
trace = mock<PublicSideEffectTraceInterface>();

worldStateDB = mock<WorldStateDB>();
const tmp = openTmpStore();
const telemetryClient = getTelemetryClient();
merkleTrees = await (await MerkleTrees.new(tmp, telemetryClient)).fork();
merkleTrees = await (await NativeWorldStateService.tmp()).fork();
(worldStateDB as jest.Mocked<WorldStateDB>).getMerkleInterface.mockReturnValue(merkleTrees);
ephemeralForest = await AvmEphemeralForest.create(worldStateDB.getMerkleInterface());

Expand Down
12 changes: 5 additions & 7 deletions yarn-project/simulator/src/avm/avm_tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import {
import { poseidon2Hash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { type IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
import { openTmpStore } from '@aztec/kv-store/lmdb';
import { getTelemetryClient } from '@aztec/telemetry-client';
import { MerkleTrees, NativeWorldStateService } from '@aztec/world-state';
import { NativeWorldStateService } from '@aztec/world-state';

import {
AvmEphemeralForest,
Expand Down Expand Up @@ -527,8 +525,7 @@ describe('Checking forking and merging', () => {
*/
describe('AVM Ephemeral Tree Sanity Test', () => {
it('Should calculate the frontier correctly', async () => {
const store = openTmpStore(true);
const worldStateTrees = await MerkleTrees.new(store, getTelemetryClient());
const worldStateTrees = await NativeWorldStateService.tmp();
const leaves = [];
const numLeaves = 6;
for (let i = 0; i < numLeaves; i++) {
Expand All @@ -553,8 +550,9 @@ describe('AVM Ephemeral Tree Sanity Test', () => {
const expectedFrontier = [expectedFrontier0, exepctedFrontier1, expectedFrontier2];
expect(tree.frontier).toEqual(expectedFrontier);
// Check root
await worldStateTrees.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, leaves);
const treeInfo = await worldStateTrees.getTreeInfo(MerkleTreeId.NOTE_HASH_TREE, true);
const fork = await worldStateTrees.fork();
await fork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, leaves);
const treeInfo = await fork.getTreeInfo(MerkleTreeId.NOTE_HASH_TREE);
const localRoot = tree.getRoot();
expect(localRoot.toBuffer()).toEqual(treeInfo.root);
});
Expand Down
7 changes: 3 additions & 4 deletions yarn-project/simulator/src/public/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec
import { type ContractArtifact, type FunctionArtifact } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr, Point } from '@aztec/foundation/fields';
import { openTmpStore } from '@aztec/kv-store/lmdb';
import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest';
import { MerkleTrees } from '@aztec/world-state';
import { NativeWorldStateService } from '@aztec/world-state';

import { strict as assert } from 'assert';

Expand All @@ -58,7 +57,7 @@ export async function simulateAvmTestContractGenerateCircuitInputs(
const globals = GlobalVariables.empty();
globals.timestamp = TIMESTAMP;

const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork();
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
if (!contractDataSource) {
contractDataSource = await MockedAvmTestContractDataSource.create();
}
Expand Down Expand Up @@ -128,7 +127,7 @@ export async function simulateAvmTestContractCall(
contractDataSource = await MockedAvmTestContractDataSource.create();
}

const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork();
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
await contractDataSource.deployContracts(merkleTrees);
const worldStateDB = new WorldStateDB(merkleTrees, contractDataSource);

Expand Down
5 changes: 2 additions & 3 deletions yarn-project/simulator/src/public/public_tx_simulator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { type AztecKVStore } from '@aztec/kv-store';
import { openTmpStore } from '@aztec/kv-store/lmdb';
import { type AppendOnlyTree, Poseidon, StandardTree, newTree } from '@aztec/merkle-tree';
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
import { MerkleTrees } from '@aztec/world-state';
import { NativeWorldStateService } from '@aztec/world-state';

import { jest } from '@jest/globals';
import { mock } from 'jest-mock-extended';
Expand Down Expand Up @@ -240,8 +240,7 @@ describe('public_tx_simulator', () => {
};

beforeEach(async () => {
const tmp = openTmpStore();
db = await (await MerkleTrees.new(tmp)).fork();
db = await (await NativeWorldStateService.tmp()).fork();
worldStateDB = new WorldStateDB(db, mock<ContractDataSource>());

treeStore = openTmpStore();
Expand Down
11 changes: 5 additions & 6 deletions yarn-project/txe/src/node/txe_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
type L2Tips,
type LogFilter,
type MerkleTreeId,
MerkleTreeWriteOperations,
type NullifierMembershipWitness,
type ProverConfig,
type PublicDataWitness,
Expand Down Expand Up @@ -44,7 +45,7 @@ import {
import { type L1ContractAddresses } from '@aztec/ethereum';
import { poseidon2Hash } from '@aztec/foundation/crypto';
import { Fr } from '@aztec/foundation/fields';
import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state';
import { MerkleTreeAdminDatabase } from '@aztec/world-state';

export class TXENode implements AztecNode {
#logsByTags = new Map<string, TxScopedL2Log[]>();
Expand All @@ -59,7 +60,8 @@ export class TXENode implements AztecNode {
private blockNumber: number,
private version: number,
private chainId: number,
private trees: MerkleTrees,
private trees: MerkleTreeAdminDatabase,
private currentFork: MerkleTreeWriteOperations,
) {}

/**
Expand Down Expand Up @@ -277,10 +279,7 @@ export class TXENode implements AztecNode {
blockNumber = await this.getBlockNumber();
}

const db =
blockNumber === (await this.getBlockNumber())
? await this.trees.getLatest()
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
const db = blockNumber === (await this.getBlockNumber()) ? this.currentFork : this.trees.getSnapshot(blockNumber);

return await db.findLeafIndices(
treeId,
Expand Down
72 changes: 35 additions & 37 deletions yarn-project/txe/src/oracle/txe_oracle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AuthWitness,
MerkleTreeId,
MerkleTreeWriteOperations,
Note,
type NoteStatus,
NullifierMembershipWitness,
Expand Down Expand Up @@ -85,7 +86,7 @@ import {
createSimulationError,
resolveAssertionMessageFromError,
} from '@aztec/simulator/server';
import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state';
import { MerkleTreeAdminDatabase } from '@aztec/world-state';

import { TXENode } from '../node/txe_node.js';
import { type TXEDatabase } from '../util/txe_database.js';
Expand Down Expand Up @@ -124,7 +125,8 @@ export class TXE implements TypedOracle {

private constructor(
private logger: Logger,
private trees: MerkleTrees,
private trees: MerkleTreeAdminDatabase,
private currentFork: MerkleTreeWriteOperations,
private executionCache: HashedValuesCache,
private keyStore: KeyStore,
private txeDatabase: TXEDatabase,
Expand All @@ -133,7 +135,7 @@ export class TXE implements TypedOracle {
this.noteCache = new ExecutionNoteCache(this.getTxRequestHash());
this.contractDataOracle = new ContractDataOracle(txeDatabase);

this.node = new TXENode(this.blockNumber, this.VERSION, this.CHAIN_ID, this.trees);
this.node = new TXENode(this.blockNumber, this.VERSION, this.CHAIN_ID, this.trees, this.currentFork);

// Default msg_sender (for entrypoints) is now Fr.max_value rather than 0 addr (see #7190 & #7404)
this.msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE);
Expand All @@ -150,21 +152,19 @@ export class TXE implements TypedOracle {

static async create(
logger: Logger,
trees: MerkleTrees,
trees: MerkleTreeAdminDatabase,
executionCache: HashedValuesCache,
keyStore: KeyStore,
txeDatabase: TXEDatabase,
) {
return new TXE(logger, trees, executionCache, keyStore, txeDatabase, await AztecAddress.random());
const fork = await trees.fork();
return new TXE(logger, trees, fork, executionCache, keyStore, txeDatabase, await AztecAddress.random());
}

// Utils

async #getTreesAt(blockNumber: number) {
const db =
blockNumber === (await this.getBlockNumber())
? await this.trees.getLatest()
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
const db = blockNumber === (await this.getBlockNumber()) ? this.currentFork : this.trees.getSnapshot(blockNumber);
return db;
}

Expand Down Expand Up @@ -213,6 +213,10 @@ export class TXE implements TypedOracle {
return this.trees;
}

getCurrentFork() {
return this.currentFork;
}

getContractDataOracle() {
return this.contractDataOracle;
}
Expand Down Expand Up @@ -270,17 +274,15 @@ export class TXE implements TypedOracle {
}

async addPublicDataWrites(writes: PublicDataWrite[]) {
const db = await this.trees.getLatest();
await db.batchInsert(
await this.currentFork.batchInsert(
MerkleTreeId.PUBLIC_DATA_TREE,
writes.map(w => new PublicDataTreeLeaf(w.leafSlot, w.value).toBuffer()),
0,
);
}

async addSiloedNullifiers(siloedNullifiers: Fr[]) {
const db = await this.trees.getLatest();
await db.batchInsert(
await this.currentFork.batchInsert(
MerkleTreeId.NULLIFIER_TREE,
siloedNullifiers.map(n => n.toBuffer()),
NULLIFIER_SUBTREE_HEIGHT,
Expand All @@ -289,8 +291,7 @@ export class TXE implements TypedOracle {

async checkNullifiersNotInTree(contractAddress: AztecAddress, nullifiers: Fr[]) {
const siloedNullifiers = nullifiers.map(nullifier => siloNullifier(contractAddress, nullifier));
const db = await this.trees.getLatest();
const nullifierIndexesInTree = await db.findLeafIndices(
const nullifierIndexesInTree = await this.currentFork.findLeafIndices(
MerkleTreeId.NULLIFIER_TREE,
siloedNullifiers.map(n => n.toBuffer()),
);
Expand All @@ -311,8 +312,7 @@ export class TXE implements TypedOracle {
}

async addUniqueNoteHashes(siloedNoteHashes: Fr[]) {
const db = await this.trees.getLatest();
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, siloedNoteHashes);
await this.currentFork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, siloedNoteHashes);
}

async addUniqueNoteHashesFromPublic(siloedNoteHashes: Fr[]) {
Expand Down Expand Up @@ -570,8 +570,7 @@ export class TXE implements TypedOracle {

async checkNullifierExists(innerNullifier: Fr): Promise<boolean> {
const nullifier = siloNullifier(this.contractAddress, innerNullifier!);
const db = await this.trees.getLatest();
const index = (await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]))[0];
const index = (await this.currentFork.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]))[0];
return index !== undefined;
}

Expand Down Expand Up @@ -612,14 +611,12 @@ export class TXE implements TypedOracle {
}

async storageWrite(startStorageSlot: Fr, values: Fr[]): Promise<Fr[]> {
const db = await this.trees.getLatest();

const publicDataWrites = values.map((value, i) => {
const storageSlot = startStorageSlot.add(new Fr(i));
this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
return new PublicDataTreeLeaf(computePublicDataTreeLeafSlot(this.contractAddress, storageSlot), value);
});
await db.batchInsert(
await this.currentFork.batchInsert(
MerkleTreeId.PUBLIC_DATA_TREE,
publicDataWrites.map(write => write.toBuffer()),
0,
Expand Down Expand Up @@ -801,8 +798,7 @@ export class TXE implements TypedOracle {
private async executePublicFunction(args: Fr[], callContext: CallContext, isTeardown: boolean = false) {
const executionRequest = new PublicExecutionRequest(callContext, args);

const db = await this.trees.getLatest();
const worldStateDb = new TXEWorldStateDB(db, new TXEPublicContractDataSource(this));
const worldStateDb = new TXEWorldStateDB(this.currentFork, new TXEPublicContractDataSource(this));

const globalVariables = GlobalVariables.empty();
globalVariables.chainId = new Fr(await this.node.getChainId());
Expand All @@ -818,13 +814,13 @@ export class TXE implements TypedOracle {
callContext.contractAddress.toField(),
);
if ((await worldStateDb.getNullifierIndex(contractAddressNullifier)) === undefined) {
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, [contractAddressNullifier.toBuffer()], 0);
await this.currentFork.batchInsert(MerkleTreeId.NULLIFIER_TREE, [contractAddressNullifier.toBuffer()], 0);
}
}

const simulator = new PublicTxSimulator(
db,
new TXEWorldStateDB(db, new TXEPublicContractDataSource(this)),
this.currentFork,
new TXEWorldStateDB(this.currentFork, new TXEPublicContractDataSource(this)),
globalVariables,
);

Expand Down Expand Up @@ -1028,36 +1024,38 @@ export class TXE implements TypedOracle {

async avmOpcodeNullifierExists(innerNullifier: Fr, targetAddress: AztecAddress): Promise<boolean> {
const nullifier = siloNullifier(targetAddress, innerNullifier!);
const db = await this.trees.getLatest();
const index = (await db.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]))[0];
const index = (await this.currentFork.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]))[0];
return index !== undefined;
}

async avmOpcodeEmitNullifier(nullifier: Fr) {
const db = await this.trees.getLatest();
const siloedNullifier = siloNullifier(this.contractAddress, nullifier);
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()], NULLIFIER_SUBTREE_HEIGHT);
await this.currentFork.batchInsert(
MerkleTreeId.NULLIFIER_TREE,
[siloedNullifier.toBuffer()],
NULLIFIER_SUBTREE_HEIGHT,
);
return Promise.resolve();
}

async avmOpcodeEmitNoteHash(noteHash: Fr) {
const db = await this.trees.getLatest();
const siloedNoteHash = siloNoteHash(this.contractAddress, noteHash);
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
await this.currentFork.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
return Promise.resolve();
}

async avmOpcodeStorageRead(slot: Fr) {
const db = await this.trees.getLatest();

const leafSlot = computePublicDataTreeLeafSlot(this.contractAddress, slot);

const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
const lowLeafResult = await this.currentFork.getPreviousValueIndex(
MerkleTreeId.PUBLIC_DATA_TREE,
leafSlot.toBigInt(),
);
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
return Fr.ZERO;
}

const preimage = (await db.getLeafPreimage(
const preimage = (await this.currentFork.getLeafPreimage(
MerkleTreeId.PUBLIC_DATA_TREE,
lowLeafResult.index,
)) as PublicDataTreeLeafPreimage;
Expand Down
Loading