diff --git a/dist/cli.js b/dist/cli.js index ed54605..0d5b4b3 100644 --- a/dist/cli.js +++ b/dist/cli.js @@ -182300,7 +182300,8 @@ class BaseEventsService { }; } // eslint-disable-next-line @typescript-eslint/no-unused-vars - validateEvents({ events, lastBlock }) { + async validateEvents({ events, lastBlock }) { + return void 0; } /** * Handle saving events @@ -182331,29 +182332,32 @@ class BaseEventsService { return !hasEvent; }); const lastBlock = newEvents.lastBlock || allEvents[allEvents.length - 1]?.blockNumber; - this.validateEvents({ events: allEvents, lastBlock }); + const validateResult = await this.validateEvents({ events: allEvents, lastBlock }); if (savedEvents.fromCache || newEvents.events.length) { await this.saveEvents({ events: allEvents, lastBlock }); } return { events: allEvents, - lastBlock + lastBlock, + validateResult }; } } class BaseTornadoService extends BaseEventsService { amount; currency; + merkleTreeService; batchTransactionService; batchBlockService; constructor(serviceConstructor) { - const { Tornado: contract, amount, currency, provider } = serviceConstructor; + const { Tornado: contract, amount, currency, provider, merkleTreeService } = serviceConstructor; super({ ...serviceConstructor, contract }); this.amount = amount; this.currency = currency; + this.merkleTreeService = merkleTreeService; this.batchTransactionService = new BatchTransactionService({ provider, onProgress: this.updateTransactionProgress @@ -182427,14 +182431,19 @@ class BaseTornadoService extends BaseEventsService { }); } } - validateEvents({ events }) { + async validateEvents({ events }) { if (events.length && this.getType().toLowerCase() === DEPOSIT) { - const lastEvent = events[events.length - 1]; - if (lastEvent.leafIndex !== events.length - 1) { - const errMsg = `Deposit events invalid wants ${events.length - 1} leafIndex have ${lastEvent.leafIndex}`; + const depositEvents = events; + const lastEvent = depositEvents[depositEvents.length - 1]; + if (lastEvent.leafIndex !== depositEvents.length - 1) { + const errMsg = `Deposit events invalid wants ${depositEvents.length - 1} leafIndex have ${lastEvent.leafIndex}`; throw new Error(errMsg); } + if (this.merkleTreeService) { + return await this.merkleTreeService.verifyTree(depositEvents); + } } + return void 0; } async getLatestEvents({ fromBlock }) { if (this.tovarishClient?.selectedRelayer) { @@ -183142,6 +183151,134 @@ class DBTornadoService extends BaseTornadoService { }); } } +class DBEchoService extends BaseEchoService { + staticUrl; + idb; + zipDigest; + constructor(params) { + super(params); + this.staticUrl = params.staticUrl; + this.idb = params.idb; + } + async getEventsFromDB() { + return await loadDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName() + }); + } + async getEventsFromCache() { + return await loadRemoteEvents({ + staticUrl: this.staticUrl, + instanceName: this.getInstanceName(), + deployedBlock: this.deployedBlock, + zipDigest: this.zipDigest + }); + } + async saveEvents({ events, lastBlock }) { + await saveDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName(), + events, + lastBlock + }); + } +} +class DBEncryptedNotesService extends BaseEncryptedNotesService { + staticUrl; + idb; + zipDigest; + constructor(params) { + super(params); + this.staticUrl = params.staticUrl; + this.idb = params.idb; + } + async getEventsFromDB() { + return await loadDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName() + }); + } + async getEventsFromCache() { + return await loadRemoteEvents({ + staticUrl: this.staticUrl, + instanceName: this.getInstanceName(), + deployedBlock: this.deployedBlock, + zipDigest: this.zipDigest + }); + } + async saveEvents({ events, lastBlock }) { + await saveDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName(), + events, + lastBlock + }); + } +} +class DBGovernanceService extends BaseGovernanceService { + staticUrl; + idb; + zipDigest; + constructor(params) { + super(params); + this.staticUrl = params.staticUrl; + this.idb = params.idb; + } + async getEventsFromDB() { + return await loadDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName() + }); + } + async getEventsFromCache() { + return await loadRemoteEvents({ + staticUrl: this.staticUrl, + instanceName: this.getInstanceName(), + deployedBlock: this.deployedBlock, + zipDigest: this.zipDigest + }); + } + async saveEvents({ events, lastBlock }) { + await saveDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName(), + events, + lastBlock + }); + } +} +class DBRegistryService extends BaseRegistryService { + staticUrl; + idb; + zipDigest; + constructor(params) { + super(params); + this.staticUrl = params.staticUrl; + this.idb = params.idb; + } + async getEventsFromDB() { + return await loadDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName() + }); + } + async getEventsFromCache() { + return await loadRemoteEvents({ + staticUrl: this.staticUrl, + instanceName: this.getInstanceName(), + deployedBlock: this.deployedBlock, + zipDigest: this.zipDigest + }); + } + async saveEvents({ events, lastBlock }) { + await saveDBEvents({ + idb: this.idb, + instanceName: this.getInstanceName(), + events, + lastBlock + }); + } +} const dist_abi$8 = [ { @@ -189412,15 +189549,18 @@ class MerkleTreeService { Creating deposit tree for ${this.netId} ${this.amount} ${this.currency.toUpperCase()} would take a while ` ); - console.time("Created tree in"); + const timeStart = Date.now(); const tree = await this.createTree(events.map(({ commitment }) => commitment)); - console.timeEnd("Created tree in"); - console.log(""); const isKnownRoot = await this.Tornado.isKnownRoot(toFixedHex(BigInt(tree.root))); if (!isKnownRoot) { const errMsg = `Deposit Event ${this.netId} ${this.amount} ${this.currency} is invalid`; throw new Error(errMsg); } + console.log( + ` +Created ${this.netId} ${this.amount} ${this.currency.toUpperCase()} tree in ${Date.now() - timeStart}ms +` + ); return tree; } } @@ -190048,15 +190188,13 @@ class NodeTornadoService extends BaseTornadoService { cacheDirectory; userDirectory; nativeCurrency; - merkleTreeService; treeCache; constructor(serviceConstructor) { super(serviceConstructor); - const { cacheDirectory, userDirectory, nativeCurrency, merkleTreeService, treeCache } = serviceConstructor; + const { cacheDirectory, userDirectory, nativeCurrency, treeCache } = serviceConstructor; this.cacheDirectory = cacheDirectory; this.userDirectory = userDirectory; this.nativeCurrency = nativeCurrency; - this.merkleTreeService = merkleTreeService; this.treeCache = treeCache; } updateEventProgress({ type, fromBlock, toBlock, count }) { @@ -190099,15 +190237,17 @@ class NodeTornadoService extends BaseTornadoService { async getEventsFromCache() { return await getEventsFromCache(this); } - async saveEvents({ events, lastBlock }) { - if (this.userDirectory && this.merkleTreeService) { - const tree = await this.merkleTreeService.verifyTree(events); - if (this.currency === this.nativeCurrency && this.treeCache) { - await this.treeCache.createTree(events, tree); - console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(tree.root))} + async validateEvents({ events }) { + const tree = await super.validateEvents({ events }); + if (tree && this.currency === this.nativeCurrency && this.treeCache) { + const merkleTree = tree; + await this.treeCache.createTree(events, merkleTree); + console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(merkleTree.root))} `); - } } + return tree; + } + async saveEvents({ events, lastBlock }) { const eventTable = new (cli_table3_default())(); eventTable.push( [{ colSpan: 2, content: `${this.getType()}s`, hAlign: "center" }], @@ -191207,21 +191347,20 @@ Connected with Tovarish Relayer ${tovarishClient.selectedRelayer.url} }; const depositsService = new NodeTornadoService({ ...TornadoServiceConstructor, - type: "Deposit" + type: "Deposit", + merkleTreeService: new MerkleTreeService({ + netId, + amount, + currency, + Tornado, + merkleWorkerPath + }) }); const withdrawalsService = new NodeTornadoService({ ...TornadoServiceConstructor, type: "Withdrawal" }); - const merkleTreeService = new MerkleTreeService({ - netId, - amount, - currency, - Tornado, - merkleWorkerPath - }); - const depositEvents = (await depositsService.updateEvents()).events; - const tree = await merkleTreeService.verifyTree(depositEvents); + const { events: depositEvents, validateResult: tree } = await depositsService.updateEvents(); const withdrawalEvents = (await withdrawalsService.updateEvents()).events; const depositEvent = depositEvents.find(({ commitment }) => commitment === commitmentHex); const withdrawalEvent = withdrawalEvents.find(({ nullifierHash }) => nullifierHash === nullifierHex); diff --git a/dist/services/nodeEvents.d.ts b/dist/services/nodeEvents.d.ts index 75ff8f0..48e1f94 100644 --- a/dist/services/nodeEvents.d.ts +++ b/dist/services/nodeEvents.d.ts @@ -1,5 +1,5 @@ import { BatchBlockOnProgress, BatchEventOnProgress, BaseTornadoService, BaseEncryptedNotesService, BaseGovernanceService, BaseRegistryService, BaseTornadoServiceConstructor, BaseEncryptedNotesServiceConstructor, BaseGovernanceServiceConstructor, BaseRegistryServiceConstructor, BaseEchoServiceConstructor, BaseEchoService, CachedRelayers } from '@tornado/core'; -import type { BaseEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, RegistersEvents, AllGovernanceEvents, EchoEvents, MerkleTreeService } from '@tornado/core'; +import type { BaseEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, RegistersEvents, AllGovernanceEvents, EchoEvents } from '@tornado/core'; import { TreeCache } from './treeCache'; export type NodeServiceConstructor = { cacheDirectory: string; @@ -7,14 +7,12 @@ export type NodeServiceConstructor = { }; export type NodeTornadoServiceConstructor = BaseTornadoServiceConstructor & NodeServiceConstructor & { nativeCurrency: string; - merkleTreeService?: MerkleTreeService; treeCache?: TreeCache; }; export declare class NodeTornadoService extends BaseTornadoService { cacheDirectory: string; userDirectory: string; nativeCurrency: string; - merkleTreeService?: MerkleTreeService; treeCache?: TreeCache; constructor(serviceConstructor: NodeTornadoServiceConstructor); updateEventProgress({ type, fromBlock, toBlock, count }: Parameters[0]): void; @@ -23,6 +21,9 @@ export declare class NodeTornadoService extends BaseTornadoService { updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters[0]): void; getEventsFromDB(): Promise>; getEventsFromCache(): Promise>; + validateEvents({ events }: { + events: (DepositsEvents | WithdrawalsEvents)[]; + }): Promise; saveEvents({ events, lastBlock }: BaseEvents): Promise; } export type NodeEchoServiceConstructor = BaseEchoServiceConstructor & NodeServiceConstructor; diff --git a/package.json b/package.json index 8b0f354..22bb15a 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "optionalDependencies": {}, "devDependencies": { "@colors/colors": "^1.6.0", - "@tornado/core": "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#ddf306a835a0907eed1a2a7aab4ed41e34fd9037", + "@tornado/core": "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#dfb20aa61753c4f29ab144517ff48959e1b33c40", "@typechain/ethers-v6": "^0.5.1", "@types/figlet": "^1.7.0", "@typescript-eslint/eslint-plugin": "^8.9.0", diff --git a/src/program.ts b/src/program.ts index 6a7afc6..725bd11 100644 --- a/src/program.ts +++ b/src/program.ts @@ -60,7 +60,6 @@ import { NetIdType, getInstanceByAddress, getConfig, - Config, enabledChains, substring, NoteAccount, @@ -73,6 +72,7 @@ import { ReverseRecords__factory, numberFormatter, } from '@tornado/core'; +import type { MerkleTree } from '@tornado/fixed-merkle-tree'; import * as packageJson from '../package.json'; import { parseUrl, @@ -983,6 +983,13 @@ export function tornadoProgram() { const depositsService = new NodeTornadoService({ ...TornadoServiceConstructor, type: 'Deposit', + merkleTreeService: new MerkleTreeService({ + netId, + amount, + currency, + Tornado, + merkleWorkerPath, + }), }); const withdrawalsService = new NodeTornadoService({ @@ -990,22 +997,11 @@ export function tornadoProgram() { type: 'Withdrawal', }); - const merkleTreeService = new MerkleTreeService({ - netId, - amount, - currency, - Tornado, - merkleWorkerPath, - }); - - const depositEvents = (await depositsService.updateEvents()).events as DepositsEvents[]; - - // Create tree using node workers which would spawn another dedicated thread to create trees - const tree = await merkleTreeService.verifyTree(depositEvents); + const { events: depositEvents, validateResult: tree } = await depositsService.updateEvents(); const withdrawalEvents = (await withdrawalsService.updateEvents()).events as WithdrawalsEvents[]; - const depositEvent = depositEvents.find(({ commitment }) => commitment === commitmentHex); + const depositEvent = (depositEvents as DepositsEvents[]).find(({ commitment }) => commitment === commitmentHex); const withdrawalEvent = withdrawalEvents.find(({ nullifierHash }) => nullifierHash === nullifierHex); diff --git a/src/services/nodeEvents.ts b/src/services/nodeEvents.ts index d326723..df62124 100644 --- a/src/services/nodeEvents.ts +++ b/src/services/nodeEvents.ts @@ -17,6 +17,7 @@ import { BaseEchoService, CachedRelayers, toFixedHex, + DEPOSIT, } from '@tornado/core'; import type { BaseEvents, @@ -26,10 +27,10 @@ import type { RegistersEvents, AllGovernanceEvents, EchoEvents, - MerkleTreeService, BaseEventsService, MinimalEvents, } from '@tornado/core'; +import type { MerkleTree } from '@tornado/fixed-merkle-tree'; import { TreeCache } from './treeCache'; import { saveUserFile, loadSavedEvents, loadCachedEvents, existsAsync } from './data'; @@ -114,7 +115,6 @@ export type NodeServiceConstructor = { export type NodeTornadoServiceConstructor = BaseTornadoServiceConstructor & NodeServiceConstructor & { nativeCurrency: string; - merkleTreeService?: MerkleTreeService; treeCache?: TreeCache; }; @@ -123,19 +123,17 @@ export class NodeTornadoService extends BaseTornadoService { userDirectory: string; nativeCurrency: string; - merkleTreeService?: MerkleTreeService; treeCache?: TreeCache; constructor(serviceConstructor: NodeTornadoServiceConstructor) { super(serviceConstructor); - const { cacheDirectory, userDirectory, nativeCurrency, merkleTreeService, treeCache } = serviceConstructor; + const { cacheDirectory, userDirectory, nativeCurrency, treeCache } = serviceConstructor; this.cacheDirectory = cacheDirectory; this.userDirectory = userDirectory; this.nativeCurrency = nativeCurrency; - this.merkleTreeService = merkleTreeService; this.treeCache = treeCache; } @@ -185,17 +183,21 @@ export class NodeTornadoService extends BaseTornadoService { return await getEventsFromCache(this); } - async saveEvents({ events, lastBlock }: BaseEvents) { - if (this.userDirectory && this.merkleTreeService) { - const tree = await this.merkleTreeService.verifyTree(events as DepositsEvents[]); + async validateEvents({ events }: { events: (DepositsEvents | WithdrawalsEvents)[] }): Promise { + const tree = await super.validateEvents({ events }); - if (this.currency === this.nativeCurrency && this.treeCache) { - await this.treeCache.createTree(events as DepositsEvents[], tree); + if (tree && this.currency === this.nativeCurrency && this.treeCache) { + const merkleTree = tree as unknown as MerkleTree; - console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(tree.root))}\n`); - } + await this.treeCache.createTree(events as DepositsEvents[], merkleTree); + + console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(merkleTree.root))}\n`); } + return tree; + } + + async saveEvents({ events, lastBlock }: BaseEvents) { const eventTable = new Table(); eventTable.push( diff --git a/yarn.lock b/yarn.lock index fb3032a..622b176 100644 --- a/yarn.lock +++ b/yarn.lock @@ -785,9 +785,9 @@ "@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0" ethers "^6.13.4" -"@tornado/core@git+https://git.tornado.ws/tornadocontrib/tornado-core.git#ddf306a835a0907eed1a2a7aab4ed41e34fd9037": +"@tornado/core@git+https://git.tornado.ws/tornadocontrib/tornado-core.git#dfb20aa61753c4f29ab144517ff48959e1b33c40": version "1.0.19" - resolved "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#ddf306a835a0907eed1a2a7aab4ed41e34fd9037" + resolved "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#dfb20aa61753c4f29ab144517ff48959e1b33c40" dependencies: "@metamask/eth-sig-util" "^7.0.3" "@tornado/contracts" "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#ece511f424dc811c3aec149a4bf0e3731c0598a4"