diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index d4f3702c4ef..fb400a50510 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -31,9 +31,12 @@ describe('e2e_voting_contract', () => { expect(await votingContract.methods.get_vote(candidate).simulate()).toBe(1n); // We try voting again, but our TX is dropped due to trying to emit duplicate nullifiers - await expect(votingContract.methods.cast_vote(candidate).send().wait()).rejects.toThrow( - 'Reason: Tx dropped by P2P node.', - ); + // first confirm that it fails simulation + await expect(votingContract.methods.cast_vote(candidate).send().wait()).rejects.toThrow(/Nullifier collision/); + // if we skip simulation, tx is dropped + await expect( + votingContract.methods.cast_vote(candidate).send({ skipPublicSimulation: true }).wait(), + ).rejects.toThrow('Reason: Tx dropped by P2P node.'); }); }); }); diff --git a/yarn-project/end-to-end/src/fixtures/fixtures.ts b/yarn-project/end-to-end/src/fixtures/fixtures.ts index ccaa85f3516..79d10d0d2da 100644 --- a/yarn-project/end-to-end/src/fixtures/fixtures.ts +++ b/yarn-project/end-to-end/src/fixtures/fixtures.ts @@ -16,7 +16,7 @@ export const U128_UNDERFLOW_ERROR = "Assertion failed: attempt to subtract with export const U128_OVERFLOW_ERROR = "Assertion failed: attempt to add with overflow 'hi == high'"; export const BITSIZE_TOO_BIG_ERROR = "Assertion failed: call to assert_max_bit_size 'self.__assert_max_bit_size'"; // TODO(https://github.com/AztecProtocol/aztec-packages/issues/5818): Make these a fixed error after transition. -export const DUPLICATE_NULLIFIER_ERROR = /dropped|duplicate nullifier|reverted/; +export const DUPLICATE_NULLIFIER_ERROR = /dropped|duplicate nullifier|reverted|Nullifier collision/; export const NO_L1_TO_L2_MSG_ERROR = /No non-nullified L1 to L2 message found for message hash|Tried to consume nonexistent L1-to-L2 message/; export const STATIC_CALL_STATE_MODIFICATION_ERROR = diff --git a/yarn-project/simulator/src/public/public_tx_simulator.ts b/yarn-project/simulator/src/public/public_tx_simulator.ts index e53d050beae..7cf250cc1d5 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator.ts @@ -26,6 +26,7 @@ import { strict as assert } from 'assert'; import { type AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js'; import { type AvmPersistableStateManager, AvmSimulator } from '../avm/index.js'; +import { NullifierCollisionError } from '../avm/journal/nullifiers.js'; import { getPublicFunctionDebugName } from '../common/debug_fn_name.js'; import { ExecutorMetrics } from './executor_metrics.js'; import { type WorldStateDB } from './public_db_sources.js'; @@ -385,7 +386,15 @@ export class PublicTxSimulator { */ public async insertNonRevertiblesFromPrivate(context: PublicTxContext) { const stateManager = context.state.getActiveStateManager(); - await stateManager.writeSiloedNullifiersFromPrivate(context.nonRevertibleAccumulatedDataFromPrivate.nullifiers); + try { + await stateManager.writeSiloedNullifiersFromPrivate(context.nonRevertibleAccumulatedDataFromPrivate.nullifiers); + } catch (e) { + if (e instanceof NullifierCollisionError) { + throw new NullifierCollisionError( + `Nullifier collision encountered when inserting non-revertible nullifiers from private.\nDetails: ${e.message}\n.Stack:${e.stack}`, + ); + } + } } /** @@ -396,6 +405,14 @@ export class PublicTxSimulator { // Fork the state manager so we can rollback to end of setup if app logic reverts. context.state.fork(); const stateManager = context.state.getActiveStateManager(); - await stateManager.writeSiloedNullifiersFromPrivate(context.revertibleAccumulatedDataFromPrivate.nullifiers); + try { + await stateManager.writeSiloedNullifiersFromPrivate(context.revertibleAccumulatedDataFromPrivate.nullifiers); + } catch (e) { + if (e instanceof NullifierCollisionError) { + throw new NullifierCollisionError( + `Nullifier collision encountered when inserting revertible nullifiers from private. Details:\n${e.message}\n.Stack:${e.stack}`, + ); + } + } } }