Tornado CLI 1.0.9-alpha

* improve event sync
* use latest core deps
This commit is contained in:
Tornado Contrib 2024-09-25 08:40:15 +00:00
parent 37ce302ca5
commit 4c9fc48ad5
Signed by: tornadocontrib
GPG Key ID: 60B4DF1A076C64B1
6 changed files with 185 additions and 187 deletions

142
dist/cli.js vendored

@ -176375,6 +176375,8 @@ const defaultConfig = {
gasLimit: 7e5
}
},
// Inactive tokens to filter from schema verification and syncing events
disabledTokens: ["cdai", "usdt", "usdc"],
relayerEnsSubdomain: "mainnet-tornado",
pollInterval: 15,
constants: {
@ -176832,9 +176834,16 @@ function getConfig(netId) {
}
return chainConfig;
}
function getInstanceByAddress({ netId, address }) {
const { tokens } = getConfig(netId);
function getActiveTokens(config) {
const { tokens, disabledTokens } = config;
return Object.keys(tokens).filter((t) => !(disabledTokens == null ? void 0 : disabledTokens.includes(t)));
}
function getInstanceByAddress(config, address) {
const { tokens, disabledTokens } = config;
for (const [currency, { instanceAddress }] of Object.entries(tokens)) {
if (disabledTokens == null ? void 0 : disabledTokens.includes(currency)) {
continue;
}
for (const [amount, instance] of Object.entries(instanceAddress)) {
if (instance === address) {
return {
@ -176845,10 +176854,6 @@ function getInstanceByAddress({ netId, address }) {
}
}
}
function getSubdomains() {
const allConfig = getNetworkConfig();
return enabledChains.map((chain) => allConfig[chain].relayerEnsSubdomain);
}
function getRelayerEnsSubdomains() {
const allConfig = getNetworkConfig();
return enabledChains.reduce((acc, chain) => {
@ -176888,7 +176893,7 @@ const statusSchema = {
required: ["rewardAccount", "instances", "netId", "tornadoServiceFee", "version", "health"]
};
function getStatusSchema(netId, config) {
const { tokens, optionalTokens = [], nativeCurrency } = config;
const { tokens, optionalTokens, disabledTokens, nativeCurrency } = config;
const schema = JSON.parse(JSON.stringify(statusSchema));
const instances = Object.keys(tokens).reduce(
(acc, token) => {
@ -176919,7 +176924,7 @@ function getStatusSchema(netId, config) {
instanceProperties.properties.symbol = { enum: [symbol] };
}
acc.properties[token] = instanceProperties;
if (!optionalTokens.includes(token)) {
if (!(optionalTokens == null ? void 0 : optionalTokens.includes(token)) && !(disabledTokens == null ? void 0 : disabledTokens.includes(token))) {
acc.required.push(token);
}
return acc;
@ -177023,18 +177028,6 @@ var __async$9 = (__this, __arguments, generator) => {
const MIN_FEE = 0.1;
const MAX_FEE = 0.6;
const MIN_STAKE_BALANCE = parseEther("500");
const semVerRegex = new RegExp("^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
function parseSemanticVersion(version) {
const { groups } = semVerRegex.exec(version);
return groups;
}
function isRelayerUpdated(relayerVersion, netId) {
const { major, patch, prerelease } = parseSemanticVersion(relayerVersion);
const requiredMajor = netId === NetId.MAINNET ? "4" : "5";
const isUpdatedMajor = major === requiredMajor;
if (prerelease) return false;
return isUpdatedMajor && (Number(patch) >= 5 || netId !== NetId.MAINNET);
}
function calculateScore({ stakeBalance, tornadoServiceFee }) {
if (tornadoServiceFee < MIN_FEE) {
tornadoServiceFee = MIN_FEE;
@ -177106,9 +177099,6 @@ class RelayerClient {
if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
throw new Error("The Relayer reward address must match registered address");
}
if (!isRelayerUpdated(status.version, this.netId)) {
throw new Error("Outdated version.");
}
return status;
});
}
@ -181125,7 +181115,7 @@ function calculateSnarkProof(input, circuit, provingKey) {
;// CONCATENATED MODULE: ./package.json
const package_namespaceObject = /*#__PURE__*/JSON.parse('{"rE":"1.0.8-alpha","h_":"Modern Toolsets for Privacy Pools on Ethereum"}');
const package_namespaceObject = /*#__PURE__*/JSON.parse('{"rE":"1.0.9-alpha","h_":"Modern Toolsets for Privacy Pools on Ethereum"}');
var package_namespaceObject_0 = /*#__PURE__*/__webpack_require__.t(package_namespaceObject, 2);
;// CONCATENATED MODULE: external "module"
const external_module_namespaceObject = require("module");
@ -184033,7 +184023,10 @@ class NodeTornadoService extends BaseTornadoService {
deployedBlock,
fetchDataOptions,
cacheDirectory,
userDirectory
userDirectory,
nativeCurrency,
merkleTreeService,
treeCache
}) {
super({
netId,
@ -184049,6 +184042,9 @@ class NodeTornadoService extends BaseTornadoService {
});
this.cacheDirectory = cacheDirectory;
this.userDirectory = userDirectory;
this.nativeCurrency = nativeCurrency;
this.merkleTreeService = merkleTreeService;
this.treeCache = treeCache;
}
updateEventProgress({ type, fromBlock, toBlock, count }) {
if (toBlock) {
@ -184160,6 +184156,14 @@ class NodeTornadoService extends BaseTornadoService {
);
console.log(eventTable.toString() + "\n");
if (this.userDirectory) {
if (this.merkleTreeService) {
const tree = yield this.merkleTreeService.verifyTree(events);
if (this.currency === this.nativeCurrency && this.treeCache) {
yield this.treeCache.createTree(events, tree);
console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(tree.root))}
`);
}
}
yield saveUserFile({
fileName: instanceName + ".json",
userDirectory: this.userDirectory,
@ -185038,12 +185042,11 @@ var program_async = (__this, __arguments, generator) => {
const EXEC_NAME = "tornado-cli";
const INACTIVE_TOKENS = ["cdai", "usdc", "usdt"];
const DEFAULT_GAS_LIMIT = Number((external_process_default()).env.DEFAULT_GAS_LIMIT) || 6e5;
const RELAYER_NETWORK = Number((external_process_default()).env.RELAYER_NETWORK) || NetId.MAINNET;
const STATIC_DIR = (external_process_default()).env.CACHE_DIR || external_path_default().join(__dirname, "../static");
const EVENTS_DIR = external_path_default().join(STATIC_DIR, "./events");
const MERKLE_WORKER_PATH = (external_process_default()).env.DISABLE_MERKLE_WORKER === "true" ? void 0 : external_path_default().join(STATIC_DIR, "./merkleTreeWorker.js");
const merkleWorkerPath = external_path_default().join(STATIC_DIR, "./merkleTreeWorker.js");
const USER_DIR = (external_process_default()).env.USER_DIR || ".";
const SAVED_DIR = external_path_default().join(USER_DIR, "./events");
const SAVED_TREE_DIR = external_path_default().join(USER_DIR, "./trees");
@ -185185,7 +185188,6 @@ function getProgramRelayer(_0) {
},
ethConfig
);
const relayerEnsSubdomains = getRelayerEnsSubdomains();
const registryService = new NodeRegistryService({
netId: RELAYER_NETWORK,
provider,
@ -185193,7 +185195,7 @@ function getProgramRelayer(_0) {
subgraphName: registrySubgraph,
RelayerRegistry: RelayerRegistry__factory.connect(registryContract, provider),
Aggregator: Aggregator__factory.connect(aggregatorContract, provider),
relayerEnsSubdomains,
relayerEnsSubdomains: getRelayerEnsSubdomains(),
deployedBlock: REGISTRY_BLOCK,
fetchDataOptions: fetchDataOptions2,
cacheDirectory: EVENTS_DIR,
@ -185595,7 +185597,8 @@ function tornadoProgram() {
deployedBlock,
fetchDataOptions: fetchDataOptions2,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR
userDirectory: SAVED_DIR,
nativeCurrency
};
const depositsService = new NodeTornadoService(program_spreadProps(program_spreadValues({}, TornadoServiceConstructor), {
type: "Deposit"
@ -185608,10 +185611,10 @@ function tornadoProgram() {
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH
merkleWorkerPath
});
const depositEvents = (yield depositsService.updateEvents()).events;
const depositTreePromise = MERKLE_WORKER_PATH ? merkleTreeService.verifyTree(depositEvents) : yield merkleTreeService.verifyTree(depositEvents);
const depositTreePromise = merkleTreeService.verifyTree(depositEvents);
const withdrawalEvents = (yield withdrawalsService.updateEvents()).events;
const depositEvent = depositEvents.find(({ commitment }) => commitment === commitmentHex);
const withdrawalEvent = withdrawalEvents.find(({ nullifierHash }) => nullifierHash === nullifierHex);
@ -185808,6 +185811,7 @@ function tornadoProgram() {
const {
tornadoSubgraph,
deployedBlock,
nativeCurrency,
tokens: { [currency]: currencyConfig }
} = config;
const {
@ -185830,27 +185834,24 @@ function tornadoProgram() {
deployedBlock,
fetchDataOptions: fetchDataOptions2,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR
userDirectory: SAVED_DIR,
nativeCurrency
};
const depositsService = new NodeTornadoService(program_spreadProps(program_spreadValues({}, TornadoServiceConstructor), {
type: "Deposit"
type: "Deposit",
merkleTreeService: new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath
})
}));
const withdrawalsService = new NodeTornadoService(program_spreadProps(program_spreadValues({}, TornadoServiceConstructor), {
type: "Withdrawal"
}));
const merkleTreeService = new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH
});
const depositEvents = (yield depositsService.updateEvents()).events;
const depositTreePromise = MERKLE_WORKER_PATH ? merkleTreeService.verifyTree(depositEvents) : yield merkleTreeService.verifyTree(depositEvents);
const [withdrawalEvents] = yield Promise.all([
withdrawalsService.updateEvents().then(({ events }) => events),
depositTreePromise
]);
const withdrawalEvents = (yield withdrawalsService.updateEvents()).events;
const depositEvent = depositEvents.find(({ commitment }) => commitment === commitmentHex);
const withdrawalEvent = withdrawalEvents.find(({ nullifierHash }) => nullifierHash === nullifierHex);
const complianceTable = new (cli_table3_default())();
@ -185930,7 +185931,6 @@ function tornadoProgram() {
yield governanceService.updateEvents();
}
if (registryContract && aggregatorContract) {
const relayerEnsSubdomains = getRelayerEnsSubdomains();
const registryService = new NodeRegistryService({
netId,
provider,
@ -185938,7 +185938,7 @@ function tornadoProgram() {
subgraphName: registrySubgraph,
RelayerRegistry: RelayerRegistry__factory.connect(registryContract, provider),
Aggregator: Aggregator__factory.connect(aggregatorContract, provider),
relayerEnsSubdomains,
relayerEnsSubdomains: getRelayerEnsSubdomains(),
deployedBlock: REGISTRY_BLOCK,
fetchDataOptions: fetchDataOptions2,
cacheDirectory: EVENTS_DIR,
@ -185970,11 +185970,8 @@ function tornadoProgram() {
userDirectory: SAVED_DIR
});
yield encryptedNotesService.updateEvents();
const currencies = currencyOpts ? [currencyOpts.toLowerCase()] : Object.keys(tokens);
const currencies = currencyOpts ? [currencyOpts.toLowerCase()] : getActiveTokens(config);
for (const currency of currencies) {
if (INACTIVE_TOKENS.includes(currency)) {
continue;
}
const currencyConfig = tokens[currency];
const amounts = Object.keys(currencyConfig.instanceAddress);
for (const amount of amounts) {
@ -185991,33 +185988,30 @@ function tornadoProgram() {
deployedBlock,
fetchDataOptions: fetchDataOptions2,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR
userDirectory: SAVED_DIR,
nativeCurrency
};
const depositsService = new NodeTornadoService(program_spreadProps(program_spreadValues({}, TornadoServiceConstructor), {
type: "Deposit"
type: "Deposit",
merkleTreeService: new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath
}),
treeCache: new TreeCache({
netId,
amount,
currency,
userDirectory: SAVED_TREE_DIR
})
}));
const withdrawalsService = new NodeTornadoService(program_spreadProps(program_spreadValues({}, TornadoServiceConstructor), {
type: "Withdrawal"
}));
const merkleTreeService = new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH
});
const treeCache = new TreeCache({
netId,
amount,
currency,
userDirectory: SAVED_TREE_DIR
});
const depositEvents = (yield depositsService.updateEvents()).events;
const depositTreePromise = MERKLE_WORKER_PATH ? merkleTreeService.verifyTree(depositEvents) : yield merkleTreeService.verifyTree(depositEvents);
const [tree] = yield Promise.all([depositTreePromise, withdrawalsService.updateEvents()]);
if (nativeCurrency === currency) {
yield treeCache.createTree(depositEvents, tree);
}
yield depositsService.updateEvents();
yield withdrawalsService.updateEvents();
}
}
}
@ -186203,7 +186197,7 @@ function tornadoProgram() {
[{ colSpan: 2, content: `Account key: ${accountKey}`, hAlign: "center" }],
["blockNumber", "note"].map((content) => ({ content: lib_default().red.bold(content) })),
...noteAccount.decryptNotes(encryptedNoteEvents).map(({ blockNumber, address, noteHex }) => {
const { amount, currency } = getInstanceByAddress({ netId, address });
const { amount, currency } = getInstanceByAddress(config, address) || {};
return [blockNumber, `tornado-${currency}-${amount}-${netId}-${noteHex}`];
})
);

@ -1,13 +1,20 @@
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 } from '@tornado/core';
import type { BaseEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, RegistersEvents, AllGovernanceEvents, EchoEvents, MerkleTreeService } from '@tornado/core';
import { TreeCache } from './treeCache';
export type NodeTornadoServiceConstructor = BaseTornadoServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
nativeCurrency: string;
merkleTreeService?: MerkleTreeService;
treeCache?: TreeCache;
};
export declare class NodeTornadoService extends BaseTornadoService {
cacheDirectory?: string;
userDirectory?: string;
constructor({ netId, provider, graphApi, subgraphName, Tornado, type, amount, currency, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, }: NodeTornadoServiceConstructor);
cacheDirectory: string;
userDirectory: string;
nativeCurrency: string;
merkleTreeService?: MerkleTreeService;
treeCache?: TreeCache;
constructor({ netId, provider, graphApi, subgraphName, Tornado, type, amount, currency, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, nativeCurrency, merkleTreeService, treeCache, }: NodeTornadoServiceConstructor);
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
updateTransactionProgress({ currentIndex, totalIndex }: Parameters<BatchBlockOnProgress>[0]): void;
updateBlockProgress({ currentIndex, totalIndex }: Parameters<BatchBlockOnProgress>[0]): void;
@ -17,12 +24,12 @@ export declare class NodeTornadoService extends BaseTornadoService {
saveEvents({ events, lastBlock }: BaseEvents<DepositsEvents | WithdrawalsEvents>): Promise<void>;
}
export type NodeEchoServiceConstructor = BaseEchoServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export declare class NodeEchoService extends BaseEchoService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({ netId, provider, graphApi, subgraphName, Echoer, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, }: NodeEchoServiceConstructor);
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
@ -31,12 +38,12 @@ export declare class NodeEchoService extends BaseEchoService {
saveEvents({ events, lastBlock }: BaseEvents<EchoEvents>): Promise<void>;
}
export type NodeEncryptedNotesServiceConstructor = BaseEncryptedNotesServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export declare class NodeEncryptedNotesService extends BaseEncryptedNotesService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({ netId, provider, graphApi, subgraphName, Router, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, }: NodeEncryptedNotesServiceConstructor);
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
@ -45,12 +52,12 @@ export declare class NodeEncryptedNotesService extends BaseEncryptedNotesService
saveEvents({ events, lastBlock }: BaseEvents<EncryptedNotesEvents>): Promise<void>;
}
export type NodeGovernanceServiceConstructor = BaseGovernanceServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export declare class NodeGovernanceService extends BaseGovernanceService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({ netId, provider, graphApi, subgraphName, Governance, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, }: NodeGovernanceServiceConstructor);
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
@ -60,12 +67,12 @@ export declare class NodeGovernanceService extends BaseGovernanceService {
saveEvents({ events, lastBlock }: BaseEvents<AllGovernanceEvents>): Promise<void>;
}
export type NodeRegistryServiceConstructor = BaseRegistryServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export declare class NodeRegistryService extends BaseRegistryService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({ netId, provider, graphApi, subgraphName, RelayerRegistry, Aggregator, relayerEnsSubdomains, deployedBlock, fetchDataOptions, cacheDirectory, userDirectory, }: NodeRegistryServiceConstructor);
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;

@ -1,6 +1,6 @@
{
"name": "@tornado/cli",
"version": "1.0.8-alpha",
"version": "1.0.9-alpha",
"description": "Modern Toolsets for Privacy Pools on Ethereum",
"main": "./dist/cli.js",
"types": "./dist/cli.d.ts",
@ -51,7 +51,7 @@
"optionalDependencies": {},
"devDependencies": {
"@colors/colors": "1.5.0",
"@tornado/core": "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#d0b032d7bef06de61872ba7ad07b769b9b1d9717",
"@tornado/core": "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#f7fdf7db0a813ae2193f9864e212d68dc840c0d7",
"@typechain/ethers-v6": "^0.5.1",
"@types/figlet": "^1.5.8",
"@typescript-eslint/eslint-plugin": "^8.6.0",

@ -67,6 +67,7 @@ import {
getSupportedInstances,
initGroth16,
getRelayerEnsSubdomains,
getActiveTokens,
} from '@tornado/core';
import * as packageJson from '../package.json';
import {
@ -87,9 +88,6 @@ import {
const EXEC_NAME = 'tornado-cli';
// Inactive tokens to filter from syncing (Either they have no activity for more than a year, should be filtered from event syncs and withdrawals)
const INACTIVE_TOKENS: string[] = ['cdai', 'usdc', 'usdt'];
/**
* Static variables, shouldn't be modified by env unless you know what they are doing
*/
@ -100,8 +98,7 @@ const RELAYER_NETWORK = Number(process.env.RELAYER_NETWORK) || NetId.MAINNET;
// Where cached events, trees, circuits, and key is saved
const STATIC_DIR = process.env.CACHE_DIR || path.join(__dirname, '../static');
const EVENTS_DIR = path.join(STATIC_DIR, './events');
const MERKLE_WORKER_PATH =
process.env.DISABLE_MERKLE_WORKER === 'true' ? undefined : path.join(STATIC_DIR, './merkleTreeWorker.js');
const merkleWorkerPath = path.join(STATIC_DIR, './merkleTreeWorker.js');
// Where we should backup notes and save events
const USER_DIR = process.env.USER_DIR || '.';
@ -315,8 +312,6 @@ export async function getProgramRelayer({
ethConfig,
);
const relayerEnsSubdomains = getRelayerEnsSubdomains();
const registryService = new NodeRegistryService({
netId: RELAYER_NETWORK,
provider,
@ -324,7 +319,7 @@ export async function getProgramRelayer({
subgraphName: registrySubgraph,
RelayerRegistry: RelayerRegistry__factory.connect(registryContract as string, provider),
Aggregator: Aggregator__factory.connect(aggregatorContract as string, provider),
relayerEnsSubdomains,
relayerEnsSubdomains: getRelayerEnsSubdomains(),
deployedBlock: REGISTRY_BLOCK,
fetchDataOptions,
cacheDirectory: EVENTS_DIR,
@ -874,6 +869,7 @@ export function tornadoProgram() {
fetchDataOptions,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR,
nativeCurrency,
};
const depositsService = new NodeTornadoService({
@ -891,15 +887,13 @@ export function tornadoProgram() {
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH,
merkleWorkerPath,
});
const depositEvents = (await depositsService.updateEvents()).events as DepositsEvents[];
// If we have MERKLE_WORKER_PATH run worker at background otherwise resolve it here
const depositTreePromise = MERKLE_WORKER_PATH
? merkleTreeService.verifyTree(depositEvents)
: await merkleTreeService.verifyTree(depositEvents);
// Create tree using node workers which would spawn another dedicated thread to create trees
const depositTreePromise = merkleTreeService.verifyTree(depositEvents);
const withdrawalEvents = (await withdrawalsService.updateEvents()).events as WithdrawalsEvents[];
@ -1166,6 +1160,7 @@ export function tornadoProgram() {
const {
tornadoSubgraph,
deployedBlock,
nativeCurrency,
tokens: { [currency]: currencyConfig },
} = config;
@ -1195,11 +1190,19 @@ export function tornadoProgram() {
fetchDataOptions,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR,
nativeCurrency,
};
const depositsService = new NodeTornadoService({
...TornadoServiceConstructor,
type: 'Deposit',
merkleTreeService: new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath,
}),
});
const withdrawalsService = new NodeTornadoService({
@ -1207,25 +1210,9 @@ export function tornadoProgram() {
type: 'Withdrawal',
});
const merkleTreeService = new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH,
});
const depositEvents = (await depositsService.updateEvents()).events as DepositsEvents[];
// If we have MERKLE_WORKER_PATH run worker at background otherwise resolve it here
const depositTreePromise = MERKLE_WORKER_PATH
? merkleTreeService.verifyTree(depositEvents)
: await merkleTreeService.verifyTree(depositEvents);
const [withdrawalEvents] = await Promise.all([
withdrawalsService.updateEvents().then(({ events }) => events as WithdrawalsEvents[]),
depositTreePromise,
]);
const withdrawalEvents = (await withdrawalsService.updateEvents()).events as WithdrawalsEvents[];
const depositEvent = depositEvents.find(({ commitment }) => commitment === commitmentHex);
@ -1327,8 +1314,6 @@ export function tornadoProgram() {
}
if (registryContract && aggregatorContract) {
const relayerEnsSubdomains = getRelayerEnsSubdomains();
const registryService = new NodeRegistryService({
netId,
provider,
@ -1336,7 +1321,7 @@ export function tornadoProgram() {
subgraphName: registrySubgraph,
RelayerRegistry: RelayerRegistry__factory.connect(registryContract, provider),
Aggregator: Aggregator__factory.connect(aggregatorContract, provider),
relayerEnsSubdomains,
relayerEnsSubdomains: getRelayerEnsSubdomains(),
deployedBlock: REGISTRY_BLOCK,
fetchDataOptions,
cacheDirectory: EVENTS_DIR,
@ -1374,14 +1359,9 @@ export function tornadoProgram() {
await encryptedNotesService.updateEvents();
const currencies = currencyOpts ? [currencyOpts.toLowerCase()] : Object.keys(tokens);
const currencies = currencyOpts ? [currencyOpts.toLowerCase()] : getActiveTokens(config);
for (const currency of currencies) {
// Skip syncing inactive instances
if (INACTIVE_TOKENS.includes(currency)) {
continue;
}
const currencyConfig = tokens[currency];
// Now load the denominations and address
const amounts = Object.keys(currencyConfig.instanceAddress);
@ -1403,11 +1383,25 @@ export function tornadoProgram() {
fetchDataOptions,
cacheDirectory: EVENTS_DIR,
userDirectory: SAVED_DIR,
nativeCurrency,
};
const depositsService = new NodeTornadoService({
...TornadoServiceConstructor,
type: 'Deposit',
merkleTreeService: new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath,
}),
treeCache: new TreeCache({
netId,
amount,
currency,
userDirectory: SAVED_TREE_DIR,
}),
});
const withdrawalsService = new NodeTornadoService({
@ -1415,33 +1409,9 @@ export function tornadoProgram() {
type: 'Withdrawal',
});
const merkleTreeService = new MerkleTreeService({
netId,
amount,
currency,
Tornado,
merkleWorkerPath: MERKLE_WORKER_PATH,
});
await depositsService.updateEvents();
const treeCache = new TreeCache({
netId,
amount,
currency,
userDirectory: SAVED_TREE_DIR,
});
const depositEvents = (await depositsService.updateEvents()).events as DepositsEvents[];
// If we have MERKLE_WORKER_PATH run worker at background otherwise resolve it here
const depositTreePromise = MERKLE_WORKER_PATH
? merkleTreeService.verifyTree(depositEvents)
: await merkleTreeService.verifyTree(depositEvents);
const [tree] = await Promise.all([depositTreePromise, withdrawalsService.updateEvents()]);
if (nativeCurrency === currency) {
await treeCache.createTree(depositEvents, tree);
}
await withdrawalsService.updateEvents();
}
}
}
@ -1696,7 +1666,7 @@ export function tornadoProgram() {
[{ colSpan: 2, content: `Account key: ${accountKey}`, hAlign: 'center' }],
['blockNumber', 'note'].map((content) => ({ content: colors.red.bold(content) })),
...noteAccount.decryptNotes(encryptedNoteEvents).map(({ blockNumber, address, noteHex }) => {
const { amount, currency } = getInstanceByAddress({ netId, address }) as { amount: string; currency: string };
const { amount, currency } = getInstanceByAddress(config, address) || {};
return [blockNumber, `tornado-${currency}-${amount}-${netId}-${noteHex}`];
}),

@ -17,6 +17,7 @@ import {
BaseEchoService,
DEPOSIT,
CachedRelayers,
toFixedHex,
} from '@tornado/core';
import type {
BaseEvents,
@ -26,17 +27,26 @@ import type {
RegistersEvents,
AllGovernanceEvents,
EchoEvents,
MerkleTreeService,
} from '@tornado/core';
import { TreeCache } from './treeCache';
import { saveUserFile, loadSavedEvents, loadCachedEvents, saveLegacyFile, existsAsync } from './data';
export type NodeTornadoServiceConstructor = BaseTornadoServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
nativeCurrency: string;
merkleTreeService?: MerkleTreeService;
treeCache?: TreeCache;
};
export class NodeTornadoService extends BaseTornadoService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
nativeCurrency: string;
merkleTreeService?: MerkleTreeService;
treeCache?: TreeCache;
constructor({
netId,
@ -51,6 +61,9 @@ export class NodeTornadoService extends BaseTornadoService {
fetchDataOptions,
cacheDirectory,
userDirectory,
nativeCurrency,
merkleTreeService,
treeCache,
}: NodeTornadoServiceConstructor) {
super({
netId,
@ -67,6 +80,10 @@ export class NodeTornadoService extends BaseTornadoService {
this.cacheDirectory = cacheDirectory;
this.userDirectory = userDirectory;
this.nativeCurrency = nativeCurrency;
this.merkleTreeService = merkleTreeService;
this.treeCache = treeCache;
}
updateEventProgress({ type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]) {
@ -190,6 +207,16 @@ export class NodeTornadoService extends BaseTornadoService {
console.log(eventTable.toString() + '\n');
if (this.userDirectory) {
if (this.merkleTreeService) {
const tree = await this.merkleTreeService.verifyTree(events as DepositsEvents[]);
if (this.currency === this.nativeCurrency && this.treeCache) {
await this.treeCache.createTree(events as DepositsEvents[], tree);
console.log(`${this.getInstanceName()}: Updated tree cache with root ${toFixedHex(BigInt(tree.root))}\n`);
}
}
await saveUserFile({
fileName: instanceName + '.json',
userDirectory: this.userDirectory,
@ -226,13 +253,13 @@ export class NodeTornadoService extends BaseTornadoService {
}
export type NodeEchoServiceConstructor = BaseEchoServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export class NodeEchoService extends BaseEchoService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({
netId,
@ -372,13 +399,13 @@ export class NodeEchoService extends BaseEchoService {
}
export type NodeEncryptedNotesServiceConstructor = BaseEncryptedNotesServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export class NodeEncryptedNotesService extends BaseEncryptedNotesService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({
netId,
@ -530,13 +557,13 @@ export class NodeEncryptedNotesService extends BaseEncryptedNotesService {
}
export type NodeGovernanceServiceConstructor = BaseGovernanceServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export class NodeGovernanceService extends BaseGovernanceService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({
netId,
@ -682,13 +709,13 @@ export class NodeGovernanceService extends BaseGovernanceService {
}
export type NodeRegistryServiceConstructor = BaseRegistryServiceConstructor & {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
};
export class NodeRegistryService extends BaseRegistryService {
cacheDirectory?: string;
userDirectory?: string;
cacheDirectory: string;
userDirectory: string;
constructor({
netId,

@ -781,9 +781,9 @@
"@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0"
ethers "^6.4.0"
"@tornado/core@git+https://git.tornado.ws/tornadocontrib/tornado-core.git#d0b032d7bef06de61872ba7ad07b769b9b1d9717":
version "1.0.13"
resolved "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#d0b032d7bef06de61872ba7ad07b769b9b1d9717"
"@tornado/core@git+https://git.tornado.ws/tornadocontrib/tornado-core.git#f7fdf7db0a813ae2193f9864e212d68dc840c0d7":
version "1.0.14"
resolved "git+https://git.tornado.ws/tornadocontrib/tornado-core.git#f7fdf7db0a813ae2193f9864e212d68dc840c0d7"
dependencies:
"@metamask/eth-sig-util" "^7.0.3"
"@tornado/contracts" "^1.0.1"