diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts index eab46862b80..249ae57b0bb 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts @@ -1,4 +1,6 @@ -import { Fr } from '@aztec/circuits.js'; +import { AztecAddress, Fr, PrivateKey } from '@aztec/circuits.js'; +import { Grumpkin } from '@aztec/circuits.js/barretenberg'; +import { TestKeyStore } from '@aztec/key-store'; import { AztecNode, L2Block, MerkleTreeId } from '@aztec/types'; import { MockProxy, mock } from 'jest-mock-extended'; @@ -83,6 +85,37 @@ describe('Synchroniser', () => { expect(roots5[MerkleTreeId.CONTRACT_TREE]).not.toEqual(roots[MerkleTreeId.CONTRACT_TREE]); expect(roots5[MerkleTreeId.CONTRACT_TREE]).toEqual(block5.endContractTreeSnapshot.root); }); + + it('note processor successfully catches up', async () => { + const block = L2Block.random(1, 4); + + // getBlocks is called by both synchroniser.work and synchroniser.workNoteProcessorCatchUp + aztecNode.getBlocks.mockResolvedValue([L2Block.fromFields(omit(block, 'newEncryptedLogs', 'newUnencryptedLogs'))]); + aztecNode.getLogs + .mockResolvedValueOnce([block.newEncryptedLogs!]) // called by synchroniser.work + .mockResolvedValueOnce([block.newUnencryptedLogs!]) // called by synchroniser.work + .mockResolvedValueOnce([block.newEncryptedLogs!]); // called by synchroniser.workNoteProcessorCatchUp + + // Sync the synchroniser so that note processor has something to catch up to + await synchroniser.work(); + + // Used in synchroniser.isAccountSynchronised + aztecNode.getBlockHeight.mockResolvedValueOnce(1); + + // Manually adding account to database so that we can call synchroniser.isAccountSynchronised + const keyStore = new TestKeyStore(await Grumpkin.new()); + keyStore.addAccount(PrivateKey.random()); + const pubKey = (await keyStore.getAccounts())[0]; + const address = AztecAddress.random(); + await database.addPublicKeyAndPartialAddress(address, pubKey, new Fr(0)); + + // Add the account which will add the note processor to the synchroniser + synchroniser.addAccount(pubKey, keyStore); + + await synchroniser.workNoteProcessorCatchUp(); + + expect(await synchroniser.isAccountSynchronised(address)).toBe(true); + }); }); class TestSynchroniser extends Synchroniser { @@ -93,4 +126,8 @@ class TestSynchroniser extends Synchroniser { public initialSync(): Promise { return super.initialSync(); } + + public workNoteProcessorCatchUp(): Promise { + return super.workNoteProcessorCatchUp(); + } } diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts index ab74fd3ccbb..3230d9501f8 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.ts @@ -134,7 +134,7 @@ export class Synchroniser { } } - private async workNoteProcessorCatchUp(limit = 1, retryInterval = 1000): Promise { + protected async workNoteProcessorCatchUp(limit = 1, retryInterval = 1000): Promise { const noteProcessor = this.noteProcessorsToCatchUp[0]; const from = noteProcessor.status.syncedToBlock + 1; // Ensuring that the note processor does not sync further than the main sync.