diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 29ecf74d8e1..5cbfcfab8d1 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -88,7 +88,7 @@ export class AztecNodeService implements AztecNode { const p2pClient = await createP2PClient(config, new InMemoryTxPool(), archiver); // now create the merkle trees and the world state syncher - const merkleTreeDB = await MerkleTrees.new(levelup(createMemDown()), await CircuitsWasm.get()); + const merkleTreeDB = await AztecNodeService.createMerkleTreeDB(); const worldStateConfig: WorldStateConfig = getWorldStateConfig(); const worldStateSynchroniser = new ServerWorldStateSynchroniser(merkleTreeDB, archiver, worldStateConfig); @@ -119,6 +119,10 @@ export class AztecNodeService implements AztecNode { ); } + static async createMerkleTreeDB() { + return MerkleTrees.new(levelup(createMemDown()), await CircuitsWasm.get()); + } + /** * Method to determine if the node is ready to accept transactions. * @returns - Flag indicating the readiness for tx submission. @@ -382,16 +386,17 @@ export class AztecNodeService implements AztecNode { **/ public async simulatePublicPart(tx: Tx) { this.log.info(`Simulating tx ${await tx.getTxHash()}`); + // Instantiate merkle tree db so uncommited updates by this simulation are local to it. + const merkleTreeDb = await AztecNodeService.createMerkleTreeDB(); const publicProcessorFactory = new PublicProcessorFactory( - this.worldStateSynchroniser.getLatest(), + merkleTreeDb.asLatest(), this.contractDataSource, this.l1ToL2MessageSource, ); const blockNumber = (await this.blockSource.getBlockNumber()) + 1; const newGlobalVariables = await this.globalVariableBuilder.buildGlobalVariables(new Fr(blockNumber)); const prevGlobalVariables = (await this.blockSource.getL2Block(-1))?.globalVariables ?? GlobalVariables.empty(); - const processor = await publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables); const [, failedTxs] = await processor.process([tx]); if (failedTxs.length) { diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 35748885af4..eb7dc60bf76 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -147,7 +147,8 @@ 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); - const [processedTxs, failedTxs] = await processor.process(validTxs); + // The processor modifies the tx objects in place, so we need to clone them. + const [processedTxs, failedTxs] = await processor.process(validTxs.map(tx => Tx.fromJSON(tx.toJSON()))); if (failedTxs.length > 0) { const failedTxData = failedTxs.map(fail => fail.tx); this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`);