diff --git a/.gitignore b/.gitignore index db72ca3..42b6dc1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,6 @@ package-lock.json yarn.lock # VScode files -.vscode \ No newline at end of file +.vscode + +test.ts \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index dbe6e5a..3f784dc 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v20.3.0 \ No newline at end of file +v16.20.2 \ No newline at end of file diff --git a/package.json b/package.json index bef9b36..e5f52b1 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,16 @@ { - "name": "proposal-27", + "name": "proposal-30", "version": "1.0.0", - "repository": "https://git.tornado.ws/Theo/proposal-27-update-ipfs", + "repository": "https://git.tornado.ws/Theo/proposal-30-decentralize-sources", "author": "Theo", "license": "MIT", "private": false, "scripts": { "calculateENS": "npx ts-node scripts/calculateENSNodes.ts", "calculateIpfsV1Cids": "npx ts-node scripts/calculateIpfsV1Cids", - "calculateIPFS": "npx ts-node scripts/calculateIPFSContenthashes", + "calculateIpfs": "npx ts-node scripts/calculateIPFSContenthashes", "init": "cd lib && git clone --recurse-submodules https://github.com/foundry-rs/forge-std", + "test:calculateENS": "npx ts-node scripts/test/calculateENSNodes.ts", "test:windows": ".\\.env.bat && forge test", "test:linux": ". .env && forge test", "test:gas:windows": ".\\.env.bat && forge test --gas-report", diff --git a/scripts/calculateENSNodes.ts b/scripts/calculateENSNodes.ts index f2c45d8..2d69f5e 100644 --- a/scripts/calculateENSNodes.ts +++ b/scripts/calculateENSNodes.ts @@ -5,40 +5,31 @@ import path from "path"; import { hash } from "@ensdomains/eth-ens-namehash"; import { keccak_256 } from "js-sha3"; import { DeclCalculator } from "./utils"; - -const rootTornadoDomain = "tornadocash.eth"; -const stakingDomain = "staking-rewards.contract.tornadocash.eth"; -const governanceImplDomain = "governance-impl.contract.tornadocash.eth"; -const novaUIDomain = "nova.tornadocash.eth"; -const docsDomain = "docs.tornadocash.eth"; -const relayersUIDomain = "relayers-network.tornadocash.eth"; -const tornadoContractDomain = "contract.tornadocash.eth"; - -const rootTornadoENSNode = hash(rootTornadoDomain); -const tornadoContractENSNode = hash(tornadoContractDomain); -const stakingRewardsENSNode = hash(stakingDomain); -const governanceImplENSNode = hash(governanceImplDomain); -const novaENSNode = hash(novaUIDomain); -const docsENSNode = hash(docsDomain); -const relayersUIENSNode = hash(relayersUIDomain); +import { ensDomains } from "./constants"; const getLabelhashFromDomain = (ensDomain: string) => "0x" + keccak_256(ensDomain.split(".")[0]); -const tornadoContractENSLabelhash = getLabelhashFromDomain(tornadoContractDomain); -const stakingRewardsENSLabelhash = getLabelhashFromDomain(stakingDomain); -const governanceImplENSLabelhash = getLabelhashFromDomain(governanceImplDomain); -const { calculateDecl } = new DeclCalculator("bytes32"); +const solidityInContractPadding = " ".repeat(4); +const { calculateDecl: calculateNodeDecl } = new DeclCalculator( + "bytes32 internal constant", + solidityInContractPadding, + hash, + (name: string) => name + "Node" +); +const { calculateDecl: calculateLabelDecl } = new DeclCalculator( + "bytes32 internal constant", + solidityInContractPadding, + getLabelhashFromDomain, + (name: string) => name + "Labelhash" +); + const solidityCode = - calculateDecl({ rootTornadoENSNode }) + - calculateDecl({ tornadoContractENSNode }) + - calculateDecl({ stakingRewardsENSNode }) + - calculateDecl({ governanceImplENSNode }) + - calculateDecl({ novaENSNode }) + - calculateDecl({ docsENSNode }) + - calculateDecl({ relayersUIENSNode }) + + Object.entries(ensDomains) + .map((e) => calculateNodeDecl(e)) + .join("") + "\n" + - calculateDecl({ tornadoContractENSLabelhash }) + - calculateDecl({ stakingRewardsENSLabelhash }) + - calculateDecl({ governanceImplENSLabelhash }); + Object.entries(ensDomains) + .map((e) => calculateLabelDecl(e)) + .join(""); fs.writeFileSync(path.join("data", "ensNodesDeclarations.txt"), solidityCode); diff --git a/scripts/calculateIPFSContenthashes.ts b/scripts/calculateIPFSContenthashes.ts index f0f74dd..a60426f 100644 --- a/scripts/calculateIPFSContenthashes.ts +++ b/scripts/calculateIPFSContenthashes.ts @@ -4,21 +4,20 @@ import fs from "fs"; import path from "path"; import { DeclCalculator } from "./utils"; -import { classicUiIpfsCid, novaUiIpfsCid, relayersUiIpfsCid, docsIpfsCid } from "./constants"; +import { ipfsCids } from "./constants"; const contentHashToBytesMemory = (hash: string) => `hex"${hash}"`; - -const classicUiIPFSContenthash = contentHash.fromIpfs(classicUiIpfsCid); -const novaUiIPFSContenthash = contentHash.fromIpfs(novaUiIpfsCid); -const relayersUiIPFSContenthash = contentHash.fromIpfs(relayersUiIpfsCid); -const docsIPFSContenthash = contentHash.fromIpfs(docsIpfsCid); +const ipfsCidToBytesMemory = (cid: string) => contentHashToBytesMemory(contentHash.fromIpfs(cid)); const solidityDoublePadding = " ".repeat(8); -const { calculateDecl } = new DeclCalculator("bytes memory", solidityDoublePadding, contentHashToBytesMemory); -const solidityCode = - calculateDecl({ classicUiIPFSContenthash }) + - calculateDecl({ novaUiIPFSContenthash }) + - calculateDecl({ relayersUiIPFSContenthash }) + - calculateDecl({ docsIPFSContenthash }); +const { calculateDecl: calculateContenthashDecl } = new DeclCalculator( + "bytes memory", + solidityDoublePadding, + ipfsCidToBytesMemory, + (name: string) => name + "Contenthash" +); +const solidityCode = Object.entries(ipfsCids) + .map((e) => calculateContenthashDecl(e)) + .join(""); fs.writeFileSync(path.join("data", "ensDomainsIPFSContenthashes.txt"), solidityCode); diff --git a/scripts/calculateIpfsV1Cids.ts b/scripts/calculateIpfsV1Cids.ts index a3b8e06..cd4d559 100644 --- a/scripts/calculateIpfsV1Cids.ts +++ b/scripts/calculateIpfsV1Cids.ts @@ -3,15 +3,13 @@ import path from "path"; import CID from "cids"; import { DeclCalculator } from "./utils"; -import { classicUiIpfsCid, novaUiIpfsCid, relayersUiIpfsCid, docsIpfsCid } from "./constants"; +import { ipfsCids } from "./constants"; const convertCIDToV1 = (cidV0: string) => `"${new CID(cidV0).toV1().toString()}"`; -const { calculateDecl } = new DeclCalculator("const", "", convertCIDToV1); -const typescriptCode = - calculateDecl({ classicUiIpfsCid }) + - calculateDecl({ novaUiIpfsCid }) + - calculateDecl({ relayersUiIpfsCid }) + - calculateDecl({ docsIpfsCid }); +const { calculateDecl } = new DeclCalculator("const", "", convertCIDToV1, (name: string) => name + "IpfsCid"); +const typescriptCode = Object.entries(ipfsCids) + .map((e) => calculateDecl(e)) + .join(""); fs.writeFileSync(path.join(".", "data", "ipfsV1CIDs.txt"), typescriptCode); diff --git a/scripts/constants.ts b/scripts/constants.ts index b262899..3ba1d60 100644 --- a/scripts/constants.ts +++ b/scripts/constants.ts @@ -1,4 +1,63 @@ -export const classicUiIpfsCid = "QmSQxyjNpGAMXYBNjkuZAjuAg5JCg1RYoe663XovNQicua"; -export const novaUiIpfsCid = "QmVS4SPsH44oJPCffUZZUGTXqCpSx3eK8UJ8YmZsSDygop"; -export const relayersUiIpfsCid = "QmSUG2SNSPc6UUc6tgTZJWQKExhUGqjxHQPcJNZuU5FcxW"; -export const docsIpfsCid = "QmQPThvEBTCBFLPp16TeHxWGk7oYKth3AGdvYdiw6TyfKV"; +const rootTornadoDomain = "tornadocash.eth"; +const sourcesDomain = "sources." + rootTornadoDomain; +const minifiedSourcesDomain = "minified." + sourcesDomain; +const packagesDomain = "packages." + sourcesDomain; + +export const ensDomains = { + rootTornadoDomain, + sourcesDomain, + minifiedSourcesDomain, + packagesDomain, + downloadScriptSourceDomain: "download." + sourcesDomain, + classicUISourceDomain: "classic-ui." + sourcesDomain, + novaUISourceDomain: "nova." + sourcesDomain, + docsSourceDomain: "docs." + sourcesDomain, + relayersUISourceDomain: "relayers-ui." + sourcesDomain, + tornTokenSourceDomain: "torn-token." + sourcesDomain, + classicRelayerSoftwareSourceDomain: "classic-relayer." + sourcesDomain, + novaRelayerSoftwareSourceDomain: "nova-relayer." + sourcesDomain, + tornadoCliSourceDomain: "cli." + sourcesDomain, + infoPageSourceDomain: "info-page." + sourcesDomain, + classicUIMinifiedDomain: "classic-ui." + minifiedSourcesDomain, + novaMinifiedDomain: "nova." + minifiedSourcesDomain, + tornadoCliMinifiedDomain: "cli." + minifiedSourcesDomain, + websnarkPackageDomain: "websnark." + packagesDomain, + circomlibPackageDomain: "circomlib." + packagesDomain, + snarkjsPackageDomain: "snarkjs." + packagesDomain, + tornadoOraclesPackageDomain: "oracles." + packagesDomain, + gasPriceOraclePackageDomain: "gas-price-oracle." + packagesDomain, + tornadoConfigPackageDomain: "config." + packagesDomain, + anonymityMiningPackageDomain: "anonymity-mining." + packagesDomain, + tornadoTreesPackageDomain: "trees." + packagesDomain, + fixedMerkleTreePackageDomain: "fixed-merkle-tree." + packagesDomain, + txManagerPackageDomain: "tx-manager." + packagesDomain, + merkleRootUpdaterPackageDomain: "merkle-root-updater." + packagesDomain, +}; + +export const ipfsCids = { + downloadInstructionsHtml: "QmX2RqM2g98EM1C7UWx2uW7Cz9ALQSCRkogDxEJDZbNH15", + downloadScriptSource: "QmXrkrmZYvVCBtsZYdpsyhRcfNERYnrcTmjgLfgwWEn2XE", + classicUiSource: "QmacsxDCzyUCsmG6W5Nz5arHPjNms5Bwc7QqfYM6utASWj", + classicRelayerSource: "QmUTA3MABmeNU9RvJK1cQ7L28KRLFVA8ebaq7gotQXAKrg", + novaRelayerSource: "QmbsX9ScTxZ5Tqy1a8ecdQNacStiCDwFufUyCJ5HXrgMSj", + relayersUiSource: "QmT5vRziiwZKDZUkDX4BqxKvXmcz3W2tLtGkE9VrtdCQuu", + novaUiSource: "QmaYVcnwab7eR8JStD11JwXUkiCLfBvth2eByMBSxWhfVP", + docsSource: "QmZC7e8KqB7fdyRFj3iu45i3sTABVsYVnmMzZ1bsn1VpMn", + tornadoCliSource: "Qmc1XYtApEGsJpMfSjTAYQoYHakNyJcfJUtRFC3FBLD1AD", + infoPageSource: "QmQwNEb8SdFkiPDMAk3ncktqbZCTGknVN3sH33LAMSaADB", + classicUiMinified: "QmQGsukwaYhkKJ1bHW3rZJTc83Rh7xFogMMu8GMDRcbAt8", + novaUiMinified: "QmecystQd1aGDfWp93EndSpU8gGGYXgyAhfFEKXsZfPA2m", + tornadoCliMinified: "QmUFAL29scANSqvrVTejoRrpMzKpJJE6j4BKrKGyKNM5XH", + tornTokenSource: "QmfRtPH3gRwTbbNEAfkvVNeGauBAcFHBzuET7JfmKvfFr1", + merkleRootUpdaterPackage: "QmTVin6iNu5Mp6YPo3jTpCNKdE5JdvM4r4tqXZJtac2UQ4", + gasPriceOraclePackage: "QmW8zZ1Dv32j9HpjP3aExNJvxcshYoGTsjQaX8VZzRTXxx", + tornadoOraclesPackage: "QmYUM1Kx6ju5ZBu6TDdRfZZjG64fCNbyKxWySMsLprPQGY", + snarkjsPackage: "QmdoqswophQXo5JrQQnbpWS5562eizT8vAK8XQDsHyKLs5", + websnarkPackage: "QmRqZ55oP7Vyq39cJrqLSAhiLEbhCLm6QTJKghhHHogKmQ", + circomlibPackage: "QmVDdK5YowqaMuQuAPwW2Hq4GSSNebVBfd3qsKUhvQZxVv", + txManagerPackage: "QmYNvuaKH47QJuFairApChBvoRtbezvnWU12tPs8cHUZzA", + fixedMerkleTreePackage: "QmUtj3m6y5sEw4Y7V7PnAS7pKp9gbJGJ2eGAMWnwXAPRP9", + tornadoTreesPackage: "QmanV67Tzu7jLdeVXStjJ7iVVYMPAvnHhmxwsCSXALAtGK", + anonymityMiningPackage: "QmTfy4wGgYMKczEjtKNRZTEpnzfYyqtPhbc3fzJqwPSpzF", + tornadoConfigPackage: "QmRPK6AqffoB721RfaWtRr1GjdpVN7x4g8ZcG27RqvLweR", +}; diff --git a/scripts/test/calculateENSNodes.ts b/scripts/test/calculateENSNodes.ts new file mode 100644 index 0000000..7c2790c --- /dev/null +++ b/scripts/test/calculateENSNodes.ts @@ -0,0 +1,71 @@ +import fs from "fs"; +import path from "path"; + +// @ts-ignore +import { hash } from "@ensdomains/eth-ens-namehash"; +import { keccak_256 } from "js-sha3"; +import { DeclCalculator } from "../utils"; + +// Different domain for Goerli testing +const rootTornadoDomain = "tornadotest.eth"; +const sourcesDomain = "sources." + rootTornadoDomain; +const minifiedSourcesDomain = "minified." + sourcesDomain; +const packagesDomain = "packages." + sourcesDomain; + +export const ensDomains = { + rootTornadoDomain, + sourcesDomain, + minifiedSourcesDomain, + packagesDomain, + downloadScriptSourceDomain: "download." + sourcesDomain, + classicUISourceDomain: "classic-ui." + sourcesDomain, + novaUISourceDomain: "nova." + sourcesDomain, + docsSourceDomain: "docs." + sourcesDomain, + relayersUISourceDomain: "relayers-ui." + sourcesDomain, + tornTokenSourceDomain: "torn-token." + sourcesDomain, + classicRelayerSoftwareSourceDomain: "classic-relayer." + sourcesDomain, + novaRelayerSoftwareSourceDomain: "nova-relayer." + sourcesDomain, + tornadoCliSourceDomain: "cli." + sourcesDomain, + infoPageSourceDomain: "info-page." + sourcesDomain, + classicUIMinifiedDomain: "classic-ui." + minifiedSourcesDomain, + novaMinifiedDomain: "nova." + minifiedSourcesDomain, + tornadoCliMinifiedDomain: "cli." + minifiedSourcesDomain, + websnarkPackageDomain: "websnark." + packagesDomain, + circomlibPackageDomain: "circomlib." + packagesDomain, + snarkjsPackageDomain: "snarkjs." + packagesDomain, + tornadoOraclesPackageDomain: "oracles." + packagesDomain, + gasPriceOraclePackageDomain: "gas-price-oracle." + packagesDomain, + tornadoConfigPackageDomain: "config." + packagesDomain, + anonymityMiningPackageDomain: "anonymity-mining." + packagesDomain, + tornadoTreesPackageDomain: "trees." + packagesDomain, + fixedMerkleTreePackageDomain: "fixed-merkle-tree." + packagesDomain, + txManagerPackageDomain: "tx-manager." + packagesDomain, + merkleRootUpdaterPackageDomain: "merkle-root-updater." + packagesDomain, +}; + +const getLabelhashFromDomain = (ensDomain: string) => "0x" + keccak_256(ensDomain.split(".")[0]); + +const solidityInContractPadding = " ".repeat(4); +const { calculateDecl: calculateNodeDecl } = new DeclCalculator( + "bytes32 internal constant", + solidityInContractPadding, + hash, + (name: string) => name + "Node" +); +const { calculateDecl: calculateLabelDecl } = new DeclCalculator( + "bytes32 internal constant", + solidityInContractPadding, + getLabelhashFromDomain, + (name: string) => name + "Labelhash" +); + +const solidityCode = + Object.entries(ensDomains) + .map((e) => calculateNodeDecl(e)) + .join("") + + "\n" + + Object.entries(ensDomains) + .map((e) => calculateLabelDecl(e)) + .join(""); + +fs.writeFileSync(path.join("data", "test", "ensNodesDeclarations.txt"), solidityCode); diff --git a/scripts/utils.ts b/scripts/utils.ts index 9b1252b..ff27200 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,33 +1,30 @@ type NodeVarObject = { [key: string]: string }; +type NodeVarArray = [string, string]; const solidityCodePadding = " ".repeat(8); const pad = (decl: string, padding: string = solidityCodePadding) => padding + decl + "\n"; class DeclCalculator { - declType!: string; - padding!: string; - transformator!: Function; - public constructor( - declType: string, - padding: string = solidityCodePadding, - transformator: Function = ( + private declType: string, + private padding: string = solidityCodePadding, + private transformator: Function = ( + () => (x: any) => + x + )(), + private variableNameChanger: Function = ( () => (x: any) => x )() - ) { - this.declType = declType; - this.padding = padding; - this.transformator = transformator; - } + ) {} private displayVariableName(varObj: NodeVarObject) { return Object.keys(varObj)[0]; } - public calculateDecl = (varObj: NodeVarObject, type: string = "bytes32") => { - const solidityVariableName = this.displayVariableName(varObj); - const solidityVariableValue = this.transformator(Object.values(varObj)[0]); + public calculateDecl = (varInfo: NodeVarObject | NodeVarArray, type: string = "bytes32") => { + const solidityVariableName = this.variableNameChanger(Array.isArray(varInfo) ? varInfo[0] : this.displayVariableName(varInfo)); + const solidityVariableValue = this.transformator(Array.isArray(varInfo) ? varInfo[1] : Object.values(varInfo)[0]); const solidityDeclaration = `${this.declType || type} ${solidityVariableName} = ${solidityVariableValue};`; return pad(solidityDeclaration, this.padding);