Skip to content

Commit

Permalink
Merge pull request #13 from celo-org/master
Browse files Browse the repository at this point in the history
master
  • Loading branch information
aaitor authored Nov 28, 2019
2 parents ef3d8d1 + 8abb8b7 commit a5be9c5
Show file tree
Hide file tree
Showing 83 changed files with 6,823 additions and 1,093 deletions.
6 changes: 5 additions & 1 deletion packages/attestation-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ You can use the following environment variables to configure the attestation ser

### Operations

This service uses `bunyan` for structured logging with JSON lines. You can pipe STDOUT to `yarn run bunyan` for a more human friendly output. The `LOG_LEVEL` environment variable can specify desired log levels. With `LOG_FORMAT=stackdriver` you can get stackdriver specific format to recover information such as error traces etc.
This service uses `bunyan` for structured logging with JSON lines. You can pipe STDOUT to `yarn run bunyan` for a more human friendly output. The `LOG_LEVEL` environment variable can specify desired log levels. We support the following `LOG_FORMAT`s:

- Default are json lines `LOG_FORMAT=json`
- With `LOG_FORMAT=stackdriver` you can get stackdriver specific format to recover information such as error traces etc.
- To get something more human readable, use `LOG_FORMAT=human`

This service exposes prometheus metrics under `/metrics`.

Expand Down
6 changes: 3 additions & 3 deletions packages/attestation-service/config/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ TWILIO_ACCOUNT_SID=x
TWILIO_MESSAGING_SERVICE_SID=x
TWILIO_AUTH_TOKEN=x
TWILIO_BLACKLIST=
# Options: default, stackdriver
LOG_FORMAT=
# Options: json (default), human, stackdriver
LOG_FORMAT= human
# Options: fatal, error, warn, info, debug, trace
LOG_LEVEL=
LOG_LEVEL=
1 change: 1 addition & 0 deletions packages/attestation-service/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
declare module 'nexmo'
declare module 'express-request-id'
declare module 'bunyan-debug-stream'
1 change: 1 addition & 0 deletions packages/attestation-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"body-parser": "1.19.0",
"bunyan": "1.8.12",
"bunyan-gke-stackdriver": "0.1.2",
"bunyan-debug-stream": "2.0.0",
"debug": "^4.1.1",
"dotenv": "8.0.0",
"eth-lib": "^0.2.8",
Expand Down
19 changes: 14 additions & 5 deletions packages/attestation-service/src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import Logger, { createLogger, levelFromName, LogLevelString, stdSerializers } from 'bunyan'
import bunyanDebugStream from 'bunyan-debug-stream'
import { createStream } from 'bunyan-gke-stackdriver'
import { fetchEnvOrDefault } from './env'

const logLevel = fetchEnvOrDefault('LOG_LEVEL', 'info') as LogLevelString
const logFormat = fetchEnvOrDefault('LOG_FORMAT', 'default')
const logFormat = fetchEnvOrDefault('LOG_FORMAT', 'json')

const stream =
logFormat === 'stackdriver'
? createStream(levelFromName[logLevel])
: { stream: process.stdout, level: logLevel }
let stream: any
switch (logFormat) {
case 'stackdriver':
stream = createStream(levelFromName[logLevel])
break
case 'human':
stream = { level: logLevel, stream: bunyanDebugStream() }
break
default:
stream = { stream: process.stdout, level: logLevel }
break
}

export const rootLogger: Logger = createLogger({
name: 'attestation-service',
Expand Down
6 changes: 6 additions & 0 deletions packages/attestation-service/src/sms/nexmo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export class NexmoSmsProvider extends SmsProvider {

initialize = async () => {
const availableNumbers = await this.getAvailableNumbers()

if (!availableNumbers) {
throw new Error(
'You have no phone numbers in your Nexmo account. Please buy at least one number at https://dashboard.nexmo.com/buy-numbers'
)
}
this.nexmoNumbers = availableNumbers.map((number: any) => ({
phoneNumber: number.msisdn,
code: phoneUtil.getRegionCodeForNumber(phoneUtil.parse('+' + number.msisdn)),
Expand Down
2 changes: 1 addition & 1 deletion packages/celotool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ a few useful commands to make running a node really easy.
#### MacOS Setup

- Install Helm 2.14.0 from https://get.helm.sh/ (Homebrew lacks this version.)
To get past the Unidentified Developer error: open the directory containing helm, then ctrl-click helm and select Open then Open again. Repeat for tiller.
To get past the Unidentified Developer error: open the directory containing helm, then ctrl-click helm and select Open then Open again. Repeat for tiller.
2 changes: 2 additions & 0 deletions packages/celotool/src/cmds/account/invite.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* tslint:disable no-console */
import { newKit } from '@celo/contractkit'
import { BigNumber } from 'bignumber.js'
import { switchToClusterFromEnv } from 'src/lib/cluster'
import { convertToContractDecimals } from 'src/lib/contract-utils'
import { portForwardAnd } from 'src/lib/port_forward'
import { execCmd } from 'src/lib/utils'
Expand All @@ -25,6 +26,7 @@ export const builder = (yargs: Argv) => {
}

export const handler = async (argv: InviteArgv) => {
await switchToClusterFromEnv()
const phone = argv.phone

console.log(`Sending invitation code to ${phone}`)
Expand Down
2 changes: 1 addition & 1 deletion packages/celotool/src/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function switchToClusterFromEnv(checkOrPromptIfStagingOrProduction
const kubernetesClusterName = fetchEnv(envVar.KUBERNETES_CLUSTER_NAME)
const kubernetesClusterZone = fetchEnv(envVar.KUBERNETES_CLUSTER_ZONE)

const expectedCluster = `gke_${projectName}_${kubernetesClusterName}_${kubernetesClusterName}`
const expectedCluster = `gke_${projectName}_${kubernetesClusterZone}_${kubernetesClusterName}`

if (currentCluster === null || currentCluster.trim() !== expectedCluster) {
await execCmdWithExitOnFailure(
Expand Down
1 change: 1 addition & 0 deletions packages/celotool/src/lib/generate_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const generateIstanbulExtraData = (validators: Validator[]) => {
'0x' +
repeat('0', istanbulVanity * 2) +
rlp
// @ts-ignore
.encode([
// Added validators
validators.map((validator) => Buffer.from(validator.address, 'hex')),
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/commands/account/authorize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ testWithGanache('account:authorize cmd', (web3: Web3) => {
'validator',
'--signer',
accounts[1],
'--pop',
'--signature',
'0x1b9fca4bbb5bfb1dbe69ef1cddbd9b4202dcb6b134c5170611e1e36ecfa468d7b46c85328d504934fce6c2a1571603a50ae224d2b32685e84d4d1a1eebad8452eb',
])
})
Expand All @@ -31,7 +31,7 @@ testWithGanache('account:authorize cmd', (web3: Web3) => {
'validator',
'--signer',
accounts[1],
'--pop',
'--signature',
'0x1b9fca4bbb5bfb1dbe69ef1cddbd9b4202dcb6b134c5170611e1e36ecfa468d7b46c85328d504934fce6c2a1571603a50ae224d2b32685e84d4d1a1eebad8452eb',
])
).rejects.toThrow()
Expand Down
12 changes: 8 additions & 4 deletions packages/cli/src/commands/account/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default class Authorize extends BaseCommand {
description: 'Role to delegate',
required: true,
}),
pop: flags.string({
description: 'Proof-of-possession of the signer key',
signature: flags.string({
description: 'Signature (a.k.a proof-of-possession) of the signer key',
required: true,
}),
signer: Flags.address({ required: true }),
Expand All @@ -27,14 +27,18 @@ export default class Authorize extends BaseCommand {
static args = []

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

async run() {
const res = this.parse(Authorize)
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)
const sig = accounts.parseSignatureOfAddress(
res.flags.from,
res.flags.signer,
res.flags.signature
)

await newCheckBuilder(this)
.isAccount(res.flags.from)
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/account/balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default class Balance extends BaseCommand {
goldBalance: await goldToken.balanceOf(args.address),
dollarBalance: await stableToken.balanceOf(args.address),
}
console.log('All balances expressed in units of 10^-18.')
printValueMap(balances)
}
}
32 changes: 32 additions & 0 deletions packages/cli/src/commands/account/set-name.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { testWithGanache } from '@celo/dev-utils/lib/ganache-test'
import Web3 from 'web3'
import Register from '../account/register'
import SetName from './set-name'

process.env.NO_SYNCCHECK = 'true'

testWithGanache('account:set-name cmd', (web3: Web3) => {
test('can set the name of an account', async () => {
const accounts = await web3.eth.getAccounts()
await Register.run(['--from', accounts[0]])
await SetName.run(['--account', accounts[0], '--name', 'TestName'])
})

test('fails if account is not registered', async () => {
const accounts = await web3.eth.getAccounts()

await expect(SetName.run(['--account', accounts[0], '--name', 'TestName'])).rejects.toThrow(
"Some checks didn't pass!"
)
})

test('fails if account is not provided', async () => {
await expect(SetName.run(['--name', 'TestName'])).rejects.toThrow('Missing required flag')
})

test('fails if name is not provided', async () => {
const accounts = await web3.eth.getAccounts()

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

export default class SetName extends BaseCommand {
static description =
"Sets the name of a registered account on-chain. An account's name is an optional human readable identifier"

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

static args = []

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

async run() {
const res = this.parse(SetName)
this.kit.defaultAccount = res.flags.account
const accounts = await this.kit.contracts.getAccounts()

await newCheckBuilder(this)
.isAccount(res.flags.account)
.runChecks()
await displaySendTx('setName', accounts.setName(res.flags.name))
}
}
23 changes: 23 additions & 0 deletions packages/cli/src/commands/account/show.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { BaseCommand } from '../../base'
import { printValueMap } from '../../utils/cli'
import { Args } from '../../utils/command'

export default class Show extends BaseCommand {
static description =
'Show information for an account, including name, authorized vote, validator, and attestation signers, the URL at which account metadata is hosted, the address the account is using with the mobile wallet, and a public key that can be used to encrypt information for the account.'

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

static args = [Args.address('address')]

static examples = ['show 0x5409ed021d9299bf6814279a6a1411a7e866a631']

async run() {
const { args } = this.parse(Show)

const accounts = await this.kit.contracts.getAccounts()
printValueMap(await accounts.getAccountSummary(args.address))
}
}
2 changes: 1 addition & 1 deletion packages/cli/src/commands/election/current.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class ElectionCurrent extends BaseCommand {
address: {},
name: {},
affiliation: {},
score: {},
score: { get: (v) => v.score.toFixed() },
ecdsaPublicKey: {},
blsPublicKey: {},
})
Expand Down
27 changes: 18 additions & 9 deletions packages/cli/src/commands/validator/list.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { flags } from '@oclif/command'
import { cli } from 'cli-ux'
import { BaseCommand } from '../../base'

Expand All @@ -7,25 +8,33 @@ export default class ValidatorList extends BaseCommand {

static flags = {
...BaseCommand.flags,
'no-truncate': flags.boolean({
description: "Don't truncate fields to fit line",
required: false,
}),
}

static examples = ['list']

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

cli.action.start('Fetching Validators')
const validators = await this.kit.contracts.getValidators()
const validatorList = await validators.getRegisteredValidators()

cli.action.stop()
cli.table(validatorList, {
address: {},
name: {},
affiliation: {},
score: { get: (v) => v.score.toFixed() },
ecdsaPublicKey: {},
blsPublicKey: {},
})
cli.table(
validatorList,
{
address: {},
name: {},
affiliation: {},
score: { get: (v) => v.score.toFixed() },
ecdsaPublicKey: {},
blsPublicKey: {},
},
{ 'no-truncate': res.flags['no-truncate'] }
)
}
}
11 changes: 9 additions & 2 deletions packages/cli/src/commands/validator/register.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { testWithGanache } from '@celo/dev-utils/lib/ganache-test'
import { addressToPublicKey } from '@celo/utils/lib/signatureUtils'
import Web3 from 'web3'
import Register from '../account/register'
import Lock from '../lockedgold/lock'
Expand All @@ -8,10 +9,12 @@ process.env.NO_SYNCCHECK = 'true'

testWithGanache('validator:register', (web3: Web3) => {
let account: string
let ecdsaPublicKey: string

beforeEach(async () => {
const accounts = await web3.eth.getAccounts()
account = accounts[0]
ecdsaPublicKey = await addressToPublicKey(account, web3.eth.sign)
await Register.run(['--from', account])
await Lock.run(['--from', account, '--value', '10000000000000000000000'])
})
Expand All @@ -20,9 +23,11 @@ testWithGanache('validator:register', (web3: Web3) => {
await ValidatorRegister.run([
'--from',
account,
'--ecdsaKey',
ecdsaPublicKey,
'--blsKey',
'0x4fa3f67fc913878b068d1fa1cdddc54913d3bf988dbe5a36a20fa888f20d4894c408a6773f3d7bde11154f2a3076b700d345a42fd25a0e5e83f4db5586ac7979ac2053cd95d8f2efd3e959571ceccaa743e02cf4be3f5d7aaddb0b06fc9aff00',
'--blsPop',
'--blsSignature',
'0xcdb77255037eb68897cd487fdd85388cbda448f617f874449d4b11588b0b7ad8ddc20d9bb450b513bb35664ea3923900',
])
})
Expand All @@ -31,9 +36,11 @@ testWithGanache('validator:register', (web3: Web3) => {
await ValidatorRegister.run([
'--from',
account,
'--ecdsaKey',
ecdsaPublicKey,
'--blsKey',
'4fa3f67fc913878b068d1fa1cdddc54913d3bf988dbe5a36a20fa888f20d4894c408a6773f3d7bde11154f2a3076b700d345a42fd25a0e5e83f4db5586ac7979ac2053cd95d8f2efd3e959571ceccaa743e02cf4be3f5d7aaddb0b06fc9aff00',
'--blsPop',
'--blsSignature',
'cdb77255037eb68897cd487fdd85388cbda448f617f874449d4b11588b0b7ad8ddc20d9bb450b513bb35664ea3923900',
])
})
Expand Down
Loading

0 comments on commit a5be9c5

Please sign in to comment.