Skip to content
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

Fix support for validator key rotation, add end-to-end test #1643

Merged
merged 219 commits into from
Nov 16, 2019
Merged
Show file tree
Hide file tree
Changes from 194 commits
Commits
Show all changes
219 commits
Select commit Hold shift + click to select a range
02f39db
Most things that don't touch incentives
Sep 19, 2019
0f226c8
Trying to get things to compile
Sep 19, 2019
721b9da
More work
Sep 19, 2019
17a624e
More changes
Sep 19, 2019
6ce7f7e
Compiling
Sep 20, 2019
c19b8b6
Updated validators test
Sep 21, 2019
a6921d3
LockedGold tests passing
Sep 24, 2019
871d06d
Validators tests passing
Sep 24, 2019
e0e8cf7
Fix governance tests
Sep 24, 2019
223536d
Add election test file
Sep 24, 2019
651009d
Election tests passing
Sep 26, 2019
a795125
Fix governance test
Sep 30, 2019
9b4d431
Most e2e governance tests passing
Oct 1, 2019
e866ca7
end to end tests passing
Oct 2, 2019
3a31670
Point to celo-blockchain branch
Oct 2, 2019
3f35c70
Merge master
Oct 2, 2019
c466d78
Add some natspecs
Oct 2, 2019
f02b05a
Linting
Oct 2, 2019
70d7478
Small fix
Oct 2, 2019
69f6ab2
ContractKit building
Oct 3, 2019
15d2e8c
cli builds
Oct 3, 2019
d6ef3ec
Update oclif
Oct 3, 2019
615ec4f
Checkpoint
Oct 3, 2019
1bbf1e0
Merge master
Oct 3, 2019
3ff2fe4
CLI seems to be working
Oct 3, 2019
d3b83c8
cleanup
Oct 3, 2019
2887651
Fix
Oct 3, 2019
2d61f63
Fix
Oct 3, 2019
a427d46
Begin work on validator/group payments
Oct 4, 2019
47a247c
Added test for epoch payment distribution
Oct 4, 2019
767c651
Validator set changing again
Oct 5, 2019
7f82317
Epoch payments and rewards appear to be working
Oct 6, 2019
50d6029
Update membership history upon validator registration
Oct 6, 2019
999bca2
End to end tests passing
Oct 7, 2019
03dc663
Add epoch size precompile, among other things
Oct 8, 2019
055d50f
Merge master
Oct 8, 2019
b491453
Revert "Feature #909 proxy delegatecall (#1152)"
asaj Oct 8, 2019
9cccd70
Merge branch 'revert-1152-feature/909-proxy-delegatecall' into asaj/p…
Oct 8, 2019
96f7a7a
Governance end-to-end tests working again
Oct 8, 2019
e40eaf0
Address comments
Oct 8, 2019
2fd2f9d
Merge master
Oct 9, 2019
adcad0b
Fix linting issues
Oct 9, 2019
53e4977
Make things build, tests pass
Oct 9, 2019
c2ea8e1
Merge branch 'master' into asaj/pos
Oct 9, 2019
ed62a4d
Merge asaj/pos
Oct 9, 2019
a5aa266
Fix unit tests
Oct 9, 2019
115a457
Fix migration
Oct 9, 2019
884773b
Add addFirstMember function
Oct 9, 2019
b2858d0
Rework balance requirements
Oct 10, 2019
0492b15
Fix build issues in contractkit
Oct 10, 2019
c0c1f27
Merge master
Oct 10, 2019
3c8739c
Merge asaj/pos
Oct 10, 2019
264a7f5
Fix
Oct 10, 2019
99d3fcc
Remove registry from governance test
Oct 10, 2019
7d9c5cc
Fix linting issues
Oct 10, 2019
f15e844
Add missing cli doc
Oct 10, 2019
993339c
Governance end-to-end test passing
Oct 10, 2019
44f9a43
Fix migration
Oct 10, 2019
3f5c804
Merge branch 'master' into asaj/pos
Oct 10, 2019
1ca67ac
Merge asaj/pos
Oct 10, 2019
2abdd08
Merge branch 'master' into asaj/pos
Oct 10, 2019
f59ca01
Fix CLI build
Oct 10, 2019
00f8061
Add electabilityThreshold enforcement
Oct 10, 2019
aba8552
Don't pay out epoch payments unless validator and group meet balance …
Oct 10, 2019
16f476c
Don't pay out epoch rewards unless the group meets balance requirements
Oct 10, 2019
3616cc6
Fix migrations
Oct 10, 2019
64016a7
Beef up documentation
Oct 11, 2019
6ffdd36
Merge branch 'master' into asaj/pos
Oct 11, 2019
b494b87
Merge branch 'master' into asaj/pos-2
Oct 11, 2019
67966e0
Merge asaj/pos
Oct 11, 2019
fb5e8b4
Fix linting issues
Oct 11, 2019
449e1ed
Add documentation
Oct 11, 2019
143a69c
Fix interface
Oct 11, 2019
1f18108
Expire previously upvoted proposals
Oct 11, 2019
506a77b
Address comments
Oct 11, 2019
23054fc
Merge branch 'master' into asaj/pos
Oct 11, 2019
0e207d0
Point to asaj/pos-2
Oct 11, 2019
90e8b58
Address comments
Oct 14, 2019
32557cf
Merge master
Oct 14, 2019
610cfe3
Base group locked gold requirement on number of members
Oct 16, 2019
b8e1797
Address comments
Oct 16, 2019
631894a
Merge master
Oct 16, 2019
4a4d6e2
Address comments
Oct 16, 2019
1d36857
Merge branch 'master' into asaj/pos
Oct 16, 2019
f3515ac
Fix tests, linting
Oct 16, 2019
c697213
Merge branch 'master' into asaj/pos
Oct 16, 2019
9aa6ec3
Remove bondeddeposits test
Oct 16, 2019
ed8e5a0
Merge branch 'master' into asaj/pos
Oct 16, 2019
89364ab
Fix test
Oct 16, 2019
98d8feb
Merge branch 'master' into asaj/pos
Oct 16, 2019
d85fc78
Merge asaj/pos
Oct 16, 2019
4faaf75
Merge master
Oct 16, 2019
931ceba
Address comments; remove url and authorizedBy.active, allow for varia…
Oct 18, 2019
92e254e
Fix build
Oct 18, 2019
a288e2b
Merge master
Oct 18, 2019
d9c2cc0
Fix migrations, end-to-end tests
Oct 18, 2019
0b894ac
Fix tests
Oct 18, 2019
44aa9f9
Update CLI docs
Oct 18, 2019
262c002
Fix end-to-end transfer tests
Oct 18, 2019
7346fa8
Merge branch 'master' into asaj/pos-2
Oct 18, 2019
97372e7
Fix contractkit tests
Oct 18, 2019
15ace64
Merge master
Oct 22, 2019
c6b2656
merge master
Oct 22, 2019
ef71139
Fix contractkit tests
Oct 22, 2019
c152286
Merge branch 'asaj/pos-2' into asaj/pos-3
Oct 22, 2019
b8eafd7
Fix
Oct 22, 2019
3847bef
Cleanup
Oct 22, 2019
ae1be93
Fix circle config
Oct 22, 2019
2b1da94
Contract unit tests passing
Oct 22, 2019
19488c7
Re-add isVoting tests
Oct 22, 2019
e3e3809
Small cleanup
Oct 22, 2019
fb7c235
Merge branch 'master' into asaj/pos-2
Oct 22, 2019
e39ff0a
Clean up election setters
Oct 23, 2019
1eb0e40
Merge branch 'master' into asaj/pos-2
Oct 23, 2019
5a43d3f
Add first pass at epoch rewards
Oct 23, 2019
035e7e2
Merge master
Oct 24, 2019
44d6f51
Fix contractkit test
Oct 24, 2019
aaf02cd
Remove outdated comment
Oct 24, 2019
ec88d47
More work
Oct 24, 2019
5e2ec52
Merge branch 'asaj/pos-2' into asaj/pos-3
Oct 24, 2019
7e60132
Merge master
Oct 24, 2019
a6c9bb6
Merge branch 'master' into asaj/pos-3
Oct 25, 2019
59dedea
Fix Validators contract wrapper
Oct 25, 2019
7c25aed
Merge branch 'master' into asaj/pos-3
Oct 30, 2019
172c7ec
Merge branch 'asaj/pos-3' into asaj/pos-4
Oct 30, 2019
367429d
Unit tests for EpochRewards passing
Oct 31, 2019
6fa6ee1
Merge master
Oct 31, 2019
9281b4c
Make precompile public
Oct 31, 2019
15c928e
Merge branch 'master' into asaj/pos-3
Oct 31, 2019
95c77d9
Fix migrations
Oct 31, 2019
4c609ec
Merge branch 'asaj/pos-3' into asaj/pos-4
Oct 31, 2019
e2eec9b
end-to-end tests passing, not accounting for voting yield and multiplier
Nov 1, 2019
c561862
Merge master
Nov 1, 2019
2bc75cc
Fix typo
Nov 1, 2019
72ff0ba
end-to-end tests adjusted for rewards multiplier
Nov 1, 2019
568659c
end-to-end tests working
Nov 1, 2019
6316dde
merge master
Nov 1, 2019
a871d67
Fix merge conflicts
Nov 1, 2019
fc95abc
Merge branch 'master' into asaj/pos-3
Nov 2, 2019
9163be1
Merge asaj/pos-3
Nov 2, 2019
b4638d5
Fix linting
Nov 2, 2019
9fe10d7
Add natspecs
Nov 2, 2019
990fc14
reduce gold requirement for contractkit tests
Nov 2, 2019
5d910c9
Be sure to migrate random contract in validator order end-to-end tests
Nov 2, 2019
9d28444
Merge branch 'asaj/pos-3' into asaj/pos-4
Nov 2, 2019
6bc0a1d
Merge master
Nov 2, 2019
e4a9c0b
Small cleanup
Nov 4, 2019
896b08c
Merge branch 'master' into asaj/pos-4
Nov 7, 2019
e51e20d
Update packages/protocol/contracts/governance/EpochRewards.sol
Nov 7, 2019
8d831ec
Update packages/protocol/contracts/governance/EpochRewards.sol
Nov 7, 2019
9ee4f02
Address comments
Nov 7, 2019
464ec62
Address comments
Nov 7, 2019
c2e9f00
WIP
Nov 8, 2019
106a27f
Tests passing other than round robin proposing
Nov 8, 2019
231eed1
Merge master
Nov 9, 2019
531e319
Address comments
Nov 9, 2019
5af2e3b
Fix tests
Nov 9, 2019
bec525b
Fix tests
Nov 9, 2019
e3f7c88
Merge branch 'master' into asaj/pos-4
Nov 9, 2019
10f3149
Delte comment
Nov 9, 2019
8afe7e5
Merge branch 'master' into asaj/pos-4
Nov 9, 2019
767afe3
Key rotation e2e test working
Nov 10, 2019
75610af
Merge master
Nov 10, 2019
1f0079b
remove \.only
Nov 10, 2019
47d2c65
Authorize and pop cli commands seem to work
Nov 10, 2019
649f7a1
Merge branch 'master' into asaj/pos-4
Nov 10, 2019
cca1e4d
Merge branch 'asaj/pos-4' of https://github.com/celo-org/celo-monorep…
Nov 10, 2019
a4090d2
Merge asaj/pos-4
Nov 10, 2019
1e3b012
Cleanup
Nov 10, 2019
e8bc744
Update exchange tests
Nov 10, 2019
fe90660
Merge branch 'asaj/pos-4' into asaj/e2e-key-swap
Nov 10, 2019
d5f0bca
Fix docstring
Nov 10, 2019
3f7cb22
Do not connect validator signers directly to any validators
Nov 10, 2019
6364667
Fix tests
Nov 10, 2019
a33012b
Fix authorize test
Nov 10, 2019
90796c1
Fix linting
Nov 10, 2019
d8265aa
Fix reserve tests
Nov 10, 2019
11d120d
Fix end-to-end tests
Nov 10, 2019
5552c2e
Merge asaj/pos-4
Nov 10, 2019
117d581
Remove unsupported test
Nov 10, 2019
0cc9273
Merge master
Nov 10, 2019
cf50693
Fix tests
Nov 10, 2019
cc2684f
Merge branch 'asaj/pos-4' into asaj/e2e-key-swap
Nov 10, 2019
4f7d450
Remove unused import
Nov 10, 2019
93571b2
Merge branch 'master' into asaj/pos-4
Nov 11, 2019
6fb7a33
Address comments
Nov 11, 2019
2e17037
Whoops
Nov 11, 2019
23776ee
Fix epoch rewards tests
Nov 11, 2019
d7520fb
Merge asa/pos-4
Nov 11, 2019
d80ab32
WIP
Nov 12, 2019
73730fb
Most unit tests passing
Nov 12, 2019
036d934
WIP
Nov 12, 2019
5f35fa9
Merge master
Nov 12, 2019
41f0dcf
end-to-end governance test passing
Nov 12, 2019
c29f513
Remove ecrecoverpublickey precompile
Nov 12, 2019
4248584
Merge branch 'master' into asaj/e2e-key-swap
Nov 12, 2019
8799b0a
Add updateEcdsaKey test
Nov 12, 2019
3039042
remove .only
Nov 12, 2019
ac0c53c
Merge branch 'master' into asaj/e2e-key-swap
Nov 12, 2019
10171dc
Update docs
Nov 12, 2019
05fb26c
Update dependencies
Nov 12, 2019
a15ffaa
Fix governance test
Nov 12, 2019
0fdbc23
Merge master
Nov 14, 2019
1d6ad57
Address comments
Nov 14, 2019
627b9f6
Make things compile
Nov 14, 2019
d550f1e
Finish removal of end-to-end-geth-integration-sync-test
Nov 14, 2019
998ead7
Fix unit tests
Nov 14, 2019
4b2c9ca
Merge branch 'master' into asaj/e2e-key-swap
Nov 14, 2019
4b498b9
Merge branch 'master' into asaj/e2e-key-swap
Nov 14, 2019
54f0bd2
Merge master
Nov 14, 2019
bb16d98
Fix tests
Nov 14, 2019
a0d7503
Remove unnecessary awaits
Nov 14, 2019
beab2c2
Merge master
Nov 15, 2019
2c4b3c1
Fix build
Nov 15, 2019
05f8903
Merge master, address comments
Nov 15, 2019
c9c01d9
WIP
Nov 15, 2019
360b473
Fix attestations test
Nov 15, 2019
4e97b48
Fix lint
Nov 15, 2019
bca30f7
Merge master
Nov 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 230 additions & 73 deletions packages/celotool/src/e2e-tests/governance_tests.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/celotool/src/e2e-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export async function init(gethBinaryPath: string, datadir: string, genesisPath:
}

export async function importPrivateKey(gethBinaryPath: string, instance: GethInstanceConfig) {
const keyFile = '/tmp/key.txt'
const keyFile = `/${getDatadir(instance)}/key.txt`
fs.writeFileSync(keyFile, instance.privateKey)
console.info(`geth:${instance.name}: import account`)
await execCmdWithExitOnFailure(
Expand Down
24 changes: 21 additions & 3 deletions packages/cli/src/commands/account/authorize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,32 @@ process.env.NO_SYNCCHECK = 'true'
testWithGanache('account:authorize cmd', (web3: Web3) => {
test('can authorize account', async () => {
const accounts = await web3.eth.getAccounts()
await Register.run(['--from', accounts[0], '--name', 'Chapulin Colorado'])
await Authorize.run(['--from', accounts[0], '--role', 'validation', '--to', accounts[1]])
await Register.run(['--from', accounts[0]])
await Authorize.run([
'--from',
accounts[0],
'--role',
'validator',
'--signer',
accounts[1],
'--pop',
'0x1b9fca4bbb5bfb1dbe69ef1cddbd9b4202dcb6b134c5170611e1e36ecfa468d7b46c85328d504934fce6c2a1571603a50ae224d2b32685e84d4d1a1eebad8452eb',
])
})

test('fails if from is not an account', async () => {
const accounts = await web3.eth.getAccounts()
await expect(
Authorize.run(['--from', accounts[0], '--role', 'validation', '--to', accounts[1]])
Authorize.run([
'--from',
accounts[0],
'--role',
'validator',
'--signer',
accounts[1],
'--pop',
'0x1b9fca4bbb5bfb1dbe69ef1cddbd9b4202dcb6b134c5170611e1e36ecfa468d7b46c85328d504934fce6c2a1571603a50ae224d2b32685e84d4d1a1eebad8452eb',
])
).rejects.toThrow()
})
})
33 changes: 14 additions & 19 deletions packages/cli/src/commands/account/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,47 @@ import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class Authorize extends BaseCommand {
static description = 'Authorize an attestation, validation or vote signing key'
static description = 'Authorize an attestation, validator, or vote signer'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true }),
role: flags.string({
char: 'r',
options: ['vote', 'validation', 'attestation'],
options: ['vote', 'validator', 'attestation'],
description: 'Role to delegate',
required: true,
}),
to: Flags.address({ required: true }),
pop: flags.string({
description: 'Proof-of-possession of the signer key',
required: true,
}),
signer: Flags.address({ required: true }),
}

static args = []

static examples = [
'authorize --from 0x5409ED021D9299bf6814279A6A1411A7e866A631 --role vote --to 0xc1912fEE45d61C87Cc5EA59DaE31190FFFFf232d',
'authorize --from 0x5409ED021D9299bf6814279A6A1411A7e866A631 --role vote --signer 0x6ecbe1db9ef729cbe972c83fb886247691fb6beb --pop 0x1b9fca4bbb5bfb1dbe69ef1cddbd9b4202dcb6b134c5170611e1e36ecfa468d7b46c85328d504934fce6c2a1571603a50ae224d2b32685e84d4d1a1eebad8452eb',
]

async run() {
const res = this.parse(Authorize)

if (!res.flags.role) {
this.error(`Specify role with --role`)
return
}

if (!res.flags.to) {
this.error(`Specify authorized address with --to`)
return
}

this.kit.defaultAccount = res.flags.from
const accounts = await this.kit.contracts.getAccounts()
const sig = accounts.parseSignatureOfAddress(res.flags.from, res.flags.signer, res.flags.pop)

await newCheckBuilder(this)
.isAccount(res.flags.from)
.runChecks()

let tx: any
if (res.flags.role === 'vote') {
tx = await accounts.authorizeVoteSigner(res.flags.from, res.flags.to)
} else if (res.flags.role === 'validation') {
tx = await accounts.authorizeValidationSigner(res.flags.from, res.flags.to)
tx = await accounts.authorizeVoteSigner(res.flags.signer, sig)
} else if (res.flags.role === 'validator') {
tx = await accounts.authorizeValidatorSigner(res.flags.signer, sig)
} else if (res.flags.role === 'attestation') {
tx = await accounts.authorizeAttestationSigner(res.flags.from, res.flags.to)
tx = await accounts.authorizeAttestationSigner(res.flags.signer, sig)
} else {
this.error(`Invalid role provided`)
return
Expand Down
28 changes: 28 additions & 0 deletions packages/cli/src/commands/account/proof-of-possession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { serializeSignature } from '@celo/utils/lib/signatureUtils'
import { BaseCommand } from '../../base'
import { printValueMap } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class ProofOfPossession extends BaseCommand {
static description = 'Generate proof-of-possession to be used to authorize a signer'

static flags = {
...BaseCommand.flags,
signer: Flags.address({ required: true }),
account: Flags.address({ required: true }),
}

static examples = [
'proof-of-possession --account 0x5409ed021d9299bf6814279a6a1411a7e866a631 --signer 0x6ecbe1db9ef729cbe972c83fb886247691fb6beb',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As naming czar, I wonder what you think about prove-possession as our commands are generally actions/verbs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that's a bit misleading, since we're not actually proving possession here, but merely generating the pop. Wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm, only thing I might add is generate-pop?

]

async run() {
const res = this.parse(ProofOfPossession)
const accounts = await this.kit.contracts.getAccounts()
const pop = await accounts.generateProofOfSigningKeyPossession(
res.flags.account,
res.flags.signer
)
printValueMap({ signature: serializeSignature(pop) })
}
}
11 changes: 8 additions & 3 deletions packages/cli/src/commands/account/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ export default class Register extends BaseCommand {

static flags = {
...BaseCommand.flags,
name: flags.string({ required: true }),
name: flags.string(),
from: Flags.address({ required: true }),
}

static args = []

static examples = ['register']
static examples = [
'register --from 0x5409ed021d9299bf6814279a6a1411a7e866a631',
'register --from 0x5409ed021d9299bf6814279a6a1411a7e866a631 --name test-account',
]

async run() {
const res = this.parse(Register)
Expand All @@ -26,6 +29,8 @@ export default class Register extends BaseCommand {
.isNotAccount(res.flags.from)
.runChecks()
await displaySendTx('register', accounts.createAccount())
await displaySendTx('setName', accounts.setName(res.flags.name))
if (res.flags.name) {
await displaySendTx('setName', accounts.setName(res.flags.name))
}
}
}
43 changes: 0 additions & 43 deletions packages/cli/src/commands/validator/publicKey.ts

This file was deleted.

17 changes: 12 additions & 5 deletions packages/cli/src/commands/validator/register.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { addressToPublicKey } from '@celo/lib/address'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { getPubKeyFromAddrAndWeb3 } from '../../utils/helpers'

export default class ValidatorRegister extends BaseCommand {
static description = 'Register a new Validator'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: 'Address for the Validator' }),
publicKey: Flags.publicKey({ required: true }),
ecdsaKey: Flags.ecdsaPublicKey({ required: true }),
blsKey: Flags.blsPublicKey({ required: true }),
blsPop: Flags.blsProofOfPossession({ required: true }),
}

static examples = [
'register --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95 --publicKey 0xc52f3fab06e22a54915a8765c4f6826090cfac5e40282b43844bf1c0df83aaa632e55b67869758f2291d1aabe0ebecc7cbf4236aaa45e3e0cfbf997eda082ae19d3e1d8f49f6b0d8e9a03d80ca07b1d24cf1cc0557bdcc04f5e17a46e35d02d0d411d956dbd5d2d2464eebd7b74ae30005d223780d785d2abc5644fac7ac29fb0e302bdc80c81a5d45018b68b1045068a4b3a4861c93037685fd0d252d7405011220a66a6257562d0c26dabf64485a1d96bad27bb1c0fd6080a75b0ec9f75b50298a2a8e04b02b2688c8104fca61fb00',
'register --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95 --ecdsaKey 0xc52f3fab06e22a54915a8765c4f6826090cfac5e40282b43844bf1c0df83aaa632e55b67869758f2291d1aabe0ebecc7cbf4236aaa45e3e0cfbf997eda082ae1 --blsKey 0x9d3e1d8f49f6b0d8e9a03d80ca07b1d24cf1cc0557bdcc04f5e17a46e35d02d0d411d956dbd5d2d2464eebd7b74ae300 --blsPop 0x05d223780d785d2abc5644fac7ac29fb0e302bdc80c81a5d45018b68b1045068a4b3a4861c93037685fd0d252d7405011220a66a6257562d0c26dabf64485a1d96bad27bb1c0fd6080a75b0ec9f75b50298a2a8e04b02b2688c8104fca61fb00',
]

async run() {
const res = this.parse(ValidatorRegister)
this.kit.defaultAccount = res.flags.from
Expand All @@ -31,12 +34,16 @@ export default class ValidatorRegister extends BaseCommand {

await displaySendTx(
'registerValidator',
validators.registerValidator(res.flags.publicKey as any)
validators.registerValidator(
res.flags.ecdsaKey as any,
res.flags.blsKey as any,
res.flags.blsPop as any
)
)

// register encryption key on accounts contract
// TODO: Use a different key data encryption
const pubKey = await getPubKeyFromAddrAndWeb3(res.flags.from, this.web3)
const pubKey = await addressToPublicKey(res.flags.from, this.web3)
// TODO fix typing
const setKeyTx = accounts.setAccountDataEncryptionKey(pubKey as any)
await displaySendTx('Set encryption key', setKeyTx)
Expand Down
36 changes: 36 additions & 0 deletions packages/cli/src/commands/validator/update-bls-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class ValidatorUpdateBlsKey extends BaseCommand {
static description = 'Update BLS key for a validator'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: "Validator's address" }),
blsKey: Flags.blsPublicKey({ required: true }),
blsPop: Flags.blsProofOfPossession({ required: true }),
}

static examples = [
'update-bls-key --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95 --blsKey 0x9d3e1d8f49f6b0d8e9a03d80ca07b1d24cf1cc0557bdcc04f5e17a46e35d02d0d411d956dbd5d2d2464eebd7b74ae300 --blsPop 0x05d223780d785d2abc5644fac7ac29fb0e302bdc80c81a5d45018b68b1045068a4b3a4861c93037685fd0d252d7405011220a66a6257562d0c26dabf64485a1d96bad27bb1c0fd6080a75b0ec9f75b50298a2a8e04b02b2688c8104fca61fb00',
]
async run() {
const res = this.parse(ValidatorUpdateBlsKey)
this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()
const accounts = await this.kit.contracts.getAccounts()

await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerAccountIsValidator()
.runChecks()

await displaySendTx(
'updateBlsKey',
validators.updateBlsKey(res.flags.blsKey as any, res.flags.blsPop as any)
)
}
}
2 changes: 1 addition & 1 deletion packages/cli/src/utils/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class CheckBuilder {
'Signer can sign Validator Txs',
this.withAccounts((lg) =>
lg
.activeValidationSignerToAccount(this.signer!)
.activeValidatorSignerToAccount(this.signer!)
.then(() => true)
.catch(() => false)
)
Expand Down
34 changes: 27 additions & 7 deletions packages/cli/src/utils/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@ import { IArg, ParseFn } from '@oclif/parser/lib/args'
import { pathExistsSync } from 'fs-extra'
import Web3 from 'web3'

const parsePublicKey: ParseFn<string> = (input) => {
// Check that the string starts with 0x and has byte length of ecdsa pub key (64 bytes) + bls pub key (48 bytes) + proof of pos (96 bytes)
if (Web3.utils.isHex(input) && input.length === 418 && input.startsWith('0x')) {
const parseBytes = (input, length, msg) => {
// Check that the string starts with 0x and has byte length of `length`.
if (Web3.utils.isHex(input) && input.length === length && input.startsWith('0x')) {
return input
} else {
throw new CLIError(`${input} is not a public key`)
throw new CLIError(msg)
}
}

const parseEcdsaPublicKey: ParseFn<string> = (input) => {
parseBytes(input, 64, `${input} is not an ECDSA public key`)
}
const parseBlsPublicKey: ParseFn<string> = (input) => {
parseBytes(input, 48, `${input} is not a BLS public key`)
asaj marked this conversation as resolved.
Show resolved Hide resolved
}
const parseBlsProofOfPossession: ParseFn<string> = (input) => {
parseBytes(input, 96, `${input} is not a BLS proof-of-possession`)
}
const parseAddress: ParseFn<string> = (input) => {
if (Web3.utils.isAddress(input)) {
return input
Expand Down Expand Up @@ -58,9 +68,19 @@ export const Flags = {
description: 'Account Address',
helpValue: '0xc1912fEE45d61C87Cc5EA59DaE31190FFFFf232d',
}),
publicKey: flags.build({
parse: parsePublicKey,
description: 'Public Key',
ecdsaPublicKey: flags.build({
parse: parseEcdsaPublicKey,
description: 'ECDSA Public Key',
helpValue: '0x',
}),
blsPublicKey: flags.build({
parse: parseBlsPublicKey,
description: 'BLS Public Key',
helpValue: '0x',
}),
blsProofOfPossession: flags.build({
parse: parseBlsProofOfPossession,
description: 'BLS Proof-of-Possession',
helpValue: '0x',
}),
url: flags.build({
Expand Down
21 changes: 0 additions & 21 deletions packages/cli/src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
import { eqAddress } from '@celo/utils/lib/address'
import ethjsutil from 'ethereumjs-util'
import Web3 from 'web3'
import { Block } from 'web3/eth/types'
import { failWith } from './cli'

import assert = require('assert')

export async function getPubKeyFromAddrAndWeb3(addr: string, web3: Web3) {
const msg = new Buffer('dummy_msg_data')
const data = '0x' + msg.toString('hex')
// Note: Eth.sign typing displays incorrect parameter order
const sig = await web3.eth.sign(data, addr)

const rawsig = ethjsutil.fromRpcSig(sig)

const prefix = new Buffer('\x19Ethereum Signed Message:\n')
const prefixedMsg = ethjsutil.sha3(Buffer.concat([prefix, new Buffer(String(msg.length)), msg]))
const pubKey = ethjsutil.ecrecover(prefixedMsg, rawsig.v, rawsig.r, rawsig.s)

const computedAddr = ethjsutil.pubToAddress(pubKey).toString('hex')
assert(eqAddress(computedAddr, addr), 'computed address !== addr')

return pubKey
}

export async function nodeIsSynced(web3: Web3): Promise<boolean> {
if (process.env.NO_SYNCCHECK) {
return true
Expand Down
Loading