-
Notifications
You must be signed in to change notification settings - Fork 2
[v1.0] Domain data aggregation and validation for use in the migration #133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
46f1024
WIP reconfigure to simplify process and reduce queries
JamesEarle 113e547
WIP more changes, some EOL
JamesEarle 5828a6b
run script against all users and additional validation to identify sp…
JamesEarle c65ee26
change to way to read and structure database calls in 01 script for v…
JamesEarle 6ad1dc1
resolve merge conflict in .gitignore
JamesEarle 53ce619
Merge branch 'support/v1.0' into migration-code
JamesEarle 08315e1
remove invalid marker for split ownership domains, general flow for r…
JamesEarle bd68f19
add reference to constants
JamesEarle 0eef123
delete unused imports
JamesEarle 209f2a0
comment out private key used in HH config mainnet
JamesEarle 14ccd0b
lint in CI fixes
JamesEarle c5c96a7
add ts eslint disable as well
JamesEarle 4d45eb3
change in validate script for parens
JamesEarle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,5 @@ docker*.tgz | |
|
||
# We don't ever use the generated manifests | ||
.openzeppelin | ||
|
||
output |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as hre from "hardhat"; | ||
import { getDomains } from "./subgraph"; | ||
import { Domain, InvalidDomain, User, ValidatedUser } from "./types"; | ||
import { getDBAdapter } from "./database"; | ||
import { getZNS } from "./zns-contract-data"; | ||
import { validateDomain } from "./validate" | ||
|
||
|
||
const main = async () => { | ||
const [ migrationAdmin ] = await hre.ethers.getSigners(); | ||
|
||
// Keeping as separate collections from the start will help downstream registration | ||
const rootDomainObjects = await getDomains(true); | ||
const subdomainObjects = await getDomains(false); | ||
|
||
console.log(`Found ${rootDomainObjects.length + subdomainObjects.length} domains`); | ||
|
||
const env = process.env.ENV_LEVEL; | ||
|
||
if (!env) throw Error("No ENV_LEVEL set in .env file"); | ||
|
||
const zns = await getZNS(migrationAdmin, env); | ||
|
||
const validRoots : Array<Domain> = []; | ||
const validSubs : Array<Domain> = []; | ||
const invalidDomains : Array<InvalidDomain> = []; | ||
|
||
// Doing this creates strong typing and extensibility that allows | ||
// the below `insertMany` calls to add properties to the object for `_id` | ||
const roots = rootDomainObjects.map((d) => { return d as Domain; }); | ||
const subs = subdomainObjects.map((d) => { return d as Domain; }); | ||
|
||
// Can iterate all at once for simplicity | ||
let index = 0; | ||
for(let domain of [...roots, ...subs]) { | ||
try { | ||
await validateDomain(domain, zns); | ||
|
||
if (domain.isWorld) { | ||
validRoots.push({ ...domain } as Domain); | ||
} else { | ||
validSubs.push({ ...domain } as Domain); | ||
} | ||
} catch (e) { | ||
// For debugging we keep invalid domains rather than throw errors | ||
invalidDomains.push({ message: (e as Error).message, domain: domain }); | ||
} | ||
|
||
console.log(`Processed ${++index} domains`); | ||
} | ||
|
||
// Connect to database collection and write user domain data to DB | ||
const dbName = process.env.MONGO_DB_NAME_WRITE; | ||
if (!dbName) throw Error("No DB name given"); | ||
|
||
const uri = process.env.MONGO_DB_URI_WRITE; | ||
if (!uri) throw Error("No connection string given"); | ||
|
||
let client = (await getDBAdapter(uri)).db(dbName); | ||
|
||
const rootCollName = process.env.MONGO_DB_ROOT_COLL_NAME || "root-domains"; | ||
const subCollName = process.env.MONGO_DB_SUB_COLL_NAME || "subdomains"; | ||
|
||
// To avoid duplicate data, we clear the DB before any inserts | ||
await client.dropCollection(rootCollName); | ||
await client.collection(rootCollName).insertMany(validRoots); | ||
|
||
await client.dropCollection(subCollName); | ||
await client.collection(subCollName).insertMany(validSubs); | ||
|
||
// Domains that have split ownership will be considered invalid domains | ||
if (invalidDomains.length > 0) { | ||
const invalidCollName = process.env.MONGO_DB_INVALID_COLL_NAME || "invalid-domains"; | ||
await client.dropCollection(invalidCollName); | ||
await client.collection(invalidCollName).insertMany(invalidDomains); | ||
} | ||
}; | ||
|
||
main() | ||
.then(() => process.exit(0)) | ||
.catch(error => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import * as hre from "hardhat"; | ||
import { Domain } from "./types"; | ||
import * as fs from "fs"; | ||
import { deployZNS } from "../../../test/helpers"; | ||
import { postMigrationValidation, registerDomainsBulk } from "./registration"; | ||
import { getZNS } from "./zns-contract-data"; | ||
import { ROOTS_FILENAME, SUBS_FILENAME } from "./constants"; | ||
import { IZNSContracts } from "../../deploy/campaign/types"; | ||
import { getDBAdapter } from "./database"; | ||
|
||
// Script #2 to be run AFTER validation of the domains with subgraph | ||
const main = async () => { | ||
const [ migrationAdmin, governor, admin ] = await hre.ethers.getSigners(); | ||
|
||
// Overall flow will be: | ||
// connect to DB | ||
// read all roots from mongodb | ||
// while there are unregistered root domains: | ||
// register a batch | ||
|
||
// read all subs with depth 1 from mongodb | ||
// while there are unregistered subdomains: | ||
// register a batch | ||
// read all subs with depth 2 from mongodb | ||
// while there are unregistered subdomains: | ||
// register a batch | ||
// read all subs with depth 3 from mongodb | ||
// while there are unregistered subdomains: | ||
// register a batch | ||
|
||
// During above we will pack transactions with to always have 50 domains | ||
// so if only 45 root domains remain at the end, we will also send the first 5 depth 1 subdomains | ||
|
||
// Steps to register a batch will mean using the Safe REST API to create a transaction | ||
// for the owning safe that calls `registerRootDomainBulk` or `registerSubdomainBulk` | ||
// Then we will wait for the transaction to be executed | ||
// Technically we could also sign each tx and execute this way | ||
|
||
let zns : IZNSContracts; | ||
|
||
const env = process.env.ENV_LEVEL; | ||
|
||
if (!env) throw Error("No ENV_LEVEL set in .env file"); | ||
|
||
// Get instance of ZNS from DB | ||
zns = await getZNS(migrationAdmin, env); | ||
|
||
// Connect to database collection and write user domain data to DB | ||
const dbName = process.env.MONGO_DB_NAME_WRITE; | ||
if (!dbName) throw Error("No DB name given"); | ||
|
||
const uri = process.env.MONGO_DB_URI_WRITE; | ||
if (!uri) throw Error("No connection string given"); | ||
|
||
let client = (await getDBAdapter(uri)).db(dbName); | ||
|
||
const rootCollName = process.env.MONGO_DB_ROOT_COLL_NAME || "root-domains"; | ||
JamesEarle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Get all documents from collection | ||
const domains = await client.collection(rootCollName).find().toArray(); | ||
|
||
console.log(domains.length); | ||
|
||
const startTime = Date.now(); | ||
|
||
// How many domains we will register in a single transaction | ||
const sliceSize = 50; | ||
|
||
process.exit(0); | ||
JamesEarle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
main().catch(error => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { MongoClient, ServerApiVersion } from "mongodb"; | ||
|
||
export let dbVersion : string; | ||
|
||
export const getDBAdapter = async ( | ||
connectionString : string | ||
): Promise<MongoClient> => { | ||
const mongoClient = new MongoClient( | ||
connectionString, | ||
{ | ||
serverApi: { | ||
version: ServerApiVersion.v1, | ||
strict: true, | ||
deprecationErrors: true, | ||
} | ||
} | ||
); | ||
|
||
return await mongoClient.connect(); | ||
} | ||
|
||
export const getZNSFromDB = async () => { | ||
let version; | ||
let uri; | ||
let dbName; | ||
|
||
version = process.env.MONGO_DB_VERSION; | ||
uri = process.env.MONGO_DB_URI; | ||
dbName = process.env.MONGO_DB_NAME; | ||
|
||
if (!uri) { | ||
throw new Error("Failed to connect: missing MongoDB URI or version"); | ||
} | ||
|
||
let dbAdapter = await getDBAdapter(uri); | ||
|
||
if(!dbName) { | ||
throw new Error(`Failed to connect: database "${dbName}" not found`); | ||
} | ||
|
||
const db = await dbAdapter.db(dbName); | ||
|
||
let zns = await db.collection("contracts").find( | ||
{ version } | ||
).toArray(); | ||
|
||
return zns; | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.