@@ -2,7 +2,7 @@ import chai, { expect } from "chai"
2
2
import chaiAsPromised from "chai-as-promised"
3
3
import { EC2Client } from "@aws-sdk/client-ec2"
4
4
import fetch from "@adobe/node-fetch-retry"
5
- import { cleanUpMockUsers , cleanUpRecursively , createMockUser , deleteBucket , deleteObjectFromS3 , envType , generateUserPasswords , getStorageConfiguration , getTranscriptLocalFilePath , initializeAdminServices , initializeUserServices , sleep } from "../utils"
5
+ import { cleanUpMockUsers , cleanUpRecursively , createMockCeremony , createMockUser , deleteBucket , deleteObjectFromS3 , envType , generateUserPasswords , getStorageConfiguration , getTranscriptLocalFilePath , initializeAdminServices , initializeUserServices , sleep } from "../utils"
6
6
import {
7
7
checkEC2Status ,
8
8
createEC2Client ,
@@ -39,105 +39,105 @@ describe("VMs", () => {
39
39
ec2 = await createEC2Client ( )
40
40
} )
41
41
42
- // describe("EC2", () => {
43
- // it("should create an instance", async () => {
44
- // instance = await createEC2Instance(ec2, [
45
- // "echo 'hello world' > hello.txt",
46
- // "aws s3 cp hello.txt s3://p0tion-test-bucket/hello.txt"
47
- // ], "t2.micro", amiId, keyName, roleArn, 8)
48
- // expect(instance).to.not.be.undefined
49
- // // give it time to actually spin up
50
- // await sleep(250000)
51
- // })
52
-
53
- // it("checkEC2Status should return true for an instance that is running", async () => {
54
- // const response = await checkEC2Status(ec2, instance.InstanceId!)
55
- // expect(response).to.be.true
56
- // })
42
+ describe ( "EC2" , ( ) => {
43
+ it ( "should create an instance" , async ( ) => {
44
+ instance = await createEC2Instance ( ec2 , [
45
+ "echo 'hello world' > hello.txt" ,
46
+ "aws s3 cp hello.txt s3://p0tion-test-bucket/hello.txt"
47
+ ] , "t2.micro" , amiId , keyName , roleArn , 8 )
48
+ expect ( instance ) . to . not . be . undefined
49
+ // give it time to actually spin up
50
+ await sleep ( 250000 )
51
+ } )
52
+
53
+ it ( "checkEC2Status should return true for an instance that is running" , async ( ) => {
54
+ const response = await checkEC2Status ( ec2 , instance . InstanceId ! )
55
+ expect ( response ) . to . be . true
56
+ } )
57
57
58
- // it("getEC2Ip should return an ip", async () => {
59
- // const ip = await getEC2Ip(ec2, instance.InstanceId!)
60
- // expect(ip).to.not.be.undefined
61
- // previousIp = ip!
62
- // })
58
+ it ( "getEC2Ip should return an ip" , async ( ) => {
59
+ const ip = await getEC2Ip ( ec2 , instance . InstanceId ! )
60
+ expect ( ip ) . to . not . be . undefined
61
+ previousIp = ip !
62
+ } )
63
63
64
- // it("stopEC2Instance should stop an instance", async () => {
65
- // await expect(stopEC2Instance(ec2, instance.InstanceId!)).to.be.fulfilled
66
- // await sleep(200000)
67
- // })
64
+ it ( "stopEC2Instance should stop an instance" , async ( ) => {
65
+ await expect ( stopEC2Instance ( ec2 , instance . InstanceId ! ) ) . to . be . fulfilled
66
+ await sleep ( 200000 )
67
+ } )
68
68
69
- // it("checkEC2Status should throw for an instance that is stopped", async () => {
70
- // await expect(checkEC2Status(ec2, instance.InstanceId!)).to.be.rejected
71
- // })
69
+ it ( "checkEC2Status should throw for an instance that is stopped" , async ( ) => {
70
+ await expect ( checkEC2Status ( ec2 , instance . InstanceId ! ) ) . to . be . rejected
71
+ } )
72
72
73
- // it("startEC2Instance should start an instance", async () => {
74
- // await expect(startEC2Instance(ec2, instance.InstanceId!)).to.be.fulfilled
75
- // await sleep(200000)
76
- // })
73
+ it ( "startEC2Instance should start an instance" , async ( ) => {
74
+ await expect ( startEC2Instance ( ec2 , instance . InstanceId ! ) ) . to . be . fulfilled
75
+ await sleep ( 200000 )
76
+ } )
77
77
78
- // it("should get a different ip address after a restart", async () => {
79
- // const ip = getEC2Ip(ec2, instance.InstanceId!)
80
- // expect(previousIp).to.not.equal(ip)
81
- // })
78
+ it ( "should get a different ip address after a restart" , async ( ) => {
79
+ const ip = getEC2Ip ( ec2 , instance . InstanceId ! )
80
+ expect ( previousIp ) . to . not . equal ( ip )
81
+ } )
82
82
83
- // it("terminateEC2Instance should terminate an instance", async () => {
84
- // await expect(terminateEC2Instance(ec2, instance.InstanceId!)).to.be.fulfilled
85
- // })
86
- // })
87
-
88
- // describe("SSM", () => {
89
- // let ssmClient: SSMClient
90
- // let commandId: string
91
- // let ssmTestInstance: P0tionEC2Instance
92
- // beforeAll(async () => {
93
- // ssmClient = await createSSMClient()
94
- // const userData = [
95
- // "#!/bin/bash",
96
- // "aws s3 cp s3://p0tion-test-bucket/script_test.sh script_test.sh",
97
- // "chmod +x script_test.sh && bash script_test.sh"
98
- // ]
99
- // ssmTestInstance = await createEC2Instance(ec2, userData, "t2.small", amiId, keyName, roleArn, 8)
100
- // await sleep(250000)
101
- // })
102
- // it("should run my commands", async () => {
103
- // await runCommandOnEC2(ssmClient, ssmTestInstance.InstanceId, [
104
- // `pwd`
105
- // ] )
83
+ it ( "terminateEC2Instance should terminate an instance" , async ( ) => {
84
+ await expect ( terminateEC2Instance ( ec2 , instance . InstanceId ! ) ) . to . be . fulfilled
85
+ } )
86
+ } )
87
+
88
+ describe ( "SSM" , ( ) => {
89
+ let ssmClient : SSMClient
90
+ let commandId : string
91
+ let ssmTestInstance : P0tionEC2Instance
92
+ beforeAll ( async ( ) => {
93
+ ssmClient = await createSSMClient ( )
94
+ const userData = [
95
+ "#!/bin/bash" ,
96
+ "aws s3 cp s3://p0tion-test-bucket/script_test.sh script_test.sh" ,
97
+ "chmod +x script_test.sh && bash script_test.sh"
98
+ ]
99
+ ssmTestInstance = await createEC2Instance ( ec2 , userData , "t2.small" , amiId , keyName , roleArn , 8 )
100
+ await sleep ( 250000 )
101
+ } )
102
+ it ( "should run my commands" , async ( ) => {
103
+ await runCommandOnEC2 ( ssmClient , ssmTestInstance . InstanceId , [
104
+ `pwd`
105
+ ] )
106
106
107
- // })
108
- // it("run a command on a VM that is active", async () => {
109
- // commandId = await runCommandOnEC2(ssmClient, ssmTestInstance.InstanceId!, [
110
- // "echo $(whoami) >> hello.txt"
111
- // ])
112
- // expect(commandId).to.not.be.null
113
- // await sleep(500)
114
- // })
115
- // it("should run multiple commands", async () => {
116
- // await runCommandOnEC2(ssmClient, ssmTestInstance.InstanceId!, [
117
- // "su ubuntu", "whoami", "id", "pwd", "ls -la", "ls -la /root", "ls -la /home/ubuntu",
118
- // ])
119
- // })
120
- // it("should throw when trying to call a command on a VM that is not active", async () => {
121
- // await expect(runCommandOnEC2(ssmClient, "nonExistentOrOff", ["echo hello world"])).to.be.rejected
122
- // })
123
- // it("should retrieve the output of a command", async () => {
124
- // await sleep(20000)
125
- // const output = await retrieveCommandOutput(ssmClient, commandId, ssmTestInstance.InstanceId!)
126
- // expect(output.length).to.be.gt(0)
127
- // })
128
- // it("should throw when trying to retrieve the output of a non existent command", async () => {
129
- // await expect(retrieveCommandOutput(ssmClient, "nonExistentCommand", ssmTestInstance.InstanceId!)).to.be.rejected
130
- // })
131
- // afterAll(async () => {
132
- // await terminateEC2Instance(ec2, ssmTestInstance.InstanceId!)
133
- // })
134
- // })
135
-
136
- // afterAll(async () => {
137
- // await terminateEC2Instance(ec2, instance.InstanceId!)
138
- // })
139
-
140
- describe ( "Setup a ceremony that uses two VMs" , ( ) => {
107
+ } )
108
+ it ( "run a command on a VM that is active" , async ( ) => {
109
+ commandId = await runCommandOnEC2 ( ssmClient , ssmTestInstance . InstanceId ! , [
110
+ "echo $(whoami) >> hello.txt"
111
+ ] )
112
+ expect ( commandId ) . to . not . be . null
113
+ await sleep ( 500 )
114
+ } )
115
+ it ( "should run multiple commands" , async ( ) => {
116
+ await runCommandOnEC2 ( ssmClient , ssmTestInstance . InstanceId ! , [
117
+ "su ubuntu" , "whoami" , "id" , "pwd" , "ls -la" , "ls -la /root" , "ls -la /home/ubuntu" ,
118
+ ] )
119
+ } )
120
+ it ( "should throw when trying to call a command on a VM that is not active" , async ( ) => {
121
+ await expect ( runCommandOnEC2 ( ssmClient , "nonExistentOrOff" , [ "echo hello world" ] ) ) . to . be . rejected
122
+ } )
123
+ it ( "should retrieve the output of a command" , async ( ) => {
124
+ await sleep ( 20000 )
125
+ const output = await retrieveCommandOutput ( ssmClient , commandId , ssmTestInstance . InstanceId ! )
126
+ expect ( output . length ) . to . be . gt ( 0 )
127
+ } )
128
+ it ( "should throw when trying to retrieve the output of a non existent command" , async ( ) => {
129
+ await expect ( retrieveCommandOutput ( ssmClient , "nonExistentCommand" , ssmTestInstance . InstanceId ! ) ) . to . be . rejected
130
+ } )
131
+ afterAll ( async ( ) => {
132
+ await terminateEC2Instance ( ec2 , ssmTestInstance . InstanceId ! )
133
+ } )
134
+ } )
135
+
136
+ afterAll ( async ( ) => {
137
+ await terminateEC2Instance ( ec2 , instance . InstanceId ! )
138
+ } )
139
+
140
+ describe ( "Setup and run a ceremony using VMs" , ( ) => {
141
141
// Sample data for running the test.
142
142
const users = [ fakeUsersData . fakeUser1 , fakeUsersData . fakeUser2 ]
143
143
const passwords = generateUserPasswords ( 2 )
@@ -149,7 +149,7 @@ describe("VMs", () => {
149
149
150
150
// Get configs for storage.
151
151
const { ceremonyBucketPostfix, streamChunkSizeInMb } = getStorageConfiguration ( )
152
- const ceremony = fakeCeremoniesData . fakeCeremonyScheduledDynamic
152
+ const ceremony = fakeCeremoniesData . fakeCeremonyOpenedFixed
153
153
const ceremonyBucket = getBucketName ( ceremony . data . prefix , ceremonyBucketPostfix )
154
154
const circuit = fakeCircuitsData . fakeCircuitSmallNoContributors
155
155
@@ -177,6 +177,8 @@ describe("VMs", () => {
177
177
// s3 objects we have to delete
178
178
const objectsToDelete = [ potStoragePath , storagePath ]
179
179
180
+ const secondCeremonyId = ceremony . uid
181
+
180
182
beforeAll ( async ( ) => {
181
183
// create 2 users the second is the coordinator
182
184
for ( let i = 0 ; i < 2 ; i ++ ) {
@@ -197,25 +199,29 @@ describe("VMs", () => {
197
199
await multiPartUpload ( userFunctions , ceremonyBucket , storagePath , zkeyPath , streamChunkSizeInMb )
198
200
// pot upload
199
201
await multiPartUpload ( userFunctions , ceremonyBucket , potStoragePath , potPath , streamChunkSizeInMb )
202
+
203
+
204
+ // create mock ceremony with circuit data
205
+ await createMockCeremony ( adminFirestore , ceremony , circuit )
200
206
} )
201
207
202
208
afterAll ( async ( ) => {
203
- // for (const instanceId of instancesToTerminate) {
204
- // await terminateEC2Instance(ec2, instanceId)
205
- // }
209
+ for ( const instanceId of instancesToTerminate ) {
210
+ await terminateEC2Instance ( ec2 , instanceId )
211
+ }
206
212
207
- // for (const objectToDelete of objectsToDelete) {
208
- // await deleteObjectFromS3(ceremonyBucket, objectToDelete)
209
- // }
210
- // await deleteBucket(ceremonyBucket)
213
+ for ( const objectToDelete of objectsToDelete ) {
214
+ await deleteObjectFromS3 ( ceremonyBucket , objectToDelete )
215
+ }
216
+ await deleteBucket ( ceremonyBucket )
211
217
212
218
await cleanUpMockUsers ( adminAuth , adminFirestore , users )
213
219
await cleanUpRecursively ( adminFirestore , ceremonyId )
214
220
215
221
fs . rmdirSync ( `${ outputDirectory } ` , { recursive : true } )
216
222
} )
217
223
218
- it . only ( "should create a ceremony and two VMs should spin up" , async ( ) => {
224
+ it ( "should create a ceremony and the VM should spin up" , async ( ) => {
219
225
// 1. setup ceremony
220
226
ceremonyId = await setupCeremony ( userFunctions , ceremony . data , ceremony . data . prefix ! , [ circuit . data ] )
221
227
@@ -240,11 +246,19 @@ describe("VMs", () => {
240
246
await signInWithEmailAndPassword ( userAuth , users [ 0 ] . data . email , passwords [ 0 ] )
241
247
await sleep ( 500 )
242
248
// 2. get circuits for ceremony
243
- const circuits = await getCeremonyCircuits ( userFirestore , ceremonyId )
249
+ const circuits = await getCeremonyCircuits ( userFirestore , secondCeremonyId )
244
250
expect ( circuits . length ) . to . be . gt ( 0 )
245
251
252
+ // set the VM instance ID that we setup before
253
+ for ( const circuit of circuits ) {
254
+ await adminFirestore . collection ( getCircuitsCollectionPath ( secondCeremonyId ) ) . doc ( circuit . id ) . set ( {
255
+ ...circuit . data ,
256
+ vmInstanceId : instancesToTerminate [ circuits . indexOf ( circuit ) ]
257
+ } )
258
+ }
259
+
246
260
// 3. register for cermeony
247
- const canParticipate = await checkParticipantForCeremony ( userFunctions , ceremonyId )
261
+ const canParticipate = await checkParticipantForCeremony ( userFunctions , secondCeremonyId )
248
262
expect ( canParticipate ) . to . be . true
249
263
250
264
// 4. entropy
@@ -273,39 +287,39 @@ describe("VMs", () => {
273
287
fs . writeFileSync ( lastZkeyLocalFilePath , await getResponse . buffer ( ) )
274
288
await sleep ( 500 )
275
289
// 9. progress to next step
276
- await progressToNextCircuitForContribution ( userFunctions , ceremonyId )
290
+ await progressToNextCircuitForContribution ( userFunctions , secondCeremonyId )
277
291
await sleep ( 1000 )
278
292
279
293
const transcriptLocalFilePath = `${ outputDirectory } /${ getTranscriptLocalFilePath (
280
294
`${ circuit . data . prefix } _${ nextZkeyIndex } .log`
281
295
) } `
282
296
const transcriptLogger = createCustomLoggerForFile ( transcriptLocalFilePath )
283
297
// 10. do contribution
284
- await zKey . contribute ( lastZkeyLocalFilePath , nextZkeyLocalFilePath , users [ 2 ] . uid , entropy , transcriptLogger )
298
+ await zKey . contribute ( lastZkeyLocalFilePath , nextZkeyLocalFilePath , users [ 0 ] . uid , entropy , transcriptLogger )
285
299
await sleep ( 1000 )
286
300
287
301
// read the contribution hash
288
302
const transcriptContents = fs . readFileSync ( transcriptLocalFilePath , "utf-8" ) . toString ( )
289
303
const matchContributionHash = transcriptContents . match ( / C o n t r i b u t i o n .+ H a s h .+ \n \t \t .+ \n \t \t .+ \n .+ \n \t \t .+ \n / )
290
304
const contributionHash = matchContributionHash ?. at ( 0 ) ?. replace ( "\n\t\t" , "" ) !
291
305
292
- await progressToNextContributionStep ( userFunctions , ceremonyId )
306
+ await progressToNextContributionStep ( userFunctions , secondCeremonyId )
293
307
await sleep ( 2000 )
294
308
await permanentlyStoreCurrentContributionTimeAndHash (
295
309
userFunctions ,
296
- ceremonyId ,
310
+ secondCeremonyId ,
297
311
new Date ( ) . valueOf ( ) ,
298
312
contributionHash
299
313
)
300
314
await sleep ( 2000 )
301
315
302
- await progressToNextContributionStep ( userFunctions , ceremonyId )
316
+ await progressToNextContributionStep ( userFunctions , secondCeremonyId )
303
317
await sleep ( 1000 )
304
318
305
319
const participant = await getDocumentById (
306
320
userFirestore ,
307
- getParticipantsCollectionPath ( ceremonyId ) ,
308
- users [ 2 ] . uid
321
+ getParticipantsCollectionPath ( secondCeremonyId ) ,
322
+ users [ 0 ] . uid
309
323
)
310
324
311
325
// Upload
@@ -319,7 +333,7 @@ describe("VMs", () => {
319
333
nextZkeyStoragePath ,
320
334
nextZkeyLocalFilePath ,
321
335
streamChunkSizeInMb ,
322
- ceremony . uid ,
336
+ secondCeremonyId ,
323
337
participant . data ( ) ! . tempContributionData
324
338
)
325
339
await sleep ( 1000 )
@@ -329,16 +343,16 @@ describe("VMs", () => {
329
343
// Execute contribution verification.
330
344
const tempCircuit = await getDocumentById (
331
345
userFirestore ,
332
- getCircuitsCollectionPath ( ceremonyId ) ,
346
+ getCircuitsCollectionPath ( secondCeremonyId ) ,
333
347
circuit . id
334
348
)
335
349
336
350
await verifyContribution (
337
351
userFunctions ,
338
- ceremonyId ,
352
+ secondCeremonyId ,
339
353
tempCircuit ,
340
354
ceremonyBucket ,
341
- users [ 2 ] . uid ,
355
+ users [ 0 ] . uid ,
342
356
String ( process . env . FIREBASE_CF_URL_VERIFY_CONTRIBUTION )
343
357
)
344
358
} )
0 commit comments