Skip to content

Commit c772fe0

Browse files
authored
update pnpcommon README, fix release sdks script, combiner deps (#10463)
update pnpcommon README, release sdks script, combiner deps
1 parent 95d846b commit c772fe0

File tree

17 files changed

+1529
-148
lines changed

17 files changed

+1529
-148
lines changed

packages/phone-number-privacy/combiner/package.json

+6-7
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,13 @@
3232
"@celo/phone-number-privacy-common": "^3.0.0-dev",
3333
"@celo/identity": "^4.1.1-dev",
3434
"@celo/encrypted-backup": "^4.1.1-dev",
35-
"@celo/identity-prev": "npm:@celo/identity@1.2.0",
3635
"@celo/poprf": "^0.1.9",
3736
"@types/bunyan": "^1.8.8",
3837
"blind-threshold-bls": "https://github.com/celo-org/blind-threshold-bls-wasm#e1e2f8a",
3938
"dotenv": "^8.2.0",
4039
"express": "^4.17.1",
41-
"firebase-admin": "^9.12.0",
42-
"firebase-functions": "^3.15.7",
40+
"firebase-admin": "^11.10.1",
41+
"firebase-functions": "^4.4.1",
4342
"knex": "^2.1.0",
4443
"node-fetch": "^2.6.9",
4544
"pg": "^8.2.1",
@@ -51,13 +50,13 @@
5150
"@types/express": "^4.17.6",
5251
"@types/supertest": "^2.0.12",
5352
"@types/uuid": "^7.0.3",
54-
"firebase-functions-test": "^0.3.3",
55-
"firebase-tools": "9.20.0"
53+
"firebase-functions-test": "^3.1.0",
54+
"firebase-tools": "12.4.7"
5655
},
5756
"peerDependencies": {
58-
"@celo/phone-number-privacy-signer": "^2.0.2"
57+
"@celo/phone-number-privacy-signer": "^3.0.0-dev"
5958
},
6059
"engines": {
61-
"node": ">=14"
60+
"node": ">=18"
6261
}
6362
}

packages/phone-number-privacy/combiner/src/common/combine.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ export abstract class CombineAction<R extends OdisRequest> implements Action<R>
157157
}
158158

159159
private addFailureToSession(signer: Signer, errorCode: number | undefined, session: Session<R>) {
160-
session.logger.warn(
161-
`Received failure from ${session.failedSigners.size}/${this.signers.length} signers`
162-
)
163160
// Tracking failed request count via signer url prevents
164161
// double counting the same failed request by mistake
165162
session.failedSigners.add(signer.url)
163+
session.logger.warn(
164+
`Received failure from ${session.failedSigners.size}/${this.signers.length} signers`
165+
)
166166
if (errorCode) {
167167
session.incrementErrorCodeCount(errorCode)
168168
}

packages/phone-number-privacy/combiner/src/common/crypto-clients/crypto-client.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ErrorMessage, KeyVersionInfo } from '@celo/phone-number-privacy-common'
22
import Logger from 'bunyan'
3+
import { performance } from 'perf_hooks'
34

45
export interface ServicePartialSignature {
56
url: string
@@ -38,7 +39,17 @@ export abstract class CryptoClient {
3839
`${ErrorMessage.NOT_ENOUGH_PARTIAL_SIGNATURES} ${this.allSignaturesLength}/${threshold}`
3940
)
4041
}
41-
return this._combineBlindedSignatureShares(blindedMessage, logger)
42+
43+
const start = `Start combineBlindedSignatureShares`
44+
const end = `End combineBlindedSignatureShares`
45+
performance.mark(start)
46+
47+
const combinedSignature = this._combineBlindedSignatureShares(blindedMessage, logger)
48+
49+
performance.mark(end)
50+
performance.measure('combineBlindedSignatureShares', start, end)
51+
52+
return combinedSignature
4253
}
4354

4455
/*

packages/phone-number-privacy/combiner/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const combiner = functions
1010
.runWith({
1111
// Keep instances warm for mainnet functions
1212
// Defined check required for running tests vs. deployment
13-
minInstances: functions.config().service ? functions.config().service.min_instances : undefined,
13+
minInstances: functions.config().service ? Number(functions.config().service.min_instances) : 0,
1414
})
1515
.https.onRequest(startCombiner(config, getContractKit(config.blockchain)))
1616
export * from './config'

packages/phone-number-privacy/common/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ These instructions assume the following scenario for readability:
2727
4. Same idea as above -- ensure the version of the `@celo/phone-number-privacy-common` package is set to the version you are trying to release (i.e. `2.0.3-beta.1`) and that all other packages are importing this version.
2828
5. From the monorepo root directory, run `yarn reset && yarn && yarn build` (expect this to take at least 10 mins)
2929
6. Commit your changes with the message `3.2.0-beta.1`
30-
7. Publish the ODIS common package by navigating to the `phone-number-privacy/common` directory and running `npm publish —-tag beta --version 3.2.0-beta.1 —-otp <OTP>`
30+
7. Publish the ODIS common package by navigating to the `phone-number-privacy/common` directory and running `npm publish —-tag beta`
31+
- You will be prompted to enter your OTP
3132
- When publishing as `latest`, omit the `--tag beta`
3233
8. Publish the sdks by running `npm run deploy-sdks` from the monorepo root directory
3334
- You will be prompted to enter a version number that you wish to publish. i.e. `3.2.0-beta.1`

packages/phone-number-privacy/common/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
"@types/elliptic": "^6.4.12",
4646
"@types/express": "^4.17.6",
4747
"@types/is-base64": "^1.1.0",
48-
"@types/node-fetch": "^2.5.7",
49-
"web3": "1.10.0"
48+
"@types/node-fetch": "^2.5.7"
5049
},
5150
"engines": {
5251
"node": ">=10"

packages/phone-number-privacy/common/src/test/utils.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { privateKeyToAddress } from '@celo/utils/lib/address'
22
import { serializeSignature, Signature, signMessage } from '@celo/utils/lib/signatureUtils'
33
import BigNumber from 'bignumber.js'
4-
import Web3 from 'web3'
54
import {
65
AuthenticationMethod,
76
PhoneNumberPrivacyRequest,
@@ -50,7 +49,7 @@ export function createMockOdisPayments(totalPaidCUSDFunc: jest.Mock<BigNumber, [
5049

5150
export function createMockContractKit(
5251
c: { [contractName in ContractRetrieval]?: any },
53-
mockWeb3?: any
52+
mockWeb3: any
5453
) {
5554
const contracts: any = {}
5655
for (const t of Object.keys(c)) {
@@ -66,8 +65,7 @@ export function createMockContractKit(
6665
}
6766
}
6867

69-
export function createMockConnection(mockWeb3?: any) {
70-
mockWeb3 = mockWeb3 ?? new Web3()
68+
export function createMockConnection(mockWeb3: any) {
7169
return {
7270
web3: mockWeb3,
7371
getTransactionCount: jest.fn(() => mockWeb3.eth.getTransactionCount()),

packages/phone-number-privacy/monitor/src/query.ts

+26-10
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import { genSessionID } from '@celo/phone-number-privacy-common/lib/utils/logger
1818
import { normalizeAddressWith0x, privateKeyToAddress } from '@celo/utils/lib/address'
1919
import { defined } from '@celo/utils/lib/sign-typed-data-utils'
2020
import { LocalWallet } from '@celo/wallet-local'
21+
import { ACCOUNT_ADDRESS, dekAuthSigner, generateRandomPhoneNumber, PRIVATE_KEY } from './resources'
2122

22-
const phoneNumber = fetchEnv('PHONE_NUMBER')
23+
let phoneNumber = fetchEnv('PHONE_NUMBER')
2324

2425
const newPrivateKey = async () => {
2526
const mnemonic = await generateMnemonic(MnemonicStrength.s256_24words)
@@ -29,21 +30,35 @@ const newPrivateKey = async () => {
2930
export const queryOdisForSalt = async (
3031
blockchainProvider: string,
3132
contextName: OdisContextName,
32-
timeoutMs: number = 10000
33+
timeoutMs: number = 10000,
34+
bypassQuota: boolean = false,
35+
useDEK: boolean = false
3336
) => {
37+
let authSigner: AuthSigner
38+
let accountAddress: string
3439
console.log(`contextName: ${contextName}`) // tslint:disable-line:no-console
3540
console.log(`blockchain provider: ${blockchainProvider}`) // tslint:disable-line:no-console
41+
console.log(`using DEK: ${useDEK}`) // tslint:disable-line:no-console
3642

3743
const serviceContext = getServiceContext(contextName, OdisAPI.PNP)
3844

3945
const contractKit = newKit(blockchainProvider, new LocalWallet())
40-
const privateKey = await newPrivateKey()
41-
const accountAddress = normalizeAddressWith0x(privateKeyToAddress(privateKey))
42-
contractKit.connection.addAccount(privateKey)
43-
contractKit.defaultAccount = accountAddress
44-
const authSigner: AuthSigner = {
45-
authenticationMethod: OdisUtils.Query.AuthenticationMethod.WALLET_KEY,
46-
contractKit,
46+
47+
if (useDEK) {
48+
accountAddress = ACCOUNT_ADDRESS
49+
contractKit.connection.addAccount(PRIVATE_KEY)
50+
contractKit.defaultAccount = accountAddress
51+
authSigner = dekAuthSigner(0)
52+
phoneNumber = generateRandomPhoneNumber()
53+
} else {
54+
const privateKey = await newPrivateKey()
55+
accountAddress = normalizeAddressWith0x(privateKeyToAddress(privateKey))
56+
contractKit.connection.addAccount(privateKey)
57+
contractKit.defaultAccount = accountAddress
58+
authSigner = {
59+
authenticationMethod: OdisUtils.Query.AuthenticationMethod.WALLET_KEY,
60+
contractKit,
61+
}
4762
}
4863

4964
const abortController = new AbortController()
@@ -52,6 +67,7 @@ export const queryOdisForSalt = async (
5267
console.log(`ODIS salt request timed out after ${timeoutMs} ms`) // tslint:disable-line:no-console
5368
}, timeoutMs)
5469
try {
70+
const testSessionId = Math.floor(Math.random() * 100000).toString()
5571
const res = await OdisUtils.Identifier.getObfuscatedIdentifier(
5672
phoneNumber,
5773
OdisUtils.Identifier.IdentifierPrefix.PHONE_NUMBER,
@@ -61,7 +77,7 @@ export const queryOdisForSalt = async (
6177
undefined,
6278
undefined,
6379
undefined,
64-
genSessionID(),
80+
bypassQuota ? testSessionId : genSessionID(),
6581
undefined,
6682
abortController
6783
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { EncryptionKeySigner } from '@celo/identity/lib/odis/query'
2+
import { AuthenticationMethod } from '@celo/phone-number-privacy-common'
3+
import {
4+
ensureLeading0x,
5+
normalizeAddressWith0x,
6+
privateKeyToAddress,
7+
} from '@celo/utils/lib/address'
8+
9+
export const PRIVATE_KEY = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
10+
export const ACCOUNT_ADDRESS = normalizeAddressWith0x(privateKeyToAddress(PRIVATE_KEY)) // 0x1be31a94361a391bbafb2a4ccd704f57dc04d4bb
11+
12+
interface DEK {
13+
privateKey: string
14+
publicKey: string
15+
address: string
16+
}
17+
18+
export const deks: DEK[] = [
19+
{
20+
privateKey: 'bf8a2b73baf8402f8fe906ad3f42b560bf14b39f7df7797ece9e293d6f162188',
21+
publicKey: '034846bc781cacdafc66f3a77aa9fc3c56a9dadcd683c72be3c446fee8da041070',
22+
address: '0x7b33dF2607b85e3211738a49A6Ad6E8Ed4d13F6E',
23+
},
24+
{
25+
privateKey: '0975b0c565abc75b6638a749ea3008cb52676af3eabe4b80e19c516d82330364',
26+
publicKey: '03b1ac8c445f0796978018c087b97e8213b32c39e6a8642ae63dce71da33a19f65',
27+
address: '0x34332049B07Fab9a2e843A7C8991469d93cF6Ae6',
28+
},
29+
]
30+
31+
// The following code can be used to generate more test DEKs
32+
// const generateDEKs = (n: number): Promise<DEK[]> => Promise.all([...Array(n).keys()].map(
33+
// async () => await deriveDek(await generateMnemonic())
34+
// ))
35+
36+
export const dekAuthSigner = (index: number): EncryptionKeySigner => {
37+
return {
38+
authenticationMethod: AuthenticationMethod.ENCRYPTION_KEY,
39+
rawKey: ensureLeading0x(deks[index].privateKey),
40+
}
41+
}
42+
43+
export function generateRandomPhoneNumber() {
44+
const min = 1000000000 // Smallest 10-digit number
45+
const max = 9999999999 // Largest 10-digit number
46+
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min
47+
return '+1' + randomNumber.toString()
48+
}

packages/phone-number-privacy/monitor/src/scripts/run-load-test.ts

+63-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import { OdisContextName } from '@celo/identity/lib/odis/query'
2+
import { CombinerEndpointPNP } from '@celo/phone-number-privacy-common'
23
import yargs from 'yargs'
34
import { concurrentLoadTest, serialLoadTest } from '../test'
45

56
/* tslint:disable:no-console */
67

7-
const runLoadTest = (contextName: string, numWorker: number, isSerial: boolean) => {
8+
const runLoadTest = (
9+
contextName: string,
10+
numWorker: number,
11+
isSerial: boolean,
12+
pnpQuotaEndpoint: boolean,
13+
timeoutMs: number,
14+
bypassQuota: boolean,
15+
useDEK: boolean
16+
) => {
817
let blockchainProvider: string
918
switch (contextName) {
1019
case 'alfajoresstaging':
@@ -25,11 +34,30 @@ const runLoadTest = (contextName: string, numWorker: number, isSerial: boolean)
2534
process.exit(1)
2635
}
2736
if (isSerial) {
28-
serialLoadTest(numWorker, blockchainProvider!, contextName as OdisContextName) // tslint:disable-line:no-floating-promises
37+
// tslint:disable-next-line: no-floating-promises
38+
serialLoadTest(
39+
numWorker,
40+
blockchainProvider!,
41+
contextName as OdisContextName,
42+
pnpQuotaEndpoint ? CombinerEndpointPNP.PNP_QUOTA : CombinerEndpointPNP.PNP_SIGN,
43+
timeoutMs,
44+
bypassQuota,
45+
useDEK
46+
)
2947
} else {
30-
concurrentLoadTest(numWorker, blockchainProvider!, contextName as OdisContextName) // tslint:disable-line:no-floating-promises
48+
// tslint:disable-next-line: no-floating-promises
49+
concurrentLoadTest(
50+
numWorker,
51+
blockchainProvider!,
52+
contextName as OdisContextName,
53+
pnpQuotaEndpoint ? CombinerEndpointPNP.PNP_QUOTA : CombinerEndpointPNP.PNP_SIGN,
54+
timeoutMs,
55+
bypassQuota,
56+
useDEK
57+
)
3158
}
3259
}
60+
3361
// tslint:disable-next-line: no-unused-expression
3462
yargs
3563
.scriptName('ODIS-load-test')
@@ -52,8 +80,38 @@ yargs
5280
})
5381
.option('isSerial', {
5482
type: 'boolean',
55-
description: 'run test workers in series.',
83+
description: 'Run test workers in series.',
84+
default: false,
85+
})
86+
.option('timeoutMs', {
87+
type: 'number',
88+
description: 'Timout in ms.',
89+
default: 10000,
90+
})
91+
.option('bypassQuota', {
92+
type: 'boolean',
93+
description: 'Bypass Signer quota check.',
94+
default: false,
95+
})
96+
.option('useDEK', {
97+
type: 'boolean',
98+
description: 'Use Data Encryption Key (DEK) to authenticate.',
99+
default: false,
100+
})
101+
.option('pnpQuotaEndpoint', {
102+
type: 'boolean',
103+
description:
104+
'Use this flag to load test PNP_QUOTA endpoint instead of PNP_SIGN endpoint.',
56105
default: false,
57106
}),
58-
(args) => runLoadTest(args.contextName!, args.numWorkers!, args.isSerial)
107+
(args) =>
108+
runLoadTest(
109+
args.contextName!,
110+
args.numWorkers!,
111+
args.isSerial,
112+
args.pnpQuotaEndpoint,
113+
args.timeoutMs,
114+
args.bypassQuota,
115+
args.useDEK
116+
)
59117
).argv

0 commit comments

Comments
 (0)