Improve networkConfig and added more relayer data

This commit is contained in:
Tornado Contrib 2024-04-26 22:22:46 +00:00
parent 3312f44a4d
commit 183dc5ca60
Signed by: tornadocontrib
GPG Key ID: 60B4DF1A076C64B1
8 changed files with 87 additions and 79 deletions

@ -24,7 +24,7 @@
"depositInvoice": "ts-node src/cli.ts depositInvoice",
"withdraw": "ts-node src/cli.ts withdraw",
"compliance": "ts-node src/cli.ts compliance",
"syncEvents": "ts-node src/cli.ts syncEvents",
"updateEvents": "ts-node src/cli.ts updateEvents",
"relayers": "ts-node src/cli.ts relayers",
"createAccount": "ts-node src/cli.ts createAccount",
"decryptNotes": "ts-node src/cli.ts decryptNotes",

@ -29,6 +29,7 @@ import {
MaxUint256,
Transaction,
BigNumberish,
getAddress,
} from 'ethers';
import type MerkleTree from '@tornado/fixed-merkle-tree';
import * as packageJson from '../package.json';
@ -80,6 +81,7 @@ import {
substring,
NoteAccount,
parseRecoveryKey,
getSupportedInstances,
} from './services';
const DEFAULT_GAS_LIMIT = 600_000;
@ -327,7 +329,11 @@ export async function getProgramRelayer({
relayerClient.selectedRelayer = {
netId: relayerStatus.netId,
url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount,
hostname: new URL(relayerStatus.url).hostname,
rewardAccount: getAddress(relayerStatus.rewardAccount),
instances: getSupportedInstances(relayerStatus.instances),
gasPrice: relayerStatus.gasPrices?.fast,
ethPrices: relayerStatus.ethPrices,
currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee,
};
@ -343,13 +349,7 @@ export async function getProgramRelayer({
const relayerStatus = validRelayers[0];
if (relayerStatus) {
relayerClient.selectedRelayer = {
netId: relayerStatus.netId,
url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount,
currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee,
};
relayerClient.selectedRelayer = relayerStatus;
}
return {
@ -370,13 +370,7 @@ export async function getProgramRelayer({
const relayerStatus = relayerClient.pickWeightedRandomRelayer(validRelayers);
if (relayerStatus) {
relayerClient.selectedRelayer = {
netId: relayerStatus.netId,
url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount,
currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee,
};
relayerClient.selectedRelayer = relayerStatus;
}
return {
@ -529,7 +523,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`];
const {
multicall: multicallAddress,
multicallContract,
routerContract,
echoContract,
nativeCurrency,
@ -569,7 +563,7 @@ export function tornadoProgram() {
}
const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider);
const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined;
const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [
@ -674,7 +668,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`];
const {
multicall: multicallAddress,
multicallContract,
routerContract,
nativeCurrency,
tokens: { [currency]: currencyConfig },
@ -705,7 +699,7 @@ export function tornadoProgram() {
}
const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider);
const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined;
const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [
@ -792,8 +786,8 @@ export function tornadoProgram() {
tornadoSubgraph,
deployedBlock,
nativeCurrency,
multicallContract,
routerContract,
multicall: multicallAddress,
ovmGasPriceOracleContract,
tokens: { [currency]: currencyConfig },
} = config;
@ -829,7 +823,7 @@ export function tornadoProgram() {
const Tornado = Tornado__factory.connect(instanceAddress, provider);
const TornadoProxy = TornadoRouter__factory.connect(routerContract, !walletWithdrawal ? provider : signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider);
const Multicall = Multicall__factory.connect(multicallContract, provider);
const tornadoFeeOracle = new TornadoFeeOracle(
ovmGasPriceOracleContract
@ -1263,7 +1257,7 @@ export function tornadoProgram() {
});
program
.command('syncEvents')
.command('updateEvents')
.description('Sync the local cache file of tornado cash events.\n\n')
.argument('[netId]', 'Network Chain ID to connect with (see https://chainlist.org for examples)', parseNumber)
.argument('[currency]', 'Currency to sync events')
@ -1287,7 +1281,7 @@ export function tornadoProgram() {
routerContract,
echoContract,
registryContract,
['governance.contract.tornadocash.eth']: governanceContract,
governanceContract,
deployedBlock,
constants: { GOVERNANCE_BLOCK, REGISTRY_BLOCK, NOTE_ACCOUNT_BLOCK, ENCRYPTED_NOTES_BLOCK },
} = config;
@ -1440,6 +1434,8 @@ export function tornadoProgram() {
const validRelayers = allRelayers.validRelayers as RelayerInfo[];
const invalidRelayers = allRelayers.invalidRelayers as RelayerError[];
console.log(validRelayers);
const relayersTable = new Table();
relayersTable.push(
@ -1699,7 +1695,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`];
const { currencyName, multicall: multicallAddress } = config;
const { currencyName, multicallContract } = config;
const provider = getProgramProvider(netId, rpc, config, {
...fetchDataOptions,
@ -1715,7 +1711,7 @@ export function tornadoProgram() {
const tokenAddress = tokenArgs ? parseAddress(tokenArgs) : tokenOpts;
const Multicall = Multicall__factory.connect(multicallAddress, provider);
const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = (tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined) as ERC20;
// Fetching feeData or nonce is unnecessary however we do this to estimate transfer amounts
@ -1775,6 +1771,11 @@ export function tornadoProgram() {
const initCost = txGasPrice * BigInt('400000');
toSend = ethBalance - initCost;
if (ethBalance === BigInt(0) || ethBalance < initCost) {
const errMsg = `Invalid ${currencyName} balance, wants ${formatEther(initCost)} have ${formatEther(ethBalance)}`;
throw new Error(errMsg);
}
const estimatedGas = await provider.estimateGas({
type: txType,
from: signer.address,
@ -1830,12 +1831,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`];
const {
currencyName,
multicall: multicallAddress,
['torn.contract.tornadocash.eth']: tornTokenAddress,
tokens,
} = config;
const { currencyName, multicallContract, tornContract, tokens } = config;
const provider = getProgramProvider(netId, rpc, config, {
...fetchDataOptions,
@ -1848,14 +1844,14 @@ export function tornadoProgram() {
throw new Error('Address is required however no user address is supplied');
}
const Multicall = Multicall__factory.connect(multicallAddress, provider);
const Multicall = Multicall__factory.connect(multicallContract, provider);
const tokenAddresses = Object.values(tokens)
.map(({ tokenAddress }) => tokenAddress)
.filter((t) => t) as string[];
if (tornTokenAddress) {
tokenAddresses.push(tornTokenAddress);
if (tornContract) {
tokenAddresses.push(tornContract);
}
const tokenBalances = await getTokenBalances({

@ -1,6 +1,6 @@
import { getEncryptionPublicKey, encrypt, decrypt, EthEncryptedData } from '@metamask/eth-sig-util';
import { Echoer } from '@tornado/contracts';
import { Wallet, computeAddress } from 'ethers';
import { Wallet, computeAddress, getAddress } from 'ethers';
import { crypto, base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes } from './utils';
import { EchoEvents, EncryptedNotesEvents } from './events';
@ -164,7 +164,7 @@ export class NoteAccount {
decryptedEvents.push({
blockNumber: event.blockNumber,
address,
address: getAddress(address),
noteHex,
});
} catch {

@ -645,7 +645,7 @@ export async function getNoteAccounts({
subgraphName,
query: GET_NOTE_ACCOUNTS,
variables: {
address,
address: address.toLowerCase(),
},
fetchDataOptions,
});

@ -119,7 +119,7 @@ export class MerkleTreeService {
);
console.time('Created tree in');
const tree = await this.createTree(events.map(({ commitment }) => BigInt(commitment).toString()));
const tree = await this.createTree(events.map(({ commitment }) => commitment));
console.timeEnd('Created tree in');
console.log('');

@ -56,8 +56,11 @@ export type Config = {
networkName: string;
deployedBlock: number;
rpcUrls: RpcUrls;
multicall: string;
multicallContract: string;
routerContract: string;
tornContract?: string;
governanceContract?: string;
stakingRewardsContract?: string;
registryContract?: string;
echoContract: string;
aggregatorContract?: string;
@ -81,11 +84,6 @@ export type Config = {
// Should be in seconds
MINING_BLOCK_TIME?: number;
};
'torn.contract.tornadocash.eth'?: string;
'governance.contract.tornadocash.eth'?: string;
'staking-rewards.contract.tornadocash.eth'?: string;
'tornado-router.contract.tornadocash.eth'?: string;
'tornado-proxy-light.contract.tornadocash.eth'?: string;
};
export type networkConfig = {
@ -145,7 +143,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com',
},
chainnodes: {
name: 'Tornado RPC',
name: 'Chainnodes RPC',
url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
},
mevblockerRPC: {
@ -173,8 +171,11 @@ export const networkConfig: networkConfig = {
url: 'https://1rpc.io/eth',
},
},
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
tornContract: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
governanceContract: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
stakingRewardsContract: '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29',
registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2',
echoContract: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42',
aggregatorContract: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49',
@ -262,14 +263,10 @@ export const networkConfig: networkConfig = {
constants: {
GOVERNANCE_BLOCK: 11474695,
NOTE_ACCOUNT_BLOCK: 11842486,
ENCRYPTED_NOTES_BLOCK: 14248730,
ENCRYPTED_NOTES_BLOCK: 12143762,
REGISTRY_BLOCK: 14173129,
MINING_BLOCK_TIME: 15,
},
'torn.contract.tornadocash.eth': '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
'governance.contract.tornadocash.eth': '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
'tornado-router.contract.tornadocash.eth': '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
'staking-rewards.contract.tornadocash.eth': '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29',
},
netId56: {
rpcCallRetryAttempt: 15,
@ -290,7 +287,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Binance Smart Chain',
deployedBlock: 8158799,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/bsc-tornado-subgraph',
@ -304,7 +301,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/bsc',
},
chainnodes: {
name: 'Tornado RPC',
name: 'Chainnodes RPC',
url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
},
stackup: {
@ -338,7 +335,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 8159269,
ENCRYPTED_NOTES_BLOCK: 8159269,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId137: {
rpcCallRetryAttempt: 15,
@ -359,7 +355,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Polygon (Matic) Network',
deployedBlock: 16257962,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
gasPriceOracleContract: '0xF81A8D8D3581985D3969fe53bFA67074aDFa8F3C',
@ -400,7 +396,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 16257996,
ENCRYPTED_NOTES_BLOCK: 16257996,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId10: {
rpcCallRetryAttempt: 15,
@ -421,7 +416,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Optimism',
deployedBlock: 2243689,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
@ -436,7 +431,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/op',
},
chainnodes: {
name: 'Tornado RPC',
name: 'Chainnodes RPC',
url: 'https://optimism-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
},
optimism: {
@ -470,7 +465,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 2243694,
ENCRYPTED_NOTES_BLOCK: 2243694,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId42161: {
rpcCallRetryAttempt: 15,
@ -491,7 +485,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Arbitrum One',
deployedBlock: 3430648,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/arbitrum-tornado-subgraph',
@ -505,7 +499,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/arbitrum',
},
chainnodes: {
name: 'Tornado RPC',
name: 'Chainnodes RPC',
url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
},
arbitrum: {
@ -539,7 +533,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 3430605,
ENCRYPTED_NOTES_BLOCK: 3430605,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId100: {
rpcCallRetryAttempt: 15,
@ -560,7 +553,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Gnosis Chain',
deployedBlock: 17754561,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/xdai-tornado-subgraph',
@ -574,7 +567,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/gnosis',
},
chainnodes: {
name: 'Tornado RPC',
name: 'Chainnodes RPC',
url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
},
gnosis: {
@ -608,7 +601,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 17754564,
ENCRYPTED_NOTES_BLOCK: 17754564,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId43114: {
rpcCallRetryAttempt: 15,
@ -629,7 +621,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Avalanche Mainnet',
deployedBlock: 4429818,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph',
@ -667,7 +659,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 4429813,
ENCRYPTED_NOTES_BLOCK: 4429813,
},
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
},
netId11155111: {
rpcCallRetryAttempt: 15,
@ -688,8 +679,11 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Ethereum Sepolia',
deployedBlock: 5594395,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
tornContract: '0x3AE6667167C0f44394106E197904519D808323cA',
governanceContract: '0xe5324cD7602eeb387418e594B87aCADee08aeCAD',
stakingRewardsContract: '0x6d0018890751Efd31feb8166711B16732E2b496b',
registryContract: '0x1428e5d2356b13778A13108b10c440C83011dfB8',
echoContract: '0xcDD1fc3F5ac2782D83449d3AbE80D6b7B273B0e5',
aggregatorContract: '0x4088712AC9fad39ea133cdb9130E465d235e9642',
@ -745,9 +739,6 @@ export const networkConfig: networkConfig = {
ENCRYPTED_NOTES_BLOCK: 5594395,
MINING_BLOCK_TIME: 15,
},
'torn.contract.tornadocash.eth': '0x3AE6667167C0f44394106E197904519D808323cA',
'governance.contract.tornadocash.eth': '0xe5324cD7602eeb387418e594B87aCADee08aeCAD',
'tornado-router.contract.tornadocash.eth': '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
},
};

@ -1,4 +1,4 @@
import { namehash, parseEther } from 'ethers';
import { getAddress, namehash, parseEther } from 'ethers';
import type { Aggregator } from '@tornado/contracts';
import type { RelayerStructOutput } from '@tornado/contracts/dist/contracts/Governance/Aggregator/Aggregator';
import { sleep } from './utils';
@ -17,19 +17,21 @@ export interface RelayerParams {
export interface Relayer {
netId: number;
url: string;
hostname: string;
rewardAccount: string;
instances: string[];
gasPrice?: number;
ethPrices?: {
[key in string]: string;
};
currentQueue: number;
tornadoServiceFee: number;
}
export type RelayerInfo = Relayer & {
hostname: string;
ensName: string;
stakeBalance: bigint;
relayerAddress: string;
ethPrices?: {
[key in string]: string;
};
};
export type RelayerError = {
@ -139,6 +141,24 @@ export function getWeightRandom(weightsScores: bigint[], random: bigint) {
return Math.floor(Math.random() * weightsScores.length);
}
export type RelayerInstanceList = {
[key in string]: {
instanceAddress: {
[key in string]: string;
};
};
};
export function getSupportedInstances(instanceList: RelayerInstanceList) {
const rawList = Object.values(instanceList)
.map(({ instanceAddress }) => {
return Object.values(instanceAddress);
})
.flat();
return rawList.map((l) => getAddress(l));
}
export function pickWeightedRandomRelayer(relayers: RelayerInfo[], netId: string | number) {
let minFee: number, maxFee: number;
@ -263,7 +283,9 @@ export class RelayerClient {
ensName,
stakeBalance,
relayerAddress,
rewardAccount: status.rewardAccount,
rewardAccount: getAddress(status.rewardAccount),
instances: getSupportedInstances(status.instances),
gasPrice: status.gasPrices?.fast,
ethPrices: status.ethPrices,
currentQueue: status.currentQueue,
tornadoServiceFee: status.tornadoServiceFee,

@ -1,4 +1,3 @@
import { URL } from 'url';
import { webcrypto } from 'crypto';
import BN from 'bn.js';
import type { BigNumberish } from 'ethers';