Skip to content
This repository has been archived by the owner on Jun 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #556 from thehubbleproject/feature/sync-public-key…
Browse files Browse the repository at this point in the history
…-registration

Sync public key registration
  • Loading branch information
jacque006 authored Apr 23, 2021
2 parents 42b6f36 + cd31e65 commit c922164
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ genesis.json
types/
cache/
artifacts/
build/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
types/
.github/
cache/
build/
13 changes: 9 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"prettier": "prettier --write \"**/*.{sol,ts,js}\"",
"generate": "hardhat compile && typechain --target ethers-v5 './artifacts/contracts/**/!(*.dbg).json'",
"compile": "hardhat compile",
"tsc": "tsc",
"node": "hardhat node",
"deploy": "ts-node ./scripts/deploy.ts",
"keyless:check": "ts-node ./scripts/keyless.ts --check",
Expand All @@ -34,6 +35,7 @@
"@openzeppelin/contracts": "^3.4.1",
"@typechain/ethers-v5": "^1.0.0",
"@types/chai": "^4.2.15",
"@types/lodash": "^4.14.168",
"@types/mocha": "^8.2.1",
"@types/node": "^14.14.33",
"bn.js": "^5.2.0",
Expand All @@ -51,6 +53,7 @@
},
"dependencies": {
"abort-controller": "^3.0.0",
"fastify": "^3.14.2"
"fastify": "^3.14.2",
"lodash": "^4.17.21"
}
}
82 changes: 69 additions & 13 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,51 @@ import { DeploymentParameters } from "../ts/interfaces";
import fs from "fs";
import { PRODUCTION_PARAMS } from "../ts/constants";
import { StateTree } from "../ts/stateTree";
import { Group } from "../ts/factory";

const argv = require("minimist")(process.argv.slice(2), {
string: ["url", "root", "key", "input", "output"]
const {
url,
root,
key,
input,
output,
numPubkeys,
pubkeyMnemonic
} = require("minimist")(process.argv.slice(2), {
string: [
"url",
"root",
"key",
"input",
"output",
"numPubkeys",
"pubkeyMnemonic"
]
});
/*
Note separate pubkeys with commas
> npm run deploy -- --url http://localhost:8545 \
--root 0x309976060df37ed6961ebd53027fe0c45d3cbbbdfc30a5039e86b2a7aa7fed6e
You can also specify a private key
> npm run deploy -- --key 0xYourPrivateKey
You can specify an Eth1 private key
> npm run deploy -- --key 0xYourPrivateKey
You can specify an initial number of BLS public keys to register and their mnemonic seed (hardhat mnemonic default)
> npm run deploy -- --numPubkeys 32 \
--pubkeyMnemonic 'focus hood pipe manual below record fly pole corn remember define slice kitchen capable search'
You can use a custom parameters.json
> npm run deploy -- --input parameters.json --output ../hubbe-commander/genesis.json
*/

function validateArgv() {
if (pubkeyMnemonic && !numPubkeys) {
throw new Error(
"numPubkeys must be specified if a pubkeyMnemonic is provided"
);
}
}

function getDefaultGenesisRoot(parameters: DeploymentParameters) {
const stateTree = StateTree.new(parameters.MAX_DEPTH);
// An completely empty genesis state
Expand All @@ -28,22 +57,49 @@ function getDefaultGenesisRoot(parameters: DeploymentParameters) {
}

async function main() {
validateArgv();

const provider = new ethers.providers.JsonRpcProvider(
argv.url ?? "http://localhost:8545"
url ?? "http://localhost:8545"
);
const signer = argv.key
? new ethers.Wallet(argv.key).connect(provider)
const signer = key
? new ethers.Wallet(key).connect(provider)
: provider.getSigner();

const parameters = argv.input
? JSON.parse(fs.readFileSync(argv.input).toString())
const parameters = input
? JSON.parse(fs.readFileSync(input).toString())
: PRODUCTION_PARAMS;

parameters.GENESIS_STATE_ROOT =
argv.root || getDefaultGenesisRoot(parameters);
parameters.GENESIS_STATE_ROOT = root || getDefaultGenesisRoot(parameters);
console.log("Deploy with parameters", parameters);

await deployAndWriteGenesis(signer, parameters, argv.output);
const { blsAccountRegistry } = await deployAndWriteGenesis(
signer,
parameters,
output
);

if (numPubkeys) {
console.log(
`Registering ${numPubkeys} pubkeys. Custom mnemonic: ${!!pubkeyMnemonic}`
);
const group = Group.new({
n: pubkeyMnemonic,
mnemonic: pubkeyMnemonic
});
// Convert this to batch register once implemented
for (const user of group.userIterator()) {
await blsAccountRegistry.register(user.pubkey);
}
}
}

main();
main()
.then(() => {
console.log("Deployment complete");
process.exit(0);
})
.catch(err => {
console.error(err);
process.exit(1);
});
39 changes: 37 additions & 2 deletions test/client/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
} from "../../ts/client/features/transfer";
import { SyncerService } from "../../ts/client/services/syncer";
import { PRODUCTION_PARAMS } from "../../ts/constants";
import { USDT } from "../../ts/decimal";
import { deployAll } from "../../ts/deploy";
import { deployKeyless } from "../../ts/deployment/deploy";
import { Group, storageManagerFactory } from "../../ts/factory";
import { Genesis } from "../../ts/genesis";
import * as mcl from "../../ts/mcl";
import { Pubkey } from "../../ts/pubkey";
import { State } from "../../ts/state";

describe("Client Integration", function() {
it("run", async function() {
Expand All @@ -22,15 +25,45 @@ describe("Client Integration", function() {
const provider = signer.provider as providers.Provider;
const genesisEth1Block = await provider.getBlockNumber();
await deployKeyless(signer, false);
const storagePacker = await storageManagerFactory();
const storageSyncer = await storageManagerFactory();

// Setup pubkeys, state for packer & syncer
const tokenID = 1;
const initialBalance = USDT.fromHumanValue("100.12");
const group = Group.new({ n: 32 });
const storagePacker = await storageManagerFactory(group);
const storageSyncer = await storageManagerFactory(group);
for (const user of group.userIterator()) {
const state = State.new(
user.pubkeyID,
tokenID,
initialBalance.l2Value,
0
);
// Setup packer L2 storage
await storagePacker.pubkey.update(
user.pubkeyID,
new Pubkey(user.pubkey)
);
await storagePacker.state.update(user.stateID, state);

// Setup syncer L2 state
// Replace with L1 deposits once implemented
await storageSyncer.state.update(user.stateID, state);
}
await storagePacker.pubkey.commit();
await storagePacker.state.commit();
await storageSyncer.state.commit();

const parameters = PRODUCTION_PARAMS;
parameters.USE_BURN_AUCTION = false;
parameters.GENESIS_STATE_ROOT = storagePacker.state.root;

const contracts = await deployAll(signer, parameters);
for (const user of group.userIterator()) {
// Setup L1 pubkeys
await contracts.blsAccountRegistry.register(user.pubkey);
}

const appID = await contracts.rollup.appID();
group.setupSigners(arrayify(appID));

Expand Down Expand Up @@ -58,6 +91,8 @@ describe("Client Integration", function() {

const syncService = new SyncerService(apiSyncer);
await syncService.initialSync();

assert.equal(storageSyncer.state.root, storagePacker.state.root);
assert.equal(storageSyncer.pubkey.root, storagePacker.pubkey.root);
}).timeout(300000);
});
1 change: 0 additions & 1 deletion test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
} from "../ts/factory";
import { DeploymentParameters } from "../ts/interfaces";
import { MigrationTree, StateTree } from "../ts/stateTree";
import { BurnAuction } from "../types/ethers-contracts/BurnAuction";
import * as mcl from "../ts/mcl";
import {
BodylessCommitment,
Expand Down
4 changes: 2 additions & 2 deletions ts/client/coreAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class SyncedPoint {
}

export interface ICoreAPI {
getlatestBatchID(): Promise<number>;
getLatestBatchID(): Promise<number>;
getState(stateID: number): Promise<State>;
updateState(stateID: number, state: State): Promise<void>;
getPubkey(pubkeyID: number): Promise<Pubkey>;
Expand Down Expand Up @@ -98,7 +98,7 @@ export class CoreAPI implements ICoreAPI {
async getBlockNumber() {
return await this.provider.getBlockNumber();
}
async getlatestBatchID() {
async getLatestBatchID() {
return Number(await this.rollup.nextBatchID()) - 1;
}

Expand Down
21 changes: 12 additions & 9 deletions ts/client/node.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { arrayify } from "@ethersproject/bytes";
import { Group, storageManagerFactory } from "../factory";
import { storageManagerFactory } from "../factory";
import * as mcl from "../../ts/mcl";
import { BigNumber } from "@ethersproject/bignumber";
import { Bidder } from "./services/bidder";
Expand Down Expand Up @@ -55,17 +54,18 @@ export class HubbleNode {
config.providerUrl
);
const signer = provider.getSigner();
const { parameters, auxiliary } = genesis;

const group = Group.new({ n: 32, domain: arrayify(auxiliary.domain) });
const storageManager = await storageManagerFactory(group, {
stateTreeDepth: parameters.MAX_DEPTH
const { MAX_DEPTH } = genesis.parameters;
const storageManager = await storageManagerFactory({
stateTreeDepth: MAX_DEPTH,
pubkeyTreeDepth: MAX_DEPTH
});
const api = CoreAPI.new(storageManager, genesis, provider, signer);

const feeReceiver = group.getUser(0).stateID;
const tokenID = (await storageManager.state.get(feeReceiver)).tokenID;

// Hardcoded for now, will be configurable in
// https://github.com/thehubbleproject/hubble-contracts/issues/557
const feeReceiver = 0;
const tokenID = 1;
const pool = new TransferPool(tokenID, feeReceiver);

const packer = new Packer(api, pool);
Expand All @@ -74,6 +74,9 @@ export class HubbleNode {
api.contracts.burnAuction
);
const syncer = new SyncerService(api);
// In the future, we will want to delay starting up the rpc client
// until after the initial sync is completed (HTTP 503).
// https://github.com/thehubbleproject/hubble-contracts/issues/558
const rpc = await RPC.init(config.rpcPort, storageManager, pool);
return new this(nodeType, provider, syncer, packer, bidder, rpc);
}
Expand Down
Loading

0 comments on commit c922164

Please sign in to comment.