Skip to content

Commit aba3018

Browse files
committed
fix: avoid simulations modifying state and txs
1 parent 7eda8a4 commit aba3018

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

yarn-project/aztec-node/src/aztec-node/server.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class AztecNodeService implements AztecNode {
8888
const p2pClient = await createP2PClient(config, new InMemoryTxPool(), archiver);
8989

9090
// now create the merkle trees and the world state syncher
91-
const merkleTreeDB = await MerkleTrees.new(levelup(createMemDown()), await CircuitsWasm.get());
91+
const merkleTreeDB = await AztecNodeService.createMerkleTreeDB();
9292
const worldStateConfig: WorldStateConfig = getWorldStateConfig();
9393
const worldStateSynchroniser = new ServerWorldStateSynchroniser(merkleTreeDB, archiver, worldStateConfig);
9494

@@ -119,6 +119,10 @@ export class AztecNodeService implements AztecNode {
119119
);
120120
}
121121

122+
static async createMerkleTreeDB() {
123+
return MerkleTrees.new(levelup(createMemDown()), await CircuitsWasm.get());
124+
}
125+
122126
/**
123127
* Method to determine if the node is ready to accept transactions.
124128
* @returns - Flag indicating the readiness for tx submission.
@@ -382,16 +386,17 @@ export class AztecNodeService implements AztecNode {
382386
**/
383387
public async simulatePublicPart(tx: Tx) {
384388
this.log.info(`Simulating tx ${await tx.getTxHash()}`);
389+
// Instantiate merkle tree db so uncommited updates by this simulation are local to it.
390+
const merkleTreeDb = await AztecNodeService.createMerkleTreeDB();
385391

386392
const publicProcessorFactory = new PublicProcessorFactory(
387-
this.worldStateSynchroniser.getLatest(),
393+
merkleTreeDb.asLatest(),
388394
this.contractDataSource,
389395
this.l1ToL2MessageSource,
390396
);
391397
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
392398
const newGlobalVariables = await this.globalVariableBuilder.buildGlobalVariables(new Fr(blockNumber));
393399
const prevGlobalVariables = (await this.blockSource.getL2Block(-1))?.globalVariables ?? GlobalVariables.empty();
394-
395400
const processor = await publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
396401
const [, failedTxs] = await processor.process([tx]);
397402
if (failedTxs.length) {

yarn-project/sequencer-client/src/sequencer/sequencer.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ export class Sequencer {
147147
// Process txs and drop the ones that fail processing
148148
// We create a fresh processor each time to reset any cached state (eg storage writes)
149149
const processor = await this.publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
150-
const [processedTxs, failedTxs] = await processor.process(validTxs);
150+
// The processor modifies the tx objects in place, so we need to clone them.
151+
const [processedTxs, failedTxs] = await processor.process(validTxs.map(tx => Tx.fromJSON(tx.toJSON())));
151152
if (failedTxs.length > 0) {
152153
const failedTxData = failedTxs.map(fail => fail.tx);
153154
this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`);

0 commit comments

Comments
 (0)