From d8373f0217bd9282d9a1903863ae86412652412d Mon Sep 17 00:00:00 2001 From: danield9tqh Date: Tue, 14 Mar 2023 13:55:29 -0700 Subject: [PATCH 1/2] Move ceremony command to R2 --- ironfish-cli/src/commands/ceremony.ts | 8 ++--- ironfish-cli/src/commands/service/ceremony.ts | 22 ++++++++++-- ironfish-cli/src/trusted-setup/server.ts | 11 +++--- ironfish-cli/src/utils/s3.ts | 34 +++++++++++++++++++ 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/ironfish-cli/src/commands/ceremony.ts b/ironfish-cli/src/commands/ceremony.ts index 1455f650f7..04e810f382 100644 --- a/ironfish-cli/src/commands/ceremony.ts +++ b/ironfish-cli/src/commands/ceremony.ts @@ -49,10 +49,10 @@ export default class Ceremony extends IronfishCommand { // Trusted setup has ended but this command may still be needed in case of future // setups / network upgrades. So for now, just exit the command with some information - this.log( - `The trusted setup ceremony was completed on Mar 3, 2023. For more information on the trusted setup process and its completion please read https://setup.ironfish.network.`, - ) - this.exit(0) + // this.log( + // `The trusted setup ceremony was completed on Mar 3, 2023. For more information on the trusted setup process and its completion please read https://setup.ironfish.network.`, + // ) + // this.exit(0) // Prompt for randomness let randomness: string | null = await CliUx.ux.prompt( diff --git a/ironfish-cli/src/commands/service/ceremony.ts b/ironfish-cli/src/commands/service/ceremony.ts index 8bd2f8c1c0..dcc99f5f97 100644 --- a/ironfish-cli/src/commands/service/ceremony.ts +++ b/ironfish-cli/src/commands/service/ceremony.ts @@ -11,7 +11,7 @@ import { S3Utils } from '../../utils' const CONTRIBUTE_TIMEOUT_MS = 5 * 60 * 1000 const UPLOAD_TIMEOUT_MS = 5 * 60 * 1000 const PRESIGNED_EXPIRATION_SEC = 5 * 60 -const START_DATE = 1676318400000 // Mon Feb 13 2023 12:00:00 GMT-0800 (Pacific Standard Time) +const START_DATE = 1681146000000 // Monday, April 10, 2023 10:00:00 AM GMT-07:00 (Pacific Daylight Time) export default class Ceremony extends IronfishCommand { static hidden = true @@ -29,6 +29,13 @@ export default class Ceremony extends IronfishCommand { description: 'S3 bucket to download and upload params to', default: 'ironfish-contributions', }), + downloadPrefix: Flags.string({ + char: 'b', + parse: (input: string) => Promise.resolve(input.trim()), + required: false, + description: 'Prefix for contribution download URLs', + default: 'https://a93bebf26da4c2fe205f71c896afcf89.r2.cloudflarestorage.com', + }), contributionTimeoutMs: Flags.integer({ required: false, description: 'Allowable milliseconds for a contributor to run the contribution script', @@ -65,7 +72,15 @@ export default class Ceremony extends IronfishCommand { const DEFAULT_HOST = '0.0.0.0' const DEFAULT_PORT = 9040 - const s3Client = S3Utils.getS3Client(true) + const r2Credentials = await S3Utils.getR2Credentials() + + if (r2Credentials === undefined) { + this.logger.log('Failed getting R2 credentials from AWS') + this.exit(0) + return + } + + const r2Client = S3Utils.getR2S3Client(r2Credentials) setLogPrefixFromConfig(`[%tag%]`) @@ -74,7 +89,8 @@ export default class Ceremony extends IronfishCommand { port: DEFAULT_PORT, host: DEFAULT_HOST, s3Bucket: flags.bucket, - s3Client: s3Client, + downloadPrefix: flags.downloadPrefix, + s3Client: r2Client, tempDir: this.sdk.config.tempDir, contributionTimeoutMs: flags.contributionTimeoutMs, uploadTimeoutMs: flags.uploadTimeoutMs, diff --git a/ironfish-cli/src/trusted-setup/server.ts b/ironfish-cli/src/trusted-setup/server.ts index c9799609e2..ddb2e78abf 100644 --- a/ironfish-cli/src/trusted-setup/server.ts +++ b/ironfish-cli/src/trusted-setup/server.ts @@ -80,6 +80,7 @@ export class CeremonyServer { readonly host: string readonly s3Bucket: string + readonly downloadPrefix: string private s3Client: S3Client readonly tempDir: string @@ -102,6 +103,7 @@ export class CeremonyServer { port: number host: string s3Bucket: string + downloadPrefix: string s3Client: S3Client tempDir: string contributionTimeoutMs: number @@ -121,6 +123,7 @@ export class CeremonyServer { this.tempDir = options.tempDir this.s3Bucket = options.s3Bucket + this.downloadPrefix = options.downloadPrefix this.s3Client = options.s3Client this.contributionTimeoutMs = options.contributionTimeoutMs @@ -188,13 +191,7 @@ export class CeremonyServer { nextClient.send({ method: 'initiate-contribution', - // S3Client doesn't support unauthenticated downloads, so we can build the URL to download for the client: - downloadLink: S3Utils.getDownloadUrl( - this.s3Bucket, - latestParamName, - { accelerated: true }, - { dualStack: true }, - ), + downloadLink: `${this.downloadPrefix}/${latestParamName}`, contributionNumber: nextParamNumber, }) } diff --git a/ironfish-cli/src/utils/s3.ts b/ironfish-cli/src/utils/s3.ts index 635b633026..429a85e837 100644 --- a/ironfish-cli/src/utils/s3.ts +++ b/ironfish-cli/src/utils/s3.ts @@ -17,6 +17,7 @@ import { S3Client, UploadPartCommand, } from '@aws-sdk/client-s3' +import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager' import { getSignedUrl } from '@aws-sdk/s3-request-presigner' import { Credentials } from '@aws-sdk/types/dist-types/credentials' import { Assert, ErrorUtils, Logger } from '@ironfish/sdk' @@ -42,6 +43,14 @@ class UploadLastMultipartError extends UploadToBucketError {} class UploadReadFileError extends UploadToBucketError {} class UploadFailedError extends UploadToBucketError {} +const R2_SECRET_NAME = 'r2-prod-access-key' +const R2_ENDPOINT = `https://a93bebf26da4c2fe205f71c896afcf89.r2.cloudflarestorage.com` + +export type R2Secret = { + r2AccessKeyId: string + r2SecretAccessKey: string +} + export async function uploadToBucket( s3: S3Client, filePath: string, @@ -309,6 +318,31 @@ export function getS3Client( }) } +export function getR2S3Client(credentials: { + r2AccessKeyId: string + r2SecretAccessKey: string +}): S3Client { + return new S3Client({ + region: 'auto', + endpoint: R2_ENDPOINT, + credentials: { + accessKeyId: credentials.r2AccessKeyId, + secretAccessKey: credentials.r2SecretAccessKey, + }, + }) +} + +export async function getR2Credentials(): Promise { + const client = new SecretsManagerClient({ region: 'us-east-1' }) + const command = new GetSecretValueCommand({ SecretId: R2_SECRET_NAME }) + const response = await client.send(command) + if (response.SecretString === undefined) { + return + } else { + return JSON.parse(response.SecretString) as R2Secret + } +} + export async function getCognitoIdentityCredentials(): Promise { const identityPoolId = 'us-east-1:3ebc542a-6ac4-4c5d-9558-1621eadd2382' From f642e06830c818b4861c94d613ed164a441bd603 Mon Sep 17 00:00:00 2001 From: danield9tqh Date: Tue, 14 Mar 2023 14:37:20 -0700 Subject: [PATCH 2/2] add ip to metadata --- ironfish-cli/src/commands/ceremony.ts | 7 ------- ironfish-cli/src/commands/service/ceremony.ts | 3 ++- ironfish-cli/src/trusted-setup/server.ts | 8 +++++++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ironfish-cli/src/commands/ceremony.ts b/ironfish-cli/src/commands/ceremony.ts index 04e810f382..53cdf21762 100644 --- a/ironfish-cli/src/commands/ceremony.ts +++ b/ironfish-cli/src/commands/ceremony.ts @@ -47,13 +47,6 @@ export default class Ceremony extends IronfishCommand { let refreshEtaInterval: NodeJS.Timeout | null = null let etaDate: Date | null = null - // Trusted setup has ended but this command may still be needed in case of future - // setups / network upgrades. So for now, just exit the command with some information - // this.log( - // `The trusted setup ceremony was completed on Mar 3, 2023. For more information on the trusted setup process and its completion please read https://setup.ironfish.network.`, - // ) - // this.exit(0) - // Prompt for randomness let randomness: string | null = await CliUx.ux.prompt( `If you'd like to contribute your own randomness to the ceremony, type it here, then press Enter. For more information on where this should come from and its importance, please read https://setup.ironfish.network. If you'd like the command to generate some randomness for you, just press Enter`, diff --git a/ironfish-cli/src/commands/service/ceremony.ts b/ironfish-cli/src/commands/service/ceremony.ts index dcc99f5f97..f327301356 100644 --- a/ironfish-cli/src/commands/service/ceremony.ts +++ b/ironfish-cli/src/commands/service/ceremony.ts @@ -34,7 +34,8 @@ export default class Ceremony extends IronfishCommand { parse: (input: string) => Promise.resolve(input.trim()), required: false, description: 'Prefix for contribution download URLs', - default: 'https://a93bebf26da4c2fe205f71c896afcf89.r2.cloudflarestorage.com', + // TODO: update this to non-dev endpoint to avoid rate limiting + default: 'https://pub-6a239e04e140459087cf392ffc3245b1.r2.dev', }), contributionTimeoutMs: Flags.integer({ required: false, diff --git a/ironfish-cli/src/trusted-setup/server.ts b/ironfish-cli/src/trusted-setup/server.ts index ddb2e78abf..0f4c6d1d00 100644 --- a/ironfish-cli/src/trusted-setup/server.ts +++ b/ironfish-cli/src/trusted-setup/server.ts @@ -400,6 +400,12 @@ export class CeremonyServer { client.logger.info(`Uploading verified contribution`) const destFile = 'params_' + nextParamNumber.toString().padStart(5, '0') + + const metadata = { + ...(client.name && { contributorName: encodeURIComponent(client.name) }), + ...(client.socket.remoteAddress && { remoteAddress: client.socket.remoteAddress }), + } + await S3Utils.uploadToBucket( this.s3Client, newParamsDownloadPath, @@ -407,7 +413,7 @@ export class CeremonyServer { this.s3Bucket, destFile, client.logger, - client.name ? { contributorName: encodeURIComponent(client.name) } : undefined, + metadata, ) client.logger.info(`Cleaning up local files`)