diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index ffa1eaf6b3c8..cf6557796749 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -761,7 +761,7 @@ export class AztecNodeService implements AztecNode { const txValidators: TxValidator[] = [ new DataTxValidator(), new MetadataTxValidator(new Fr(this.l1ChainId), new Fr(blockNumber)), - new DoubleSpendTxValidator(new WorldStateDB(this.worldStateSynchronizer.getLatest())), + new DoubleSpendTxValidator(new WorldStateDB(this.worldStateSynchronizer.getLatest(), this.contractDataSource)), ]; if (!isSimulation) { diff --git a/yarn-project/bb-prover/src/avm_proving.test.ts b/yarn-project/bb-prover/src/avm_proving.test.ts index 80c9033b827b..e667b8dd1210 100644 --- a/yarn-project/bb-prover/src/avm_proving.test.ts +++ b/yarn-project/bb-prover/src/avm_proving.test.ts @@ -1,12 +1,11 @@ import { AvmCircuitInputs, AvmVerificationKeyData, FunctionSelector, Gas, GlobalVariables } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { AvmSimulator, type PublicContractsDB, PublicSideEffectTrace, type PublicStateDB } from '@aztec/simulator'; +import { AvmSimulator, type PublicContractsDB, PublicSideEffectTrace, type WorldStateDB } from '@aztec/simulator'; import { getAvmTestContractBytecode, initContext, initExecutionEnvironment, - initHostStorage, initPersistableStateManager, resolveAvmTestContractAssertionMessage, } from '@aztec/simulator/avm/fixtures'; @@ -70,16 +69,15 @@ const proveAndVerifyAvmTestContract = async ( }).withAddress(environment.address); contractsDb.getContractInstance.mockResolvedValue(Promise.resolve(contractInstance)); - const storageDb = mock(); + const worldStateDB = mock(); const storageValue = new Fr(5); - storageDb.storageRead.mockResolvedValue(Promise.resolve(storageValue)); + worldStateDB.storageRead.mockResolvedValue(Promise.resolve(storageValue)); - const hostStorage = initHostStorage({ contractsDb }); const trace = new PublicSideEffectTrace(startSideEffectCounter); - const persistableState = initPersistableStateManager({ hostStorage, trace }); + const persistableState = initPersistableStateManager({ worldStateDB, trace }); const context = initContext({ env: environment, persistableState }); const nestedCallBytecode = getAvmTestContractBytecode('add_args_return'); - jest.spyOn(hostStorage.contractsDb, 'getBytecode').mockResolvedValue(nestedCallBytecode); + jest.spyOn(worldStateDB, 'getBytecode').mockResolvedValue(nestedCallBytecode); const startGas = new Gas(context.machineState.gasLeft.daGas, context.machineState.gasLeft.l2Gas); diff --git a/yarn-project/ivc-integration/src/avm_integration.test.ts b/yarn-project/ivc-integration/src/avm_integration.test.ts index 693b60168c58..c2bb09e3675b 100644 --- a/yarn-project/ivc-integration/src/avm_integration.test.ts +++ b/yarn-project/ivc-integration/src/avm_integration.test.ts @@ -16,12 +16,11 @@ import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { BufferReader } from '@aztec/foundation/serialize'; import { type FixedLengthArray } from '@aztec/noir-protocol-circuits-types/types'; -import { AvmSimulator, type PublicContractsDB, PublicSideEffectTrace, type PublicStateDB } from '@aztec/simulator'; +import { AvmSimulator, type PublicContractsDB, PublicSideEffectTrace, type WorldStateDB } from '@aztec/simulator'; import { getAvmTestContractBytecode, initContext, initExecutionEnvironment, - initHostStorage, initPersistableStateManager, resolveAvmTestContractAssertionMessage, } from '@aztec/simulator/avm/fixtures'; @@ -146,16 +145,15 @@ const proveAvmTestContract = async ( }).withAddress(environment.address); contractsDb.getContractInstance.mockResolvedValue(await Promise.resolve(contractInstance)); - const storageDb = mock(); + const worldStateDB = mock(); const storageValue = new Fr(5); - storageDb.storageRead.mockResolvedValue(await Promise.resolve(storageValue)); + worldStateDB.storageRead.mockResolvedValue(await Promise.resolve(storageValue)); - const hostStorage = initHostStorage({ contractsDb }); const trace = new PublicSideEffectTrace(startSideEffectCounter); - const persistableState = initPersistableStateManager({ hostStorage, trace }); + const persistableState = initPersistableStateManager({ worldStateDB, trace }); const context = initContext({ env: environment, persistableState }); const nestedCallBytecode = getAvmTestContractBytecode('add_args_return'); - jest.spyOn(hostStorage.contractsDb, 'getBytecode').mockResolvedValue(nestedCallBytecode); + jest.spyOn(worldStateDB, 'getBytecode').mockResolvedValue(nestedCallBytecode); const startGas = new Gas(context.machineState.gasLeft.daGas, context.machineState.gasLeft.l2Gas); diff --git a/yarn-project/prover-client/src/mocks/test_context.ts b/yarn-project/prover-client/src/mocks/test_context.ts index e0d6e1706852..f5d9b78a8aca 100644 --- a/yarn-project/prover-client/src/mocks/test_context.ts +++ b/yarn-project/prover-client/src/mocks/test_context.ts @@ -13,7 +13,6 @@ import { type Fr } from '@aztec/foundation/fields'; import { type DebugLogger } from '@aztec/foundation/log'; import { openTmpStore } from '@aztec/kv-store/utils'; import { - type ContractsDataSourcePublicDB, type PublicExecutionResult, PublicExecutionResultBuilder, type PublicExecutor, @@ -21,7 +20,7 @@ import { RealPublicKernelCircuitSimulator, type SimulationProvider, WASMSimulator, - type WorldStatePublicDB, + type WorldStateDB, } from '@aztec/simulator'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { MerkleTrees } from '@aztec/world-state'; @@ -41,8 +40,7 @@ import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixt export class TestContext { constructor( public publicExecutor: MockProxy, - public publicContractsDB: MockProxy, - public publicWorldStateDB: MockProxy, + public worldStateDB: MockProxy, public publicProcessor: PublicProcessor, public simulationProvider: SimulationProvider, public globalVariables: GlobalVariables, @@ -71,8 +69,7 @@ export class TestContext { const globalVariables = makeGlobals(blockNumber); const publicExecutor = mock(); - const publicContractsDB = mock(); - const publicWorldStateDB = mock(); + const worldStateDB = mock(); const publicKernel = new RealPublicKernelCircuitSimulator(new WASMSimulator()); const telemetry = new NoopTelemetryClient(); @@ -94,8 +91,7 @@ export class TestContext { publicKernel, GlobalVariables.empty(), Header.empty(), - publicContractsDB, - publicWorldStateDB, + worldStateDB, telemetry, ); @@ -130,8 +126,7 @@ export class TestContext { return new this( publicExecutor, - publicContractsDB, - publicWorldStateDB, + worldStateDB, processor, simulationProvider, globalVariables, diff --git a/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts b/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts index acf7e21cf6ad..410322968e55 100644 --- a/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts +++ b/yarn-project/sequencer-client/src/tx_validator/tx_validator_factory.ts @@ -2,7 +2,7 @@ import { type AllowedElement, type ProcessedTx, type Tx, type TxValidator } from import { type GlobalVariables } from '@aztec/circuits.js'; import { AggregateTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator } from '@aztec/p2p'; import { FeeJuiceAddress } from '@aztec/protocol-contracts/fee-juice'; -import { WorldStateDB, WorldStatePublicDB } from '@aztec/simulator'; +import { WorldStateDB } from '@aztec/simulator'; import { type ContractDataSource } from '@aztec/types/contracts'; import { type MerkleTreeOperations } from '@aztec/world-state'; @@ -17,16 +17,17 @@ export class TxValidatorFactory { ) {} validatorForNewTxs(globalVariables: GlobalVariables, setupAllowList: AllowedElement[]): TxValidator { + const worldStateDB = new WorldStateDB(this.merkleTreeDb, this.contractDataSource); return new AggregateTxValidator( new DataTxValidator(), new MetadataTxValidator(globalVariables.chainId, globalVariables.blockNumber), - new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb)), + new DoubleSpendTxValidator(worldStateDB), new PhasesTxValidator(this.contractDataSource, setupAllowList), - new GasTxValidator(new WorldStatePublicDB(this.merkleTreeDb), FeeJuiceAddress, this.enforceFees), + new GasTxValidator(worldStateDB, FeeJuiceAddress, this.enforceFees), ); } validatorForProcessedTxs(): TxValidator { - return new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb)); + return new DoubleSpendTxValidator(new WorldStateDB(this.merkleTreeDb, this.contractDataSource)); } } diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index df66275513b1..0c1906b42d04 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -10,6 +10,7 @@ import { type Fieldable } from '@aztec/foundation/serialize'; import { randomInt } from 'crypto'; import { mock } from 'jest-mock-extended'; +import { type WorldStateDB } from '../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../public/side_effect_trace_interface.js'; import { type AvmContext } from './avm_context.js'; import { type AvmExecutionEnvironment } from './avm_execution_environment.js'; @@ -22,7 +23,6 @@ import { initContext, initExecutionEnvironment, initGlobalVariables, - initHostStorage, initMachineState, initPersistableStateManager, randomMemoryBytes, @@ -30,7 +30,6 @@ import { randomMemoryUint64s, resolveAvmTestContractAssertionMessage, } from './fixtures/index.js'; -import { type HostStorage } from './journal/host_storage.js'; import { type AvmPersistableStateManager } from './journal/journal.js'; import { Add, CalldataCopy, Return, Set } from './opcodes/index.js'; import { encodeToBytecode } from './serialization/bytecode_serialization.js'; @@ -395,14 +394,14 @@ describe('AVM simulator: transpiled Noir contracts', () => { const value0 = new Fr(420); const value1 = new Fr(69); - let hostStorage: HostStorage; + let worldStateDB: WorldStateDB; let trace: PublicSideEffectTraceInterface; let persistableState: AvmPersistableStateManager; beforeEach(() => { - hostStorage = initHostStorage(); + worldStateDB = mock(); trace = mock(); - persistableState = initPersistableStateManager({ hostStorage, trace }); + persistableState = initPersistableStateManager({ worldStateDB, trace }); }); const createContext = (calldata: Fr[] = []) => { @@ -429,7 +428,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('note_hash_exists'); if (mockAtLeafIndex !== undefined) { - mockNoteHashExists(hostStorage, mockAtLeafIndex, value0); + mockNoteHashExists(worldStateDB, mockAtLeafIndex, value0); } const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -454,7 +453,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const bytecode = getAvmTestContractBytecode('nullifier_exists'); if (exists) { - mockNullifierExists(hostStorage, leafIndex, value0); + mockNullifierExists(worldStateDB, leafIndex, value0); } const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -493,7 +492,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); if (mockAtLeafIndex !== undefined) { - mockL1ToL2MessageExists(hostStorage, mockAtLeafIndex, value0, /*valueAtOtherIndices=*/ value1); + mockL1ToL2MessageExists(worldStateDB, mockAtLeafIndex, value0, /*valueAtOtherIndices=*/ value1); } const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -631,7 +630,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { it('Should read value in storage (single)', async () => { const context = createContext(); - mockStorageRead(hostStorage, value0); + mockStorageRead(worldStateDB, value0); const bytecode = getAvmTestContractBytecode('read_storage_single'); @@ -694,7 +693,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { [listSlot0.toBigInt(), value0], [listSlot1.toBigInt(), value1], ]); - mockStorageReadWithMap(hostStorage, mockedStorage); + mockStorageReadWithMap(worldStateDB, mockedStorage); const bytecode = getAvmTestContractBytecode('read_storage_list'); @@ -768,7 +767,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const calldata = [storageAddress]; const context = createContext(calldata); - mockStorageRead(hostStorage, value0); + mockStorageRead(worldStateDB, value0); const bytecode = getAvmTestContractBytecode('read_storage_map'); const results = await new AvmSimulator(context).executeBytecode(bytecode); @@ -800,7 +799,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { initializationHash: new Fr(0x101112), publicKeysHash: new Fr(0x161718), }; - mockGetContractInstance(hostStorage, contractInstance); + mockGetContractInstance(worldStateDB, contractInstance); const bytecode = getAvmTestContractBytecode('test_get_contract_instance_raw'); @@ -844,7 +843,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); const callBytecode = getAvmTestContractBytecode('nested_call_to_add'); const addBytecode = getAvmTestContractBytecode('add_args_return'); - mockGetBytecode(hostStorage, addBytecode); + mockGetBytecode(worldStateDB, addBytecode); const nestedTrace = mock(); mockTraceFork(trace, nestedTrace); @@ -860,7 +859,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); const callBytecode = getAvmTestContractBytecode('nested_static_call_to_add'); const addBytecode = getAvmTestContractBytecode('add_args_return'); - mockGetBytecode(hostStorage, addBytecode); + mockGetBytecode(worldStateDB, addBytecode); const nestedTrace = mock(); mockTraceFork(trace, nestedTrace); @@ -877,7 +876,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(calldata); const callBytecode = getAvmTestContractBytecode('nested_call_to_add_with_gas'); const addBytecode = getAvmTestContractBytecode('add_args_return'); - mockGetBytecode(hostStorage, addBytecode); + mockGetBytecode(worldStateDB, addBytecode); mockTraceFork(trace); const results = await new AvmSimulator(context).executeBytecode(callBytecode); @@ -896,7 +895,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const context = createContext(); const callBytecode = getAvmTestContractBytecode('nested_static_call_to_set_storage'); const nestedBytecode = getAvmTestContractBytecode('set_storage_single'); - mockGetBytecode(hostStorage, nestedBytecode); + mockGetBytecode(worldStateDB, nestedBytecode); mockTraceFork(trace); const results = await new AvmSimulator(context).executeBytecode(callBytecode); @@ -920,7 +919,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const callBytecode = getAvmTestContractBytecode('nested_call_to_add'); // We actually don't pass the function ADD, but it's ok because the signature is the same. const nestedBytecode = getAvmTestContractBytecode('assert_same'); - mockGetBytecode(hostStorage, nestedBytecode); + mockGetBytecode(worldStateDB, nestedBytecode); const results = await new AvmSimulator(context).executeBytecode(callBytecode); expect(results.reverted).toBe(true); // The outer call should revert. diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index 72bc6d66a7fb..28092122612e 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -10,20 +10,13 @@ import { strict as assert } from 'assert'; import { mock } from 'jest-mock-extended'; import merge from 'lodash.merge'; -import { - type CommitmentsDB, - type PublicContractsDB, - type PublicStateDB, - resolveAssertionMessage, - traverseCauseChain, -} from '../../index.js'; +import { type WorldStateDB, resolveAssertionMessage, traverseCauseChain } from '../../index.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; import { AvmContext } from '../avm_context.js'; import { AvmContextInputs, AvmExecutionEnvironment } from '../avm_execution_environment.js'; import { AvmMachineState } from '../avm_machine_state.js'; import { Field, Uint8, Uint64 } from '../avm_memory_types.js'; import { type AvmRevertReason } from '../errors.js'; -import { HostStorage } from '../journal/host_storage.js'; import { AvmPersistableStateManager } from '../journal/journal.js'; import { NullifierManager } from '../journal/nullifiers.js'; import { PublicStorage } from '../journal/public_storage.js'; @@ -43,32 +36,19 @@ export function initContext(overrides?: { ); } -/** Creates an empty host storage with mocked dbs. */ -export function initHostStorage(overrides?: { - publicDb?: PublicStateDB; - contractsDb?: PublicContractsDB; - commitmentsDb?: CommitmentsDB; -}): HostStorage { - return new HostStorage( - overrides?.publicDb || mock(), - overrides?.contractsDb || mock(), - overrides?.commitmentsDb || mock(), - ); -} - /** Creates an empty state manager with mocked host storage. */ export function initPersistableStateManager(overrides?: { - hostStorage?: HostStorage; + worldStateDB?: WorldStateDB; trace?: PublicSideEffectTraceInterface; publicStorage?: PublicStorage; nullifiers?: NullifierManager; }): AvmPersistableStateManager { - const hostStorage = overrides?.hostStorage || initHostStorage(); + const worldStateDB = overrides?.worldStateDB || mock(); return new AvmPersistableStateManager( - hostStorage, + worldStateDB, overrides?.trace || mock(), - overrides?.publicStorage || new PublicStorage(hostStorage.publicStateDb), - overrides?.nullifiers || new NullifierManager(hostStorage.commitmentsDb), + overrides?.publicStorage || new PublicStorage(worldStateDB), + overrides?.nullifiers || new NullifierManager(worldStateDB), ); } diff --git a/yarn-project/simulator/src/avm/journal/host_storage.ts b/yarn-project/simulator/src/avm/journal/host_storage.ts deleted file mode 100644 index 1064c82b5e3c..000000000000 --- a/yarn-project/simulator/src/avm/journal/host_storage.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from '../../public/db_interfaces.js'; - -/** - * Host storage - * - * A wrapper around the node dbs - */ -export class HostStorage { - constructor( - public readonly publicStateDb: PublicStateDB, - public readonly contractsDb: PublicContractsDB, - public readonly commitmentsDb: CommitmentsDB, - ) {} -} diff --git a/yarn-project/simulator/src/avm/journal/index.ts b/yarn-project/simulator/src/avm/journal/index.ts index 86fe25115d8e..5a3cc78b4162 100644 --- a/yarn-project/simulator/src/avm/journal/index.ts +++ b/yarn-project/simulator/src/avm/journal/index.ts @@ -1,2 +1 @@ -export * from './host_storage.js'; export * from './journal.js'; diff --git a/yarn-project/simulator/src/avm/journal/journal.test.ts b/yarn-project/simulator/src/avm/journal/journal.test.ts index f3c18188d129..07efb46a6471 100644 --- a/yarn-project/simulator/src/avm/journal/journal.test.ts +++ b/yarn-project/simulator/src/avm/journal/journal.test.ts @@ -4,8 +4,9 @@ import { SerializableContractInstance } from '@aztec/types/contracts'; import { mock } from 'jest-mock-extended'; +import { type WorldStateDB } from '../../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; -import { initHostStorage, initPersistableStateManager } from '../fixtures/index.js'; +import { initPersistableStateManager } from '../fixtures/index.js'; import { mockGetContractInstance, mockL1ToL2MessageExists, @@ -13,7 +14,6 @@ import { mockNullifierExists, mockStorageRead, } from '../test_utils.js'; -import { type HostStorage } from './host_storage.js'; import { type AvmPersistableStateManager } from './journal.js'; describe('journal', () => { @@ -21,14 +21,14 @@ describe('journal', () => { const utxo = Fr.random(); const leafIndex = Fr.random(); - let hostStorage: HostStorage; + let worldStateDB: WorldStateDB; let trace: PublicSideEffectTraceInterface; let persistableState: AvmPersistableStateManager; beforeEach(() => { - hostStorage = initHostStorage(); + worldStateDB = mock(); trace = mock(); - persistableState = initPersistableStateManager({ hostStorage, trace }); + persistableState = initPersistableStateManager({ worldStateDB, trace }); }); describe('Public Storage', () => { @@ -38,7 +38,7 @@ describe('journal', () => { const storedValue = new Fr(420); const cachedValue = new Fr(69); - mockStorageRead(hostStorage, storedValue); + mockStorageRead(worldStateDB, storedValue); // Get the cache first const cacheMissResult = await persistableState.readStorage(address, slot); @@ -83,7 +83,7 @@ describe('journal', () => { }); it('checkNoteHashExists works for existing note hashes', async () => { - mockNoteHashExists(hostStorage, leafIndex, utxo); + mockNoteHashExists(worldStateDB, leafIndex, utxo); const exists = await persistableState.checkNoteHashExists(address, utxo, leafIndex); expect(exists).toEqual(true); expect(trace.traceNoteHashCheck).toHaveBeenCalledTimes(1); @@ -110,7 +110,7 @@ describe('journal', () => { }); it('checkNullifierExists works for existing nullifiers', async () => { - mockNullifierExists(hostStorage, leafIndex, utxo); + mockNullifierExists(worldStateDB, leafIndex, utxo); const exists = await persistableState.checkNullifierExists(address, utxo); expect(exists).toEqual(true); expect(trace.traceNullifierCheck).toHaveBeenCalledTimes(1); @@ -130,7 +130,7 @@ describe('journal', () => { }); it('checkL1ToL2MessageExists works for existing message', async () => { - mockL1ToL2MessageExists(hostStorage, leafIndex, utxo); + mockL1ToL2MessageExists(worldStateDB, leafIndex, utxo); const exists = await persistableState.checkL1ToL2MessageExists(address, utxo, leafIndex); expect(exists).toEqual(true); expect(trace.traceL1ToL2MessageCheck).toHaveBeenCalledTimes(1); @@ -148,7 +148,7 @@ describe('journal', () => { describe('Getting contract instances', () => { it('Should get contract instance', async () => { const contractInstance = randomContractInstanceWithAddress(/*(base instance) opts=*/ {}, /*address=*/ address); - mockGetContractInstance(hostStorage, contractInstance); + mockGetContractInstance(worldStateDB, contractInstance); await persistableState.getContractInstance(address); expect(trace.traceGetContractInstance).toHaveBeenCalledTimes(1); expect(trace.traceGetContractInstance).toHaveBeenCalledWith({ exists: true, ...contractInstance }); diff --git a/yarn-project/simulator/src/avm/journal/journal.ts b/yarn-project/simulator/src/avm/journal/journal.ts index 2f869c76a7b8..843b6ed90aec 100644 --- a/yarn-project/simulator/src/avm/journal/journal.ts +++ b/yarn-project/simulator/src/avm/journal/journal.ts @@ -3,11 +3,11 @@ import { Fr } from '@aztec/foundation/fields'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { SerializableContractInstance } from '@aztec/types/contracts'; +import { type WorldStateDB } from '../../public/public_db_sources.js'; import { type TracedContractInstance } from '../../public/side_effect_trace.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; import { type AvmContractCallResult } from '../avm_contract_call_result.js'; import { type AvmExecutionEnvironment } from '../avm_execution_environment.js'; -import { type HostStorage } from './host_storage.js'; import { NullifierManager } from './nullifiers.js'; import { PublicStorage } from './public_storage.js'; @@ -25,7 +25,7 @@ export class AvmPersistableStateManager { constructor( /** Reference to node storage */ - private readonly hostStorage: HostStorage, + private readonly worldStateDB: WorldStateDB, /** Side effect trace */ private readonly trace: PublicSideEffectTraceInterface, /** Public storage, including cached writes */ @@ -39,18 +39,15 @@ export class AvmPersistableStateManager { * Create a new state manager with some preloaded pending siloed nullifiers */ public static newWithPendingSiloedNullifiers( - hostStorage: HostStorage, + worldStateDB: WorldStateDB, trace: PublicSideEffectTraceInterface, pendingSiloedNullifiers: Fr[], ) { - const parentNullifiers = NullifierManager.newWithPendingSiloedNullifiers( - hostStorage.commitmentsDb, - pendingSiloedNullifiers, - ); + const parentNullifiers = NullifierManager.newWithPendingSiloedNullifiers(worldStateDB, pendingSiloedNullifiers); return new AvmPersistableStateManager( - hostStorage, + worldStateDB, trace, - /*publicStorage=*/ new PublicStorage(hostStorage.publicStateDb), + /*publicStorage=*/ new PublicStorage(worldStateDB), /*nullifiers=*/ parentNullifiers.fork(), ); } @@ -60,7 +57,7 @@ export class AvmPersistableStateManager { */ public fork() { return new AvmPersistableStateManager( - this.hostStorage, + this.worldStateDB, this.trace.fork(), this.publicStorage.fork(), this.nullifiers.fork(), @@ -122,7 +119,7 @@ export class AvmPersistableStateManager { * @returns true if the note hash exists at the given leaf index, false otherwise */ public async checkNoteHashExists(storageAddress: Fr, noteHash: Fr, leafIndex: Fr): Promise { - const gotLeafValue = (await this.hostStorage.commitmentsDb.getCommitmentValue(leafIndex.toBigInt())) ?? Fr.ZERO; + const gotLeafValue = (await this.worldStateDB.getCommitmentValue(leafIndex.toBigInt())) ?? Fr.ZERO; const exists = gotLeafValue.equals(noteHash); this.log.debug( `noteHashes(${storageAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`, @@ -177,7 +174,7 @@ export class AvmPersistableStateManager { * @returns exists - whether the message exists in the L1 to L2 Messages tree */ public async checkL1ToL2MessageExists(contractAddress: Fr, msgHash: Fr, msgLeafIndex: Fr): Promise { - const valueAtIndex = (await this.hostStorage.commitmentsDb.getL1ToL2LeafValue(msgLeafIndex.toBigInt())) ?? Fr.ZERO; + const valueAtIndex = (await this.worldStateDB.getL1ToL2LeafValue(msgLeafIndex.toBigInt())) ?? Fr.ZERO; const exists = valueAtIndex.equals(msgHash); this.log.debug( `l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`, @@ -217,7 +214,7 @@ export class AvmPersistableStateManager { public async getContractInstance(contractAddress: Fr): Promise { let exists = true; const aztecAddress = AztecAddress.fromField(contractAddress); - let instance = await this.hostStorage.contractsDb.getContractInstance(aztecAddress); + let instance = await this.worldStateDB.getContractInstance(aztecAddress); if (instance === undefined) { instance = SerializableContractInstance.empty().withAddress(aztecAddress); exists = false; @@ -242,7 +239,7 @@ export class AvmPersistableStateManager { * Get a contract's bytecode from the contracts DB */ public async getBytecode(contractAddress: AztecAddress, selector: FunctionSelector): Promise { - return await this.hostStorage.contractsDb.getBytecode(contractAddress, selector); + return await this.worldStateDB.getBytecode(contractAddress, selector); } /** @@ -260,10 +257,8 @@ export class AvmPersistableStateManager { this.acceptNestedCallState(nestedState); } const functionName = - (await nestedState.hostStorage.contractsDb.getDebugFunctionName( - nestedEnvironment.address, - nestedEnvironment.functionSelector, - )) ?? `${nestedEnvironment.address}:${nestedEnvironment.functionSelector}`; + (await this.worldStateDB.getDebugFunctionName(nestedEnvironment.address, nestedEnvironment.functionSelector)) ?? + `${nestedEnvironment.address}:${nestedEnvironment.functionSelector}`; this.log.verbose(`[AVM] Calling nested function ${functionName}`); diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts index aab2ae6efa6c..442bb985ba37 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.test.ts @@ -2,17 +2,12 @@ import { Fr } from '@aztec/circuits.js'; import { mock } from 'jest-mock-extended'; +import { type WorldStateDB } from '../../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; import { type AvmContext } from '../avm_context.js'; import { Field, Uint8, Uint32 } from '../avm_memory_types.js'; import { InstructionExecutionError, StaticCallAlterationError } from '../errors.js'; -import { - initContext, - initExecutionEnvironment, - initHostStorage, - initPersistableStateManager, -} from '../fixtures/index.js'; -import { type HostStorage } from '../journal/host_storage.js'; +import { initContext, initExecutionEnvironment, initPersistableStateManager } from '../fixtures/index.js'; import { type AvmPersistableStateManager } from '../journal/journal.js'; import { mockL1ToL2MessageExists, mockNoteHashExists, mockNullifierExists } from '../test_utils.js'; import { @@ -26,7 +21,7 @@ import { } from './accrued_substate.js'; describe('Accrued Substate', () => { - let hostStorage: HostStorage; + let worldStateDB: WorldStateDB; let trace: PublicSideEffectTraceInterface; let persistableState: AvmPersistableStateManager; let context: AvmContext; @@ -43,9 +38,9 @@ describe('Accrued Substate', () => { const existsOffset = 2; beforeEach(() => { - hostStorage = initHostStorage(); + worldStateDB = mock(); trace = mock(); - persistableState = initPersistableStateManager({ hostStorage, trace }); + persistableState = initPersistableStateManager({ worldStateDB, trace }); context = initContext({ persistableState, env: initExecutionEnvironment({ address, storageAddress, sender }) }); }); @@ -83,7 +78,7 @@ describe('Accrued Substate', () => { : ''; it(`Should return ${expectFound} (and be traced) when noteHash ${existsStr} ${foundAtStr}`, async () => { if (mockAtLeafIndex !== undefined) { - mockNoteHashExists(hostStorage, mockAtLeafIndex, value0); + mockNoteHashExists(worldStateDB, mockAtLeafIndex, value0); } context.machineState.memory.set(value0Offset, new Field(value0)); // noteHash @@ -160,7 +155,7 @@ describe('Accrued Substate', () => { const storageAddressOffset = 1; if (exists) { - mockNullifierExists(hostStorage, leafIndex, value0); + mockNullifierExists(worldStateDB, leafIndex, value0); } context.machineState.memory.set(value0Offset, new Field(value0)); // nullifier @@ -229,7 +224,7 @@ describe('Accrued Substate', () => { }); it('Nullifier collision reverts (nullifier exists in host state)', async () => { - mockNullifierExists(hostStorage, leafIndex); // db will say that nullifier already exists + mockNullifierExists(worldStateDB, leafIndex); // db will say that nullifier already exists context.machineState.memory.set(value0Offset, new Field(value0)); await expect(new EmitNullifier(/*indirect=*/ 0, /*offset=*/ value0Offset).execute(context)).rejects.toThrow( new InstructionExecutionError( @@ -275,7 +270,7 @@ describe('Accrued Substate', () => { it(`Should return ${expectFound} (and be traced) when noteHash ${existsStr} ${foundAtStr}`, async () => { if (mockAtLeafIndex !== undefined) { - mockL1ToL2MessageExists(hostStorage, mockAtLeafIndex, value0, /*valueAtOtherIndices=*/ value1); + mockL1ToL2MessageExists(worldStateDB, mockAtLeafIndex, value0, /*valueAtOtherIndices=*/ value1); } context.machineState.memory.set(value0Offset, new Field(value0)); // noteHash diff --git a/yarn-project/simulator/src/avm/opcodes/contract.test.ts b/yarn-project/simulator/src/avm/opcodes/contract.test.ts index ced3a000d64f..6ce6eefac993 100644 --- a/yarn-project/simulator/src/avm/opcodes/contract.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/contract.test.ts @@ -4,11 +4,11 @@ import { SerializableContractInstance } from '@aztec/types/contracts'; import { mock } from 'jest-mock-extended'; +import { type WorldStateDB } from '../../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; import { type AvmContext } from '../avm_context.js'; import { Field } from '../avm_memory_types.js'; -import { initContext, initHostStorage, initPersistableStateManager } from '../fixtures/index.js'; -import { type HostStorage } from '../journal/host_storage.js'; +import { initContext, initPersistableStateManager } from '../fixtures/index.js'; import { type AvmPersistableStateManager } from '../journal/journal.js'; import { mockGetContractInstance } from '../test_utils.js'; import { GetContractInstance } from './contract.js'; @@ -16,15 +16,15 @@ import { GetContractInstance } from './contract.js'; describe('Contract opcodes', () => { const address = AztecAddress.random(); - let hostStorage: HostStorage; + let worldStateDB: WorldStateDB; let trace: PublicSideEffectTraceInterface; let persistableState: AvmPersistableStateManager; let context: AvmContext; beforeEach(() => { - hostStorage = initHostStorage(); + worldStateDB = mock(); trace = mock(); - persistableState = initPersistableStateManager({ hostStorage, trace }); + persistableState = initPersistableStateManager({ worldStateDB, trace }); context = initContext({ persistableState }); }); @@ -48,7 +48,7 @@ describe('Contract opcodes', () => { it('should copy contract instance to memory if found', async () => { const contractInstance = randomContractInstanceWithAddress(/*(base instance) opts=*/ {}, /*address=*/ address); - mockGetContractInstance(hostStorage, contractInstance); + mockGetContractInstance(worldStateDB, contractInstance); context.machineState.memory.set(0, new Field(address.toField())); await new GetContractInstance(/*indirect=*/ 0, /*addressOffset=*/ 0, /*dstOffset=*/ 1).execute(context); diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts index ce6bbe4a7f7f..638e7913d452 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.test.ts @@ -2,12 +2,12 @@ import { Fr } from '@aztec/foundation/fields'; import { mock } from 'jest-mock-extended'; +import { type WorldStateDB } from '../../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js'; import { type AvmContext } from '../avm_context.js'; import { Field, TypeTag, Uint8, Uint32 } from '../avm_memory_types.js'; import { markBytecodeAsAvm } from '../bytecode_utils.js'; -import { adjustCalldataIndex, initContext, initHostStorage, initPersistableStateManager } from '../fixtures/index.js'; -import { type HostStorage } from '../journal/host_storage.js'; +import { adjustCalldataIndex, initContext, initPersistableStateManager } from '../fixtures/index.js'; import { type AvmPersistableStateManager } from '../journal/journal.js'; import { encodeToBytecode } from '../serialization/bytecode_serialization.js'; import { Opcode } from '../serialization/instruction_serialization.js'; @@ -20,15 +20,15 @@ import { SStore } from './storage.js'; describe('External Calls', () => { let context: AvmContext; - let hostStorage: HostStorage; + let worldStateDB: WorldStateDB; let trace: PublicSideEffectTraceInterface; let persistableState: AvmPersistableStateManager; beforeEach(() => { - hostStorage = initHostStorage(); + worldStateDB = mock(); trace = mock(); - persistableState = initPersistableStateManager({ hostStorage, trace }); - context = initContext({ persistableState: persistableState }); + persistableState = initPersistableStateManager({ worldStateDB, trace }); + context = initContext({ persistableState }); mockTraceFork(trace); // make sure trace.fork() works on nested call }); @@ -94,7 +94,7 @@ describe('External Calls', () => { new Return(/*indirect=*/ 0, /*retOffset=*/ 0, /*size=*/ 2), ]), ); - mockGetBytecode(hostStorage, otherContextInstructionsBytecode); + mockGetBytecode(worldStateDB, otherContextInstructionsBytecode); const { l2GasLeft: initialL2Gas, daGasLeft: initialDaGas } = context.machineState; @@ -148,7 +148,7 @@ describe('External Calls', () => { new Return(/*indirect=*/ 0, /*retOffset=*/ 0, /*size=*/ 1), ]), ); - mockGetBytecode(hostStorage, otherContextInstructionsBytecode); + mockGetBytecode(worldStateDB, otherContextInstructionsBytecode); const { l2GasLeft: initialL2Gas, daGasLeft: initialDaGas } = context.machineState; @@ -235,7 +235,7 @@ describe('External Calls', () => { ]; const otherContextInstructionsBytecode = markBytecodeAsAvm(encodeToBytecode(otherContextInstructions)); - mockGetBytecode(hostStorage, otherContextInstructionsBytecode); + mockGetBytecode(worldStateDB, otherContextInstructionsBytecode); const instruction = new StaticCall( /*indirect=*/ 0, diff --git a/yarn-project/simulator/src/avm/test_utils.ts b/yarn-project/simulator/src/avm/test_utils.ts index f7dda9f6593d..65862759fb58 100644 --- a/yarn-project/simulator/src/avm/test_utils.ts +++ b/yarn-project/simulator/src/avm/test_utils.ts @@ -4,12 +4,11 @@ import { type ContractInstanceWithAddress } from '@aztec/types/contracts'; import { type jest } from '@jest/globals'; import { mock } from 'jest-mock-extended'; -import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from '../public/db_interfaces.js'; +import { type WorldStateDB } from '../public/public_db_sources.js'; import { type PublicSideEffectTraceInterface } from '../public/side_effect_trace_interface.js'; -import { type HostStorage } from './journal/host_storage.js'; -export function mockGetBytecode(hs: HostStorage, bytecode: Buffer) { - (hs as jest.Mocked).contractsDb.getBytecode.mockResolvedValue(bytecode); +export function mockGetBytecode(worldStateDB: WorldStateDB, bytecode: Buffer) { + (worldStateDB as jest.Mocked).getBytecode.mockResolvedValue(bytecode); } export function mockTraceFork(trace: PublicSideEffectTraceInterface, nestedTrace?: PublicSideEffectTraceInterface) { @@ -18,18 +17,18 @@ export function mockTraceFork(trace: PublicSideEffectTraceInterface, nestedTrace ); } -export function mockStorageRead(hs: HostStorage, value: Fr) { - (hs.publicStateDb as jest.Mocked).storageRead.mockResolvedValue(value); +export function mockStorageRead(worldStateDB: WorldStateDB, value: Fr) { + (worldStateDB as jest.Mocked).storageRead.mockResolvedValue(value); } -export function mockStorageReadWithMap(hs: HostStorage, mockedStorage: Map) { - (hs.publicStateDb as jest.Mocked).storageRead.mockImplementation((_address, slot) => +export function mockStorageReadWithMap(worldStateDB: WorldStateDB, mockedStorage: Map) { + (worldStateDB as jest.Mocked).storageRead.mockImplementation((_address, slot) => Promise.resolve(mockedStorage.get(slot.toBigInt()) ?? Fr.ZERO), ); } -export function mockNoteHashExists(hs: HostStorage, _leafIndex: Fr, value?: Fr) { - (hs.commitmentsDb as jest.Mocked).getCommitmentValue.mockImplementation((index: bigint) => { +export function mockNoteHashExists(worldStateDB: WorldStateDB, _leafIndex: Fr, value?: Fr) { + (worldStateDB as jest.Mocked).getCommitmentValue.mockImplementation((index: bigint) => { if (index == _leafIndex.toBigInt()) { return Promise.resolve(value); } else { @@ -39,12 +38,17 @@ export function mockNoteHashExists(hs: HostStorage, _leafIndex: Fr, value?: Fr) }); } -export function mockNullifierExists(hs: HostStorage, leafIndex: Fr, _value?: Fr) { - (hs.commitmentsDb as jest.Mocked).getNullifierIndex.mockResolvedValue(leafIndex.toBigInt()); +export function mockNullifierExists(worldStateDB: WorldStateDB, leafIndex: Fr, _value?: Fr) { + (worldStateDB as jest.Mocked).getNullifierIndex.mockResolvedValue(leafIndex.toBigInt()); } -export function mockL1ToL2MessageExists(hs: HostStorage, leafIndex: Fr, value: Fr, valueAtOtherIndices?: Fr) { - (hs.commitmentsDb as jest.Mocked).getL1ToL2LeafValue.mockImplementation((index: bigint) => { +export function mockL1ToL2MessageExists( + worldStateDB: WorldStateDB, + leafIndex: Fr, + value: Fr, + valueAtOtherIndices?: Fr, +) { + (worldStateDB as jest.Mocked).getL1ToL2LeafValue.mockImplementation((index: bigint) => { if (index == leafIndex.toBigInt()) { return Promise.resolve(value); } else { @@ -55,6 +59,6 @@ export function mockL1ToL2MessageExists(hs: HostStorage, leafIndex: Fr, value: F }); } -export function mockGetContractInstance(hs: HostStorage, contractInstance: ContractInstanceWithAddress) { - (hs.contractsDb as jest.Mocked).getContractInstance.mockResolvedValue(contractInstance); +export function mockGetContractInstance(worldStateDB: WorldStateDB, contractInstance: ContractInstanceWithAddress) { + (worldStateDB as jest.Mocked).getContractInstance.mockResolvedValue(contractInstance); } diff --git a/yarn-project/simulator/src/public/app_logic_phase_manager.ts b/yarn-project/simulator/src/public/app_logic_phase_manager.ts index 9809e4cb2268..5d78b366766e 100644 --- a/yarn-project/simulator/src/public/app_logic_phase_manager.ts +++ b/yarn-project/simulator/src/public/app_logic_phase_manager.ts @@ -1,11 +1,11 @@ import { PublicKernelType, type PublicProvingRequest, type Tx } from '@aztec/circuit-types'; import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; +import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { AbstractPhaseManager, makeAvmProvingRequest } from './abstract_phase_manager.js'; -import { type ContractsDataSourcePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; /** @@ -18,8 +18,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, + protected worldStateDB: WorldStateDB, phase: PublicKernelType = PublicKernelType.APP_LOGIC, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); @@ -37,7 +36,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { // TODO(@spalladino): Should we allow emitting contracts in the fee preparation phase? // TODO(#6464): Should we allow emitting contracts in the private setup phase? // if so, this should only add contracts that were deployed during private app logic. - await this.publicContractsDB.addNewContracts(tx); + await this.worldStateDB.addNewContracts(tx); const { publicProvingInformation, kernelOutput, @@ -49,7 +48,7 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { } = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousCircuit).catch( // if we throw for any reason other than simulation, we need to rollback and drop the TX async err => { - await this.publicStateDB.rollbackToCommit(); + await this.worldStateDB.rollbackToCommit(); throw err; }, ); @@ -57,8 +56,8 @@ export class AppLogicPhaseManager extends AbstractPhaseManager { if (revertReason) { // TODO(#6464): Should we allow emitting contracts in the private setup phase? // if so, this is removing contracts deployed in private setup - await this.publicContractsDB.removeNewContracts(tx); - await this.publicStateDB.rollbackToCheckpoint(); + await this.worldStateDB.removeNewContracts(tx); + await this.worldStateDB.rollbackToCheckpoint(); tx.filterRevertedLogs(kernelOutput); } else { tx.unencryptedLogs.addFunctionLogs(newUnencryptedLogs); diff --git a/yarn-project/simulator/src/public/executor.ts b/yarn-project/simulator/src/public/executor.ts index f3a8a13ebceb..52f664df4361 100644 --- a/yarn-project/simulator/src/public/executor.ts +++ b/yarn-project/simulator/src/public/executor.ts @@ -9,11 +9,10 @@ import { AvmContext } from '../avm/avm_context.js'; import { AvmExecutionEnvironment } from '../avm/avm_execution_environment.js'; import { AvmMachineState } from '../avm/avm_machine_state.js'; import { AvmSimulator } from '../avm/avm_simulator.js'; -import { HostStorage } from '../avm/journal/host_storage.js'; import { AvmPersistableStateManager } from '../avm/journal/index.js'; -import { type CommitmentsDB, type PublicContractsDB, type PublicStateDB } from './db_interfaces.js'; import { type PublicExecutionResult } from './execution.js'; import { ExecutorMetrics } from './executor_metrics.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { PublicSideEffectTrace } from './side_effect_trace.js'; /** @@ -22,13 +21,7 @@ import { PublicSideEffectTrace } from './side_effect_trace.js'; export class PublicExecutor { metrics: ExecutorMetrics; - constructor( - private readonly publicStorageDB: PublicStateDB, - private readonly contractsDb: PublicContractsDB, - private readonly commitmentsDb: CommitmentsDB, - private readonly header: Header, - client: TelemetryClient, - ) { + constructor(private readonly worldStateDB: WorldStateDB, private readonly header: Header, client: TelemetryClient) { this.metrics = new ExecutorMetrics(client, 'PublicExecutor'); } @@ -56,15 +49,14 @@ export class PublicExecutor { ): Promise { const address = executionRequest.contractAddress; const selector = executionRequest.callContext.functionSelector; - const fnName = (await this.contractsDb.getDebugFunctionName(address, selector)) ?? `${address}:${selector}`; + const fnName = (await this.worldStateDB.getDebugFunctionName(address, selector)) ?? `${address}:${selector}`; PublicExecutor.log.verbose(`[AVM] Executing public external function ${fnName}.`); const timer = new Timer(); - const hostStorage = new HostStorage(this.publicStorageDB, this.contractsDb, this.commitmentsDb); const trace = new PublicSideEffectTrace(startSideEffectCounter); const avmPersistableState = AvmPersistableStateManager.newWithPendingSiloedNullifiers( - hostStorage, + this.worldStateDB, trace, pendingSiloedNullifiers.map(n => n.value), ); diff --git a/yarn-project/simulator/src/public/phase_manager_factory.ts b/yarn-project/simulator/src/public/phase_manager_factory.ts index 5a71ff748634..7c42be49b9b3 100644 --- a/yarn-project/simulator/src/public/phase_manager_factory.ts +++ b/yarn-project/simulator/src/public/phase_manager_factory.ts @@ -1,11 +1,11 @@ import { PublicKernelType, type Tx } from '@aztec/circuit-types'; import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; -import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; +import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { type AbstractPhaseManager } from './abstract_phase_manager.js'; import { AppLogicPhaseManager } from './app_logic_phase_manager.js'; -import { type ContractsDataSourcePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; import { SetupPhaseManager } from './setup_phase_manager.js'; import { TailPhaseManager } from './tail_phase_manager.js'; @@ -31,20 +31,11 @@ export class PhaseManagerFactory { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - publicContractsDB: ContractsDataSourcePublicDB, - publicStateDB: PublicStateDB, + worldStateDB: WorldStateDB, ): AbstractPhaseManager | undefined { const data = tx.data.forPublic!; if (data.needsSetup) { - return new SetupPhaseManager( - db, - publicExecutor, - publicKernel, - globalVariables, - historicalHeader, - publicContractsDB, - publicStateDB, - ); + return new SetupPhaseManager(db, publicExecutor, publicKernel, globalVariables, historicalHeader, worldStateDB); } else if (data.needsAppLogic) { return new AppLogicPhaseManager( db, @@ -52,8 +43,7 @@ export class PhaseManagerFactory { publicKernel, globalVariables, historicalHeader, - publicContractsDB, - publicStateDB, + worldStateDB, ); } else if (data.needsTeardown) { return new TeardownPhaseManager( @@ -62,8 +52,7 @@ export class PhaseManagerFactory { publicKernel, globalVariables, historicalHeader, - publicContractsDB, - publicStateDB, + worldStateDB, ); } else { return undefined; @@ -78,8 +67,7 @@ export class PhaseManagerFactory { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - publicContractsDB: ContractsDataSourcePublicDB, - publicStateDB: PublicStateDB, + worldStateDB: WorldStateDB, ): AbstractPhaseManager | undefined { if (output.needsSetup) { throw new CannotTransitionToSetupError(); @@ -93,8 +81,7 @@ export class PhaseManagerFactory { publicKernel, globalVariables, historicalHeader, - publicContractsDB, - publicStateDB, + worldStateDB, ); } else if (output.needsTeardown) { if (currentPhaseManager.phase === PublicKernelType.TEARDOWN) { @@ -106,19 +93,10 @@ export class PhaseManagerFactory { publicKernel, globalVariables, historicalHeader, - publicContractsDB, - publicStateDB, + worldStateDB, ); } else if (currentPhaseManager.phase !== PublicKernelType.TAIL) { - return new TailPhaseManager( - db, - publicExecutor, - publicKernel, - globalVariables, - historicalHeader, - publicContractsDB, - publicStateDB, - ); + return new TailPhaseManager(db, publicExecutor, publicKernel, globalVariables, historicalHeader, worldStateDB); } else { return undefined; } diff --git a/yarn-project/simulator/src/public/public_db_sources.test.ts b/yarn-project/simulator/src/public/public_db_sources.test.ts index d3a66358d1da..4880036b5a88 100644 --- a/yarn-project/simulator/src/public/public_db_sources.test.ts +++ b/yarn-project/simulator/src/public/public_db_sources.test.ts @@ -2,21 +2,25 @@ import { MerkleTreeId } from '@aztec/circuit-types'; import { AztecAddress, Fr, PublicDataTreeLeafPreimage } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash'; import { type IndexedTreeLeafPreimage } from '@aztec/foundation/trees'; +import { type ContractDataSource } from '@aztec/types/contracts'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { WorldStatePublicDB } from './public_db_sources.js'; +import { WorldStateDB } from './public_db_sources.js'; const DB_VALUES_SIZE = 10; describe('world_state_public_db', () => { let db: MockProxy; + const contractDataSource: MockProxy = mock(); let dbStorage: Map>; let addresses: AztecAddress[]; let slots: Fr[]; let dbValues: Fr[]; + let worldStateDB: WorldStateDB; + beforeEach(() => { addresses = Array(DB_VALUES_SIZE).fill(0).map(AztecAddress.random); slots = Array(DB_VALUES_SIZE).fill(0).map(Fr.random); @@ -68,153 +72,147 @@ describe('world_state_public_db', () => { return Promise.resolve(PublicDataTreeLeafPreimage.fromBuffer(tree.get(index)!)); }); + + worldStateDB = new WorldStateDB(db, contractDataSource); }); it('reads unwritten value from merkle tree db', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); - expect(await publicStateDb.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); }); it('reads uncommitted value back', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // should read back the uncommitted value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); // other slots should be unchanged - expect(await publicStateDb.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); + expect(await worldStateDB.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); }); it('reads committed value back', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // commit the data - await publicStateDb.commit(); + await worldStateDB.commit(); // should read back the committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); // other slots should be unchanged - expect(await publicStateDb.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); + expect(await worldStateDB.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); }); it('will not rollback a committed value', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // commit the data - await publicStateDb.commit(); + await worldStateDB.commit(); // should read back the committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); - await publicStateDb.rollbackToCommit(); + await worldStateDB.rollbackToCommit(); // should still read back the committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); }); it('reads original value if rolled back uncommitted value', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // should read back the uncommitted value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); // now rollback - await publicStateDb.rollbackToCommit(); + await worldStateDB.rollbackToCommit(); // should now read the original value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); }); it('reads newly uncommitted value back', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // commit the data - await publicStateDb.commit(); + await worldStateDB.commit(); // should read back the committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); // other slots should be unchanged - expect(await publicStateDb.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); + expect(await worldStateDB.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); // now update the slot again const newValue2 = new Fr(dbValues[0].toBigInt() + 2n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue2); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue2); // should read back the uncommitted value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue2); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue2); }); it('rolls back to previously committed value', async function () { - const publicStateDb = new WorldStatePublicDB(db); - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(dbValues[0]); const newValue = new Fr(dbValues[0].toBigInt() + 1n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue); // commit the data - await publicStateDb.commit(); + await worldStateDB.commit(); // should read back the committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); // other slots should be unchanged - expect(await publicStateDb.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); + expect(await worldStateDB.storageRead(addresses[1], slots[1])).toEqual(dbValues[1]); // now update the slot again const newValue2 = new Fr(dbValues[0].toBigInt() + 2n); // write a new value to our first value - await publicStateDb.storageWrite(addresses[0], slots[0], newValue2); + await worldStateDB.storageWrite(addresses[0], slots[0], newValue2); // should read back the uncommitted value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue2); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue2); // rollback - await publicStateDb.rollbackToCommit(); + await worldStateDB.rollbackToCommit(); // should read back the previously committed value - expect(await publicStateDb.storageRead(addresses[0], slots[0])).toEqual(newValue); + expect(await worldStateDB.storageRead(addresses[0], slots[0])).toEqual(newValue); }); it('can use checkpoints', async function () { - const publicStateDb = new WorldStatePublicDB(db); - const read = () => publicStateDb.storageRead(addresses[0], slots[0]); - const write = (value: Fr) => publicStateDb.storageWrite(addresses[0], slots[0], value); + const read = () => worldStateDB.storageRead(addresses[0], slots[0]); + const write = (value: Fr) => worldStateDB.storageWrite(addresses[0], slots[0], value); const newValue = new Fr(dbValues[0].toBigInt() + 1n); const newValue2 = new Fr(dbValues[0].toBigInt() + 2n); @@ -226,32 +224,32 @@ describe('world_state_public_db', () => { // basic expect(await read()).toEqual(dbValues[0]); await write(newValue); - await publicStateDb.checkpoint(); + await worldStateDB.checkpoint(); await write(newValue2); - await publicStateDb.rollbackToCheckpoint(); + await worldStateDB.rollbackToCheckpoint(); expect(await read()).toEqual(newValue); - await publicStateDb.rollbackToCommit(); + await worldStateDB.rollbackToCommit(); expect(await read()).toEqual(dbValues[0]); // write, checkpoint, commit, rollback to checkpoint, rollback to commit await write(newValue3); - await publicStateDb.checkpoint(); - await publicStateDb.rollbackToCheckpoint(); + await worldStateDB.checkpoint(); + await worldStateDB.rollbackToCheckpoint(); expect(await read()).toEqual(newValue3); - await publicStateDb.commit(); - await publicStateDb.rollbackToCommit(); + await worldStateDB.commit(); + await worldStateDB.rollbackToCommit(); expect(await read()).toEqual(newValue3); // writes after checkpoint take precedence await write(newValue4); - await publicStateDb.checkpoint(); + await worldStateDB.checkpoint(); await write(newValue5); - await publicStateDb.commit(); + await worldStateDB.commit(); expect(await read()).toEqual(newValue5); // rollback to checkpoint does not cross commit boundaries await write(newValue6); - await publicStateDb.rollbackToCheckpoint(); + await worldStateDB.rollbackToCheckpoint(); expect(await read()).toEqual(newValue5); }); }); diff --git a/yarn-project/simulator/src/public/public_db_sources.ts b/yarn-project/simulator/src/public/public_db_sources.ts index 662ccae10c3a..745f9bfe550f 100644 --- a/yarn-project/simulator/src/public/public_db_sources.ts +++ b/yarn-project/simulator/src/public/public_db_sources.ts @@ -38,7 +38,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { private log = createDebugLogger('aztec:sequencer:contracts-data-source'); - constructor(private db: ContractDataSource) {} + constructor(private dataSource: ContractDataSource) {} /** * Add new contracts from a transaction @@ -78,11 +78,11 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { } public async getContractInstance(address: AztecAddress): Promise { - return this.instanceCache.get(address.toString()) ?? (await this.db.getContract(address)); + return this.instanceCache.get(address.toString()) ?? (await this.dataSource.getContract(address)); } public async getContractClass(contractClassId: Fr): Promise { - return this.classCache.get(contractClassId.toString()) ?? (await this.db.getContractClass(contractClassId)); + return this.classCache.get(contractClassId.toString()) ?? (await this.dataSource.getContractClass(contractClassId)); } async getBytecode(address: AztecAddress, selector: FunctionSelector): Promise { @@ -98,7 +98,7 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { } public async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise { - const artifact = await this.db.getContractArtifact(address); + const artifact = await this.dataSource.getContractArtifact(address); if (!artifact) { return Promise.resolve(undefined); } @@ -115,14 +115,18 @@ export class ContractsDataSourcePublicDB implements PublicContractsDB { } /** - * Implements the PublicStateDB using a world-state database. + * A public state DB that reads and writes to the world state. */ -export class WorldStatePublicDB implements PublicStateDB { - private committedWriteCache: Map = new Map(); - private checkpointedWriteCache: Map = new Map(); - private uncommittedWriteCache: Map = new Map(); +export class WorldStateDB extends ContractsDataSourcePublicDB implements PublicStateDB, CommitmentsDB { + private logger = createDebugLogger('aztec:sequencer:world-state-db'); - constructor(private db: MerkleTreeOperations) {} + private publicCommittedWriteCache: Map = new Map(); + private publicCheckpointedWriteCache: Map = new Map(); + private publicUncommittedWriteCache: Map = new Map(); + + constructor(private db: MerkleTreeOperations, dataSource: ContractDataSource) { + super(dataSource); + } /** * Reads a value from public storage, returning zero if none. @@ -132,15 +136,15 @@ export class WorldStatePublicDB implements PublicStateDB { */ public async storageRead(contract: AztecAddress, slot: Fr): Promise { const leafSlot = computePublicDataTreeLeafSlot(contract, slot).value; - const uncommitted = this.uncommittedWriteCache.get(leafSlot); + const uncommitted = this.publicUncommittedWriteCache.get(leafSlot); if (uncommitted !== undefined) { return uncommitted; } - const checkpointed = this.checkpointedWriteCache.get(leafSlot); + const checkpointed = this.publicCheckpointedWriteCache.get(leafSlot); if (checkpointed !== undefined) { return checkpointed; } - const committed = this.committedWriteCache.get(leafSlot); + const committed = this.publicCommittedWriteCache.get(leafSlot); if (committed !== undefined) { return committed; } @@ -167,57 +171,10 @@ export class WorldStatePublicDB implements PublicStateDB { */ public storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise { const index = computePublicDataTreeLeafSlot(contract, slot).value; - this.uncommittedWriteCache.set(index, newValue); + this.publicUncommittedWriteCache.set(index, newValue); return Promise.resolve(index); } - /** - * Commit the pending changes to the DB. - * @returns Nothing. - */ - commit(): Promise { - for (const [k, v] of this.checkpointedWriteCache) { - this.committedWriteCache.set(k, v); - } - // uncommitted writes take precedence over checkpointed writes - // since they are the most recent - for (const [k, v] of this.uncommittedWriteCache) { - this.committedWriteCache.set(k, v); - } - return this.rollbackToCommit(); - } - - /** - * Rollback the pending changes. - * @returns Nothing. - */ - async rollbackToCommit(): Promise { - await this.rollbackToCheckpoint(); - this.checkpointedWriteCache = new Map(); - return Promise.resolve(); - } - - checkpoint(): Promise { - for (const [k, v] of this.uncommittedWriteCache) { - this.checkpointedWriteCache.set(k, v); - } - return this.rollbackToCheckpoint(); - } - - rollbackToCheckpoint(): Promise { - this.uncommittedWriteCache = new Map(); - return Promise.resolve(); - } -} - -/** - * Implements WorldState db using a world state database. - */ -export class WorldStateDB implements CommitmentsDB { - private log = createDebugLogger('aztec:sequencer:world-state-db'); - - constructor(private db: MerkleTreeOperations) {} - public async getNullifierMembershipWitnessAtLatestBlock( nullifier: Fr, ): Promise { @@ -239,7 +196,7 @@ export class WorldStateDB implements CommitmentsDB { return undefined; } - this.log.debug(`[DB] Fetched nullifier membership`, { + this.logger.debug(`[DB] Fetched nullifier membership`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-nullifier-membership-witness-at-latest-block', @@ -277,7 +234,7 @@ export class WorldStateDB implements CommitmentsDB { messageIndex, ); - this.log.debug(`[DB] Fetched L1 to L2 message membership`, { + this.logger.debug(`[DB] Fetched L1 to L2 message membership`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-l1-to-l2-message-membership-witness', @@ -289,7 +246,7 @@ export class WorldStateDB implements CommitmentsDB { public async getL1ToL2LeafValue(leafIndex: bigint): Promise { const timer = new Timer(); const leafValue = await this.db.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex); - this.log.debug(`[DB] Fetched L1 to L2 message leaf value`, { + this.logger.debug(`[DB] Fetched L1 to L2 message leaf value`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-l1-to-l2-message-leaf-value', @@ -300,7 +257,7 @@ export class WorldStateDB implements CommitmentsDB { public async getCommitmentIndex(commitment: Fr): Promise { const timer = new Timer(); const index = await this.db.findLeafIndex(MerkleTreeId.NOTE_HASH_TREE, commitment); - this.log.debug(`[DB] Fetched commitment index`, { + this.logger.debug(`[DB] Fetched commitment index`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-commitment-index', @@ -311,7 +268,7 @@ export class WorldStateDB implements CommitmentsDB { public async getCommitmentValue(leafIndex: bigint): Promise { const timer = new Timer(); const leafValue = await this.db.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex); - this.log.debug(`[DB] Fetched commitment leaf value`, { + this.logger.debug(`[DB] Fetched commitment leaf value`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-commitment-leaf-value', @@ -322,11 +279,49 @@ export class WorldStateDB implements CommitmentsDB { public async getNullifierIndex(nullifier: Fr): Promise { const timer = new Timer(); const index = await this.db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer()); - this.log.debug(`[DB] Fetched nullifier index`, { + this.logger.debug(`[DB] Fetched nullifier index`, { eventName: 'public-db-access', duration: timer.ms(), operation: 'get-nullifier-index', } satisfies PublicDBAccessStats); return index; } + + /** + * Commit the pending public changes to the DB. + * @returns Nothing. + */ + commit(): Promise { + for (const [k, v] of this.publicCheckpointedWriteCache) { + this.publicCommittedWriteCache.set(k, v); + } + // uncommitted writes take precedence over checkpointed writes + // since they are the most recent + for (const [k, v] of this.publicUncommittedWriteCache) { + this.publicCommittedWriteCache.set(k, v); + } + return this.rollbackToCommit(); + } + + /** + * Rollback the pending public changes. + * @returns Nothing. + */ + async rollbackToCommit(): Promise { + await this.rollbackToCheckpoint(); + this.publicCheckpointedWriteCache = new Map(); + return Promise.resolve(); + } + + checkpoint(): Promise { + for (const [k, v] of this.publicUncommittedWriteCache) { + this.publicCheckpointedWriteCache.set(k, v); + } + return this.rollbackToCheckpoint(); + } + + rollbackToCheckpoint(): Promise { + this.publicUncommittedWriteCache = new Map(); + return Promise.resolve(); + } } diff --git a/yarn-project/simulator/src/public/public_processor.test.ts b/yarn-project/simulator/src/public/public_processor.test.ts index 7778147a3ef0..5558997ab9cc 100644 --- a/yarn-project/simulator/src/public/public_processor.test.ts +++ b/yarn-project/simulator/src/public/public_processor.test.ts @@ -50,7 +50,7 @@ import { jest } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; import { PublicExecutionResultBuilder, makeFunctionCall } from '../mocks/fixtures.js'; -import { type ContractsDataSourcePublicDB, type WorldStatePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { RealPublicKernelCircuitSimulator } from './public_kernel.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; import { PublicProcessor } from './public_processor.js'; @@ -58,8 +58,7 @@ import { PublicProcessor } from './public_processor.js'; describe('public_processor', () => { let db: MockProxy; let publicExecutor: MockProxy; - let publicContractsDB: MockProxy; - let publicWorldStateDB: MockProxy; + let worldStateDB: MockProxy; let prover: MockProxy; let proof: ClientIvcProof; @@ -70,15 +69,14 @@ describe('public_processor', () => { beforeEach(() => { db = mock(); publicExecutor = mock(); - publicContractsDB = mock(); - publicWorldStateDB = mock(); + worldStateDB = mock(); prover = mock(); proof = ClientIvcProof.empty(); root = Buffer.alloc(32, 5); db.getTreeInfo.mockResolvedValue({ root } as TreeInfo); - publicWorldStateDB.storageRead.mockResolvedValue(Fr.ZERO); + worldStateDB.storageRead.mockResolvedValue(Fr.ZERO); }); describe('with mock circuits', () => { @@ -92,8 +90,7 @@ describe('public_processor', () => { publicKernel, GlobalVariables.empty(), Header.empty(), - publicContractsDB, - publicWorldStateDB, + worldStateDB, new NoopTelemetryClient(), ); }); @@ -138,8 +135,8 @@ describe('public_processor', () => { expect(processed).toEqual([]); expect(failed[0].tx).toEqual(tx); expect(failed[0].error).toEqual(new SimulationError(`Failed`, [])); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(0); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(1); expect(prover.addNewTx).toHaveBeenCalledTimes(0); }); }); @@ -191,8 +188,7 @@ describe('public_processor', () => { publicKernel, GlobalVariables.from({ ...GlobalVariables.empty(), gasFees: GasFees.default() }), header, - publicContractsDB, - publicWorldStateDB, + worldStateDB, new NoopTelemetryClient(), ); }); @@ -211,8 +207,8 @@ describe('public_processor', () => { expect(processed[0].hash).toEqual(tx.getTxHash()); expect(processed[0].clientIvcProof).toEqual(proof); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); // we keep the logs expect(processed[0].encryptedLogs.getTotalLogCount()).toBe(6); @@ -245,10 +241,10 @@ describe('public_processor', () => { expect(failed).toHaveLength(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(1); // we only call checkpoint after successful "setup" - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(0); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); expect(prover.addNewTx).toHaveBeenCalledWith(processed[0]); }); @@ -268,8 +264,8 @@ describe('public_processor', () => { expect(processed[1].clientIvcProof).toEqual(proof); expect(failed).toHaveLength(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(2); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); expect(prover.addNewTx).toHaveBeenCalledWith(processed[0]); expect(prover.addNewTx).toHaveBeenCalledWith(processed[1]); @@ -383,10 +379,10 @@ describe('public_processor', () => { expect(appLogicSpy).toHaveBeenCalledTimes(2); expect(teardownSpy).toHaveBeenCalledTimes(2); expect(publicExecutor.simulate).toHaveBeenCalledTimes(3); - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); const txEffect = toTxEffect(processed[0], GasFees.default()); const numPublicDataWrites = 5; @@ -490,10 +486,10 @@ describe('public_processor', () => { expect(teardownSpy).toHaveBeenCalledTimes(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(1); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(0); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(0); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(1); expect(prover.addNewTx).toHaveBeenCalledTimes(0); }); @@ -587,10 +583,10 @@ describe('public_processor', () => { expect(appLogicSpy).toHaveBeenCalledTimes(1); expect(teardownSpy).toHaveBeenCalledTimes(2); expect(publicExecutor.simulate).toHaveBeenCalledTimes(3); - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); const txEffect = toTxEffect(processed[0], GasFees.default()); const numPublicDataWrites = 3; @@ -703,10 +699,10 @@ describe('public_processor', () => { expect(appLogicSpy).toHaveBeenCalledTimes(1); expect(teardownSpy).toHaveBeenCalledTimes(2); expect(publicExecutor.simulate).toHaveBeenCalledTimes(3); - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(2); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); const txEffect = toTxEffect(processed[0], GasFees.default()); const numPublicDataWrites = 3; @@ -873,10 +869,10 @@ describe('public_processor', () => { expect(publicExecutor.simulate).toHaveBeenNthCalledWith(2, ...expectedSimulateCall(afterSetupGas, 0)); expect(publicExecutor.simulate).toHaveBeenNthCalledWith(3, ...expectedSimulateCall(teardownGas, expectedTxFee)); - expect(publicWorldStateDB.checkpoint).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.checkpoint).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCheckpoint).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); expect(processed[0].data.end.gasUsed).toEqual(Gas.from(expectedTotalGasUsed)); expect(processed[0].gasUsed[PublicKernelType.SETUP]).toEqual(setupGasUsed); @@ -988,8 +984,8 @@ describe('public_processor', () => { inclusionFee: new Fr(inclusionFee), }); - publicWorldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); - publicWorldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => + worldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); + worldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => Promise.resolve(computePublicDataTreeLeafSlot(address, slot).toBigInt()), ); @@ -998,9 +994,9 @@ describe('public_processor', () => { expect(failed.map(f => f.error)).toEqual([]); expect(processed).toHaveLength(1); expect(publicExecutor.simulate).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.storageWrite).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.storageWrite).toHaveBeenCalledTimes(1); expect(processed[0].data.feePayer).toEqual(feePayer); expect(processed[0].finalPublicDataUpdateRequests[MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]).toEqual( PublicDataUpdateRequest.from({ @@ -1028,8 +1024,8 @@ describe('public_processor', () => { inclusionFee: new Fr(inclusionFee), }); - publicWorldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); - publicWorldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => + worldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); + worldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => Promise.resolve(computePublicDataTreeLeafSlot(address, slot).toBigInt()), ); @@ -1040,9 +1036,9 @@ describe('public_processor', () => { expect(processed[0].hash).toEqual(tx.getTxHash()); expect(processed[0].clientIvcProof).toEqual(proof); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.storageWrite).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.storageWrite).toHaveBeenCalledTimes(1); expect(processed[0].data.feePayer).toEqual(feePayer); expect(processed[0].finalPublicDataUpdateRequests[MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]).toEqual( PublicDataUpdateRequest.from({ @@ -1070,8 +1066,8 @@ describe('public_processor', () => { inclusionFee: new Fr(inclusionFee), }); - publicWorldStateDB.storageRead.mockResolvedValue(Fr.ZERO); - publicWorldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => + worldStateDB.storageRead.mockResolvedValue(Fr.ZERO); + worldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => Promise.resolve(computePublicDataTreeLeafSlot(address, slot).toBigInt()), ); @@ -1088,9 +1084,9 @@ describe('public_processor', () => { expect(processed[0].hash).toEqual(tx.getTxHash()); expect(processed[0].clientIvcProof).toEqual(proof); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.storageWrite).toHaveBeenCalledTimes(1); + expect(worldStateDB.commit).toHaveBeenCalledTimes(1); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.storageWrite).toHaveBeenCalledTimes(1); expect(processed[0].data.feePayer).toEqual(feePayer); expect(processed[0].finalPublicDataUpdateRequests[0]).toEqual( PublicDataUpdateRequest.from({ @@ -1118,8 +1114,8 @@ describe('public_processor', () => { inclusionFee: new Fr(inclusionFee), }); - publicWorldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); - publicWorldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => + worldStateDB.storageRead.mockResolvedValue(new Fr(initialBalance)); + worldStateDB.storageWrite.mockImplementation((address: AztecAddress, slot: Fr) => Promise.resolve(computePublicDataTreeLeafSlot(address, slot).toBigInt()), ); @@ -1129,9 +1125,9 @@ describe('public_processor', () => { expect(failed).toHaveLength(1); expect(failed[0].error.message).toMatch(/Not enough balance/i); expect(publicExecutor.simulate).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); - expect(publicWorldStateDB.storageWrite).toHaveBeenCalledTimes(0); + expect(worldStateDB.commit).toHaveBeenCalledTimes(0); + expect(worldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); + expect(worldStateDB.storageWrite).toHaveBeenCalledTimes(0); }); }); }); diff --git a/yarn-project/simulator/src/public/public_processor.ts b/yarn-project/simulator/src/public/public_processor.ts index 84cffb190f05..0e36df968c12 100644 --- a/yarn-project/simulator/src/public/public_processor.ts +++ b/yarn-project/simulator/src/public/public_processor.ts @@ -29,7 +29,6 @@ import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer'; import { PublicExecutor, - type PublicStateDB, type SimulationProvider, computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot, @@ -40,7 +39,7 @@ import { type MerkleTreeOperations } from '@aztec/world-state'; import { type AbstractPhaseManager } from './abstract_phase_manager.js'; import { PhaseManagerFactory } from './phase_manager_factory.js'; -import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from './public_db_sources.js'; +import { WorldStateDB } from './public_db_sources.js'; import { RealPublicKernelCircuitSimulator } from './public_kernel.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; import { PublicProcessorMetrics } from './public_processor_metrics.js'; @@ -65,25 +64,16 @@ export class PublicProcessorFactory { public create(maybeHistoricalHeader: Header | undefined, globalVariables: GlobalVariables): PublicProcessor { const { merkleTree, telemetryClient } = this; const historicalHeader = maybeHistoricalHeader ?? merkleTree.getInitialHeader(); - const publicContractsDB = new ContractsDataSourcePublicDB(this.contractDataSource); - const worldStatePublicDB = new WorldStatePublicDB(merkleTree); - const worldStateDB = new WorldStateDB(merkleTree); - const publicExecutor = new PublicExecutor( - worldStatePublicDB, - publicContractsDB, - worldStateDB, - historicalHeader, - telemetryClient, - ); + const worldStateDB = new WorldStateDB(merkleTree, this.contractDataSource); + const publicExecutor = new PublicExecutor(worldStateDB, historicalHeader, telemetryClient); return new PublicProcessor( merkleTree, publicExecutor, new RealPublicKernelCircuitSimulator(this.simulator), globalVariables, historicalHeader, - publicContractsDB, - worldStatePublicDB, + worldStateDB, this.telemetryClient, ); } @@ -101,8 +91,7 @@ export class PublicProcessor { protected publicKernel: PublicKernelCircuitSimulator, protected globalVariables: GlobalVariables, protected historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, + protected worldStateDB: WorldStateDB, telemetryClient: TelemetryClient, private log = createDebugLogger('aztec:sequencer:public-processor'), ) { @@ -151,7 +140,7 @@ export class PublicProcessor { processedTx.finalPublicDataUpdateRequests = await this.createFinalDataUpdateRequests(processedTx); // Commit the state updates from this transaction - await this.publicStateDB.commit(); + await this.worldStateDB.commit(); validateProcessedTx(processedTx); // Re-validate the transaction @@ -217,14 +206,14 @@ export class PublicProcessor { const balance = existingBalanceWriteIndex > -1 ? finalPublicDataUpdateRequests[existingBalanceWriteIndex].newValue - : await this.publicStateDB.storageRead(feeJuiceAddress, balanceSlot); + : await this.worldStateDB.storageRead(feeJuiceAddress, balanceSlot); if (balance.lt(txFee)) { throw new Error(`Not enough balance for fee payer to pay for transaction (got ${balance} needs ${txFee})`); } const updatedBalance = balance.sub(txFee); - await this.publicStateDB.storageWrite(feeJuiceAddress, balanceSlot, updatedBalance); + await this.worldStateDB.storageWrite(feeJuiceAddress, balanceSlot, updatedBalance); finalPublicDataUpdateRequests[ existingBalanceWriteIndex > -1 ? existingBalanceWriteIndex : MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX @@ -247,10 +236,10 @@ export class PublicProcessor { this.publicKernel, this.globalVariables, this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, + this.worldStateDB, ); this.log.debug(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`); + let publicKernelPublicInput = tx.data.toPublicKernelCircuitPublicInputs(); let lastKernelArtifact: ProtocolArtifact = 'PrivateKernelTailToPublicArtifact'; // All txs with public calls must carry tail to public proofs let finalKernelOutput: KernelCircuitPublicInputs | undefined; @@ -285,8 +274,7 @@ export class PublicProcessor { this.publicKernel, this.globalVariables, this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, + this.worldStateDB, ); } diff --git a/yarn-project/simulator/src/public/setup_phase_manager.test.ts b/yarn-project/simulator/src/public/setup_phase_manager.test.ts index a765c59e9849..58333097a03b 100644 --- a/yarn-project/simulator/src/public/setup_phase_manager.test.ts +++ b/yarn-project/simulator/src/public/setup_phase_manager.test.ts @@ -6,7 +6,7 @@ import { type MerkleTreeOperations } from '@aztec/world-state'; import { it } from '@jest/globals'; import { type MockProxy, mock } from 'jest-mock-extended'; -import { type ContractsDataSourcePublicDB, type WorldStatePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; import { SetupPhaseManager } from './setup_phase_manager.js'; @@ -19,8 +19,7 @@ class TestSetupPhaseManager extends SetupPhaseManager { describe('setup_phase_manager', () => { let db: MockProxy; let publicExecutor: MockProxy; - let publicContractsDB: MockProxy; - let publicWorldStateDB: MockProxy; + let worldStateDB: MockProxy; let publicKernel: MockProxy; let root: Buffer; @@ -30,8 +29,7 @@ describe('setup_phase_manager', () => { beforeEach(() => { db = mock(); publicExecutor = mock(); - publicContractsDB = mock(); - publicWorldStateDB = mock(); + worldStateDB = mock(); root = Buffer.alloc(32, 5); db.getTreeInfo.mockResolvedValue({ root } as TreeInfo); @@ -42,8 +40,7 @@ describe('setup_phase_manager', () => { publicKernel, GlobalVariables.empty(), Header.empty(), - publicContractsDB, - publicWorldStateDB, + worldStateDB, ); }); diff --git a/yarn-project/simulator/src/public/setup_phase_manager.ts b/yarn-project/simulator/src/public/setup_phase_manager.ts index 2e40f0ffeb0d..4fd1d02986ba 100644 --- a/yarn-project/simulator/src/public/setup_phase_manager.ts +++ b/yarn-project/simulator/src/public/setup_phase_manager.ts @@ -1,11 +1,11 @@ import { PublicKernelType, type PublicProvingRequest, type Tx } from '@aztec/circuit-types'; import { type GlobalVariables, type Header, type PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; +import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { AbstractPhaseManager, makeAvmProvingRequest } from './abstract_phase_manager.js'; -import { type ContractsDataSourcePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; /** @@ -18,8 +18,7 @@ export class SetupPhaseManager extends AbstractPhaseManager { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, + protected worldStateDB: WorldStateDB, phase: PublicKernelType = PublicKernelType.SETUP, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); @@ -33,17 +32,17 @@ export class SetupPhaseManager extends AbstractPhaseManager { this.log.verbose(`Processing tx ${tx.getTxHash()}`); // TODO(#6464): Should we allow emitting contracts in the private setup phase? // if so, this should only add contracts that were deployed during private app logic. - await this.publicContractsDB.addNewContracts(tx); + await this.worldStateDB.addNewContracts(tx); const { publicProvingInformation, kernelOutput, lastKernelArtifact, newUnencryptedLogs, revertReason, gasUsed } = await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousCircuit).catch( // the abstract phase manager throws if simulation gives error in a non-revertible phase async err => { - await this.publicStateDB.rollbackToCommit(); + await this.worldStateDB.rollbackToCommit(); throw err; }, ); tx.unencryptedLogs.addFunctionLogs(newUnencryptedLogs); - await this.publicStateDB.checkpoint(); + await this.worldStateDB.checkpoint(); // Return a list of setup proving requests const publicProvingRequests: PublicProvingRequest[] = publicProvingInformation.map(info => { diff --git a/yarn-project/simulator/src/public/tail_phase_manager.ts b/yarn-project/simulator/src/public/tail_phase_manager.ts index 08b0916d30cd..19de912dd19d 100644 --- a/yarn-project/simulator/src/public/tail_phase_manager.ts +++ b/yarn-project/simulator/src/public/tail_phase_manager.ts @@ -10,11 +10,11 @@ import { mergeAccumulatedData, } from '@aztec/circuits.js'; import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; +import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { AbstractPhaseManager } from './abstract_phase_manager.js'; -import { type ContractsDataSourcePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; export class TailPhaseManager extends AbstractPhaseManager { @@ -24,8 +24,7 @@ export class TailPhaseManager extends AbstractPhaseManager { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, + protected worldStateDB: WorldStateDB, phase: PublicKernelType = PublicKernelType.TAIL, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); @@ -40,7 +39,7 @@ export class TailPhaseManager extends AbstractPhaseManager { const [inputs, finalKernelOutput] = await this.simulate(previousPublicKernelOutput, previousKernelArtifact).catch( // the abstract phase manager throws if simulation gives error in non-revertible phase async err => { - await this.publicStateDB.rollbackToCommit(); + await this.worldStateDB.rollbackToCommit(); throw err; }, ); diff --git a/yarn-project/simulator/src/public/teardown_phase_manager.ts b/yarn-project/simulator/src/public/teardown_phase_manager.ts index 03401e33dbb1..85ba32ebd8db 100644 --- a/yarn-project/simulator/src/public/teardown_phase_manager.ts +++ b/yarn-project/simulator/src/public/teardown_phase_manager.ts @@ -7,13 +7,13 @@ import { type PublicKernelCircuitPublicInputs, } from '@aztec/circuits.js'; import { type ProtocolArtifact } from '@aztec/noir-protocol-circuits-types'; -import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; +import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; import { inspect } from 'util'; import { AbstractPhaseManager, makeAvmProvingRequest } from './abstract_phase_manager.js'; -import { type ContractsDataSourcePublicDB } from './public_db_sources.js'; +import { type WorldStateDB } from './public_db_sources.js'; import { type PublicKernelCircuitSimulator } from './public_kernel_circuit_simulator.js'; /** @@ -26,8 +26,7 @@ export class TeardownPhaseManager extends AbstractPhaseManager { publicKernel: PublicKernelCircuitSimulator, globalVariables: GlobalVariables, historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, + protected worldStateDB: WorldStateDB, phase: PublicKernelType = PublicKernelType.TEARDOWN, ) { super(db, publicExecutor, publicKernel, globalVariables, historicalHeader, phase); @@ -43,12 +42,12 @@ export class TeardownPhaseManager extends AbstractPhaseManager { await this.processEnqueuedPublicCalls(tx, previousPublicKernelOutput, previousKernelArtifact).catch( // the abstract phase manager throws if simulation gives error in a non-revertible phase async err => { - await this.publicStateDB.rollbackToCommit(); + await this.worldStateDB.rollbackToCommit(); throw err; }, ); if (revertReason) { - await this.publicStateDB.rollbackToCheckpoint(); + await this.worldStateDB.rollbackToCheckpoint(); tx.filterRevertedLogs(kernelOutput); } else { // TODO(#6464): Should we allow emitting contracts in the public teardown phase? diff --git a/yarn-project/txe/src/oracle/txe_oracle.ts b/yarn-project/txe/src/oracle/txe_oracle.ts index 93a8bcc59f26..cccf85cef4a5 100644 --- a/yarn-project/txe/src/oracle/txe_oracle.ts +++ b/yarn-project/txe/src/oracle/txe_oracle.ts @@ -51,7 +51,6 @@ import { Timer } from '@aztec/foundation/timer'; import { type KeyStore } from '@aztec/key-store'; import { ContractDataOracle } from '@aztec/pxe'; import { - ContractsDataSourcePublicDB, ExecutionError, type ExecutionNoteCache, type MessageLoadOracleInputs, @@ -74,7 +73,6 @@ import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/wor import { type TXEDatabase } from '../util/txe_database.js'; import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js'; -import { TXEPublicStateDB } from '../util/txe_public_state_db.js'; export class TXE implements TypedOracle { private blockNumber = 0; @@ -717,10 +715,9 @@ export class TXE implements TypedOracle { const header = Header.empty(); header.state = await this.trees.getStateReference(true); header.globalVariables.blockNumber = new Fr(await this.getBlockNumber()); + const executor = new PublicExecutor( - new TXEPublicStateDB(this), - new ContractsDataSourcePublicDB(new TXEPublicContractDataSource(this)), - new WorldStateDB(this.trees.asLatest()), + new WorldStateDB(this.trees.asLatest(), new TXEPublicContractDataSource(this)), header, new NoopTelemetryClient(), );