Skip to content

Commit

Permalink
[cli] validator deregister. Split affliliate/deaffiliate
Browse files Browse the repository at this point in the history
Also:
 - Checks on cmds
 - support use of signer
  • Loading branch information
mcortesi committed Nov 7, 2019
1 parent 730c950 commit a708015
Show file tree
Hide file tree
Showing 39 changed files with 1,014 additions and 156 deletions.
8 changes: 5 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,12 @@ jobs:
- attach_workspace:
at: ~/app
- run:
name: Test
name: Generate DevChain
command: |
set -euo pipefail
yarn --cwd=packages/cli test
(cd packages/cli && yarn test:reset)
- run:
name: Run Tests
command: yarn --cwd=packages/cli test
- run:
name: Fail if someone forgot to commit CLI docs
command: |
Expand Down
1 change: 1 addition & 0 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
node_modules
oclif.manifest.json
src/generated
.devchain/
3 changes: 3 additions & 0 deletions packages/cli/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['<rootDir>/src/**/?(*.)+(spec|test).ts?(x)'],
setupFilesAfterEnv: ['<rootDir>/src/test-utils/matchers.ts'],
globalSetup: '<rootDir>/src/test-utils/ganache.setup.ts',
globalTeardown: '<rootDir>/src/test-utils/ganache.teardown.ts',
}
4 changes: 3 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
"docs": "yarn oclif-dev readme --multi --dir=../docs/command-line-interface && yarn prettier ../docs/command-line-interface/*.md --write",
"lint": "tslint -c tslint.json --project tsconfig.json",
"prepack": "yarn run build && oclif-dev manifest && oclif-dev readme",
"test": "TZ=UTC jest"
"test:reset": "yarn --cwd ../protocol devchain generate .devchain",
"test:livechain": "yarn --cwd ../protocol devchain run .devchain",
"test": "TZ=UTC jest --runInBand"
},
"dependencies": {
"@celo/contractkit": "^0.1.6",
Expand Down
21 changes: 21 additions & 0 deletions packages/cli/src/commands/account/authorize.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Web3 from 'web3'
import { testWithGanache } from '../../test-utils/ganache-test'
import Authorize from './authorize'
import Register from './register'

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]])
await Authorize.run(['--from', accounts[0], '--role', 'validator', '--to', accounts[1]])
})

test('fails if from is not an account', async () => {
const accounts = await web3.eth.getAccounts()
await expect(
Authorize.run(['--from', accounts[0], '--role', 'validator', '--to', accounts[1]])
).rejects.toThrow()
})
})
6 changes: 6 additions & 0 deletions packages/cli/src/commands/account/authorize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand Down Expand Up @@ -38,6 +39,11 @@ export default class Authorize extends BaseCommand {

this.kit.defaultAccount = res.flags.from
const accounts = await this.kit.contracts.getAccounts()

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Address } from '@celo/utils/lib/address'
import { flags } from '@oclif/command'
import BigNumber from 'bignumber.js'
import { BaseCommand } from '../../base'
import { displaySendTx, failWith } from '../../utils/cli'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { LockedGoldArgs } from '../../utils/lockedgold'

Expand All @@ -26,14 +27,15 @@ export default class Lock extends BaseCommand {
const address: Address = res.flags.from

this.kit.defaultAccount = address
const lockedGold = await this.kit.contracts.getLockedGold()

const value = new BigNumber(res.flags.value)

if (!value.gt(new BigNumber(0))) {
failWith(`Provided value must be greater than zero => [${value.toString()}]`)
}
await newCheckBuilder(this)
.addCheck(`Value [${value.toString()}] is >= 0`, () => value.gt(0))
.isAccount(address)
.hasEnoughGold(address, value)
.runChecks()

const lockedGold = await this.kit.contracts.getLockedGold()
const tx = lockedGold.lock()
await displaySendTx('lock', tx, { value: value.toString() })
}
Expand Down
19 changes: 19 additions & 0 deletions packages/cli/src/commands/account/register.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Web3 from 'web3'
import { testWithGanache } from '../../test-utils/ganache-test'
import Register from './register'

process.env.NO_SYNCCHECK = 'true'

testWithGanache('account:register cmd', (web3: Web3) => {
test('can register account', async () => {
const accounts = await web3.eth.getAccounts()

await Register.run(['--from', accounts[0]])
})

test('fails if from is missing', async () => {
// const accounts = await web3.eth.getAccounts()

await expect(Register.run([])).rejects.toThrow('Missing required flag')
})
})
5 changes: 5 additions & 0 deletions packages/cli/src/commands/account/register.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand All @@ -20,6 +21,10 @@ export default class Register extends BaseCommand {
const res = this.parse(Register)
this.kit.defaultAccount = res.flags.from
const accounts = await this.kit.contracts.getAccounts()

await newCheckBuilder(this)
.isNotAccount(res.flags.from)
.runChecks()
await displaySendTx('register', accounts.createAccount())
await displaySendTx('setName', accounts.setName(name))
}
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/commands/lockedgold/show.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { printValueMapRecursive } from '../../utils/cli'
import { Args } from '../../utils/command'

Expand All @@ -14,10 +15,14 @@ export default class Show extends BaseCommand {
static examples = ['show 0x5409ed021d9299bf6814279a6a1411a7e866a631']

async run() {
// tslint:disable-next-line
const { args } = this.parse(Show)

const lockedGold = await this.kit.contracts.getLockedGold()

await newCheckBuilder(this)
.isAccount(args.account)
.runChecks()

printValueMapRecursive(await lockedGold.getAccountSummary(args.account))
}
}
6 changes: 6 additions & 0 deletions packages/cli/src/commands/lockedgold/unlock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { LockedGoldArgs } from '../../utils/lockedgold'
Expand All @@ -21,6 +22,11 @@ export default class Unlock extends BaseCommand {
const res = this.parse(Unlock)
this.kit.defaultAccount = res.flags.from
const lockedgold = await this.kit.contracts.getLockedGold()

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

await displaySendTx('unlock', lockedgold.unlock(res.flags.value))
}
}
7 changes: 6 additions & 1 deletion packages/cli/src/commands/lockedgold/withdraw.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand All @@ -17,8 +18,12 @@ export default class Withdraw extends BaseCommand {
const { flags } = this.parse(Withdraw)
this.kit.defaultAccount = flags.from
const lockedgold = await this.kit.contracts.getLockedGold()
const currentTime = Math.round(new Date().getTime() / 1000)

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

const currentTime = Math.round(new Date().getTime() / 1000)
while (true) {
let madeWithdrawal = false
const pendingWithdrawals = await lockedgold.getPendingWithdrawals(flags.from)
Expand Down
37 changes: 37 additions & 0 deletions packages/cli/src/commands/validator/affiliate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { IArg } from '@oclif/parser/lib/args'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Args, Flags } from '../../utils/command'

export default class ValidatorAffiliate extends BaseCommand {
static description = 'Affiliate to a ValidatorGroup'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: "Signer or Validator's address" }),
}

static args: IArg[] = [
Args.address('groupAddress', { description: "ValidatorGroup's address", required: true }),
]

static examples = [
'affiliate --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95 0x97f7333c51897469e8d98e7af8653aab468050a3',
]

async run() {
const res = this.parse(ValidatorAffiliate)
this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

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

await displaySendTx('affiliate', validators.affiliate(res.args.groupAddress))
}
}
41 changes: 0 additions & 41 deletions packages/cli/src/commands/validator/affiliation.ts

This file was deleted.

29 changes: 29 additions & 0 deletions packages/cli/src/commands/validator/deaffiliate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class ValidatorDeAffiliate extends BaseCommand {
static description = 'DeAffiliate to a ValidatorGroup'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: "Signer or Validator's address" }),
}

static examples = ['deaffiliate --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95']

async run() {
const res = this.parse(ValidatorDeAffiliate)
this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

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

await displaySendTx('deaffiliate', validators.deaffiliate())
}
}
31 changes: 31 additions & 0 deletions packages/cli/src/commands/validator/deregister.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class ValidatorDeregister extends BaseCommand {
static description = 'Deregister a Validator'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: "Signer or Validator's address" }),
}

static examples = ['deregister --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95']

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

this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

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

const validator = await validators.signerToAccount(res.flags.from)
await displaySendTx('deregister', await validators.deregisterValidator(validator))
}
}
9 changes: 9 additions & 0 deletions packages/cli/src/commands/validator/register.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { getPubKeyFromAddrAndWeb3 } from '../../utils/helpers'
Expand All @@ -18,8 +19,16 @@ export default class ValidatorRegister extends BaseCommand {
async run() {
const res = this.parse(ValidatorRegister)
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()
.signerMeetsValidatorBalanceRequirements()
.runChecks()

await displaySendTx(
'registerValidator',
validators.registerValidator(res.flags.publicKey as any)
Expand Down
22 changes: 22 additions & 0 deletions packages/cli/src/commands/validator/requirements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BaseCommand } from '../../base'
import { printValueMap } from '../../utils/cli'

export default class ValidatorRequirements extends BaseCommand {
static description = 'Get Requirements for Validators'

static flags = {
...BaseCommand.flags,
}

static examples = ['requirements']

async run() {
this.parse(ValidatorRequirements)

const validators = await this.kit.contracts.getValidators()

const requirements = await validators.getValidatorLockedGoldRequirements()

printValueMap(requirements)
}
}
Loading

0 comments on commit a708015

Please sign in to comment.