Add scripts to calculate all new ENS nodes and IPFS hashes

This commit is contained in:
Theo 2023-09-29 05:12:03 -07:00
parent eaeb72357d
commit b569bd3f77
9 changed files with 191 additions and 73 deletions

2
.gitignore vendored

@ -23,3 +23,5 @@ yarn.lock
# VScode files
.vscode
test.ts

2
.nvmrc

@ -1 +1 @@
v20.3.0
v16.20.2

@ -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",

@ -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);

@ -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);

@ -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);

@ -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",
};

@ -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);

@ -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);