@@ -27,7 +27,10 @@ type BenchmarkResult struct {
2727 MedianTime time.Duration
2828 OperationTimes []time.Duration
2929 ErrorRate float64
30- OperationsPerSec float64
30+ OperationsPerMin float64
31+ BatchSize int
32+ TotalBatches int
33+ BatchTimes []time.Duration
3134}
3235
3336func main () {
@@ -80,6 +83,12 @@ func keygenBenchmarkCommand() *cli.Command {
8083 Value : 30 ,
8184 Aliases : []string {"t" },
8285 },
86+ & cli.IntFlag {
87+ Name : "batch-size" ,
88+ Usage : "Number of operations per batch" ,
89+ Value : 10 ,
90+ Aliases : []string {"b" },
91+ },
8392 },
8493 }
8594}
@@ -97,6 +106,12 @@ func ecdsaSignBenchmarkCommand() *cli.Command {
97106 Value : 30 ,
98107 Aliases : []string {"t" },
99108 },
109+ & cli.IntFlag {
110+ Name : "batch-size" ,
111+ Usage : "Number of operations per batch" ,
112+ Value : 10 ,
113+ Aliases : []string {"b" },
114+ },
100115 },
101116 }
102117}
@@ -114,6 +129,12 @@ func eddsaSignBenchmarkCommand() *cli.Command {
114129 Value : 30 ,
115130 Aliases : []string {"t" },
116131 },
132+ & cli.IntFlag {
133+ Name : "batch-size" ,
134+ Usage : "Number of operations per batch" ,
135+ Value : 10 ,
136+ Aliases : []string {"b" },
137+ },
117138 },
118139 }
119140}
@@ -131,6 +152,12 @@ func reshareBenchmarkCommand() *cli.Command {
131152 Value : 30 ,
132153 Aliases : []string {"t" },
133154 },
155+ & cli.IntFlag {
156+ Name : "batch-size" ,
157+ Usage : "Number of operations per batch" ,
158+ Value : 10 ,
159+ Aliases : []string {"b" },
160+ },
134161 & cli.IntFlag {
135162 Name : "new-threshold" ,
136163 Usage : "New threshold for resharing" ,
@@ -156,11 +183,22 @@ func createMPCClient(cmd *cli.Command) (client.MPCClient, error) {
156183 return nil , fmt .Errorf ("failed to connect to NATS: %w" , err )
157184 }
158185
159- opts := client. Options {
160- NatsConn : nc ,
186+ // Create a LocalSigner with the provided key path and password
187+ signerOpts := client. LocalSignerOptions {
161188 KeyPath : keyPath ,
162189 Password : password ,
163190 }
191+
192+ // Default to Ed25519 for event initiator keys
193+ signer , err := client .NewLocalSigner (types .EventInitiatorKeyTypeEd25519 , signerOpts )
194+ if err != nil {
195+ return nil , fmt .Errorf ("failed to create signer: %w" , err )
196+ }
197+
198+ opts := client.Options {
199+ NatsConn : nc ,
200+ Signer : signer ,
201+ }
164202 return client .NewMPCClient (opts ), nil
165203}
166204
@@ -259,7 +297,7 @@ func runKeygenBenchmark(ctx context.Context, cmd *cli.Command) error {
259297 totalTime := time .Since (startTime )
260298
261299 // Calculate results
262- benchResult := calculateBenchmarkResult (results , totalTime )
300+ benchResult := calculateBenchmarkResult (results , totalTime , 1 , []time. Duration { totalTime } )
263301 printBenchmarkResult ("Keygen" , benchResult )
264302
265303 return nil
@@ -287,13 +325,15 @@ func runSignBenchmark(ctx context.Context, cmd *cli.Command, keyType types.KeyTy
287325 }
288326
289327 timeout := time .Duration (cmd .Int ("timeout" )) * time .Second
328+ batchSize := cmd .Int ("batch-size" )
290329
291330 mpcClient , err := createMPCClient (cmd )
292331 if err != nil {
293332 return err
294333 }
295334
296- fmt .Printf ("Starting %s signing benchmark with %d operations for wallet %s...\n " , keyTypeName , n , walletID )
335+ totalBatches := (n + batchSize - 1 ) / batchSize
336+ fmt .Printf ("Starting %s signing benchmark with %d operations (%d batches of %d) for wallet %s...\n " , keyTypeName , n , totalBatches , batchSize , walletID )
297337
298338 var results []OperationResult
299339 var wg sync.WaitGroup
@@ -322,47 +362,79 @@ func runSignBenchmark(ctx context.Context, cmd *cli.Command, keyType types.KeyTy
322362 return fmt .Errorf ("failed to set up result listener: %w" , err )
323363 }
324364
325- // Run operations
365+ // Run operations in batches
326366 startTime := time .Now ()
327- for i := 0 ; i < n ; i ++ {
328- txID := fmt .Sprintf ("benchmark-%s-sign-%d-%d" , keyTypeName , time .Now ().UnixNano (), i )
329-
330- // Generate random transaction data
331- txData := make ([]byte , 32 )
332- rand .Read (txData )
333-
334- msg := & types.SignTxMessage {
335- KeyType : keyType ,
336- WalletID : walletID ,
337- NetworkInternalCode : "benchmark" ,
338- TxID : txID ,
339- Tx : txData ,
367+ var batchTimes []time.Duration
368+
369+ // Start progress reporting goroutine
370+ progressTicker := time .NewTicker (10 * time .Second )
371+ defer progressTicker .Stop ()
372+ go func () {
373+ for range progressTicker .C {
374+ mu .Lock ()
375+ completed := 0
376+ for _ , r := range results {
377+ if r .Completed {
378+ completed ++
379+ }
380+ }
381+ mu .Unlock ()
382+ fmt .Printf ("Progress: %d/%d results received\n " , completed , n )
340383 }
384+ }()
341385
342- result := OperationResult {
343- ID : txID ,
344- StartTime : time .Now (),
386+ for batchNum := 0 ; batchNum < totalBatches ; batchNum ++ {
387+ batchStart := time .Now ()
388+ batchStartIdx := batchNum * batchSize
389+ batchEndIdx := batchStartIdx + batchSize
390+ if batchEndIdx > n {
391+ batchEndIdx = n
345392 }
346393
347- mu .Lock ()
348- results = append (results , result )
349- mu .Unlock ()
394+ fmt .Printf ("Starting batch %d/%d (%d operations)...\n " , batchNum + 1 , totalBatches , batchEndIdx - batchStartIdx )
350395
351- wg .Add (1 )
396+ for i := batchStartIdx ; i < batchEndIdx ; i ++ {
397+ txID := fmt .Sprintf ("benchmark-%s-sign-%d-%d" , keyTypeName , time .Now ().UnixNano (), i )
398+
399+ // Generate random transaction data
400+ txData := make ([]byte , 32 )
401+ rand .Read (txData )
402+
403+ msg := & types.SignTxMessage {
404+ KeyType : keyType ,
405+ WalletID : walletID ,
406+ NetworkInternalCode : "benchmark" ,
407+ TxID : txID ,
408+ Tx : txData ,
409+ }
410+
411+ result := OperationResult {
412+ ID : txID ,
413+ StartTime : time .Now (),
414+ }
352415
353- err := mpcClient .SignTransaction (msg )
354- if err != nil {
355416 mu .Lock ()
356- results [i ].Completed = true
357- results [i ].Success = false
358- results [i ].ErrorReason = err .Error ()
359- results [i ].EndTime = time .Now ()
417+ results = append (results , result )
360418 mu .Unlock ()
361- wg .Done ()
419+
420+ wg .Add (1 )
421+
422+ err := mpcClient .SignTransaction (msg )
423+ if err != nil {
424+ mu .Lock ()
425+ results [i ].Completed = true
426+ results [i ].Success = false
427+ results [i ].ErrorReason = err .Error ()
428+ results [i ].EndTime = time .Now ()
429+ mu .Unlock ()
430+ wg .Done ()
431+ }
432+
433+ // Add small delay between operations
434+ time .Sleep (10 * time .Millisecond )
362435 }
363436
364- // Add small delay between operations
365- time .Sleep (10 * time .Millisecond )
437+ batchTimes = append (batchTimes , time .Since (batchStart ))
366438 }
367439
368440 // Wait for all operations with timeout
@@ -382,7 +454,7 @@ func runSignBenchmark(ctx context.Context, cmd *cli.Command, keyType types.KeyTy
382454 totalTime := time .Since (startTime )
383455
384456 // Calculate results
385- benchResult := calculateBenchmarkResult (results , totalTime )
457+ benchResult := calculateBenchmarkResult (results , totalTime , batchSize , batchTimes )
386458 printBenchmarkResult (fmt .Sprintf ("%s Signing" , keyTypeName ), benchResult )
387459
388460 return nil
@@ -505,7 +577,7 @@ func runReshareBenchmark(ctx context.Context, cmd *cli.Command) error {
505577 totalTime := time .Since (startTime )
506578
507579 // Calculate results
508- benchResult := calculateBenchmarkResult (results , totalTime )
580+ benchResult := calculateBenchmarkResult (results , totalTime , 1 , []time. Duration { totalTime } )
509581 printBenchmarkResult ("Reshare" , benchResult )
510582
511583 return nil
@@ -533,7 +605,7 @@ func parseNumOps(numOps string) (int, error) {
533605 return n , nil
534606}
535607
536- func calculateBenchmarkResult (results []OperationResult , totalTime time.Duration ) BenchmarkResult {
608+ func calculateBenchmarkResult (results []OperationResult , totalTime time.Duration , batchSize int , batchTimes []time. Duration ) BenchmarkResult {
537609 var operationTimes []time.Duration
538610 successfulOps := 0
539611 failedOps := 0
@@ -577,8 +649,8 @@ func calculateBenchmarkResult(results []OperationResult, totalTime time.Duration
577649 medianTime = operationTimes [len (operationTimes )/ 2 ]
578650 }
579651
580- // Calculate operations per second
581- operationsPerSec = float64 (successfulOps ) / totalTime .Seconds ()
652+ // Calculate operations per minute
653+ operationsPerSec = float64 (successfulOps ) / totalTime .Minutes ()
582654 }
583655
584656 return BenchmarkResult {
@@ -590,25 +662,60 @@ func calculateBenchmarkResult(results []OperationResult, totalTime time.Duration
590662 MedianTime : medianTime ,
591663 OperationTimes : operationTimes ,
592664 ErrorRate : errorRate ,
593- OperationsPerSec : operationsPerSec ,
665+ OperationsPerMin : operationsPerSec ,
666+ BatchSize : batchSize ,
667+ TotalBatches : len (batchTimes ),
668+ BatchTimes : batchTimes ,
594669 }
595670}
596671
597672func printBenchmarkResult (operationType string , result BenchmarkResult ) {
598- fmt .Printf ("\n === %s Benchmark Results ===\n " , operationType )
599- fmt .Printf ("Total Operations: %d\n " , result .TotalOperations )
600- fmt .Printf ("Successful: %d\n " , result .SuccessfulOps )
601- fmt .Printf ("Failed: %d\n " , result .FailedOps )
602- fmt .Printf ("Error Rate: %.2f%%\n " , result .ErrorRate )
603- fmt .Printf ("Total Time: %v\n " , result .TotalTime )
604- fmt .Printf ("Average Time/Op: %v\n " , result .AverageTime )
605- fmt .Printf ("Median Time/Op: %v\n " , result .MedianTime )
606- fmt .Printf ("Operations/Second: %.2f\n " , result .OperationsPerSec )
607-
608- if len (result .OperationTimes ) > 0 {
609- fmt .Printf ("Min Time/Op: %v\n " , result .OperationTimes [0 ])
610- fmt .Printf ("Max Time/Op: %v\n " , result .OperationTimes [len (result .OperationTimes )- 1 ])
611- }
612-
613- fmt .Println ("=====================================" )
673+ fmt .Println ()
674+ fmt .Println ("===============================" )
675+ fmt .Printf ("BENCHMARK RESULTS SUMMARY\n " )
676+ fmt .Println ("===============================" )
677+ fmt .Printf ("Total benchmark time: %v\n " , result .TotalTime )
678+ fmt .Printf ("Total batches sent: %d\n " , result .TotalBatches )
679+ fmt .Printf ("Total requests sent: %d\n " , result .TotalOperations )
680+ fmt .Printf ("Successful completions: %d\n " , result .SuccessfulOps )
681+ fmt .Printf ("Success rate: %.2f%%\n " , 100.0 - result .ErrorRate )
682+ fmt .Printf ("Average signs per minute: %.2f\n " , result .OperationsPerMin )
683+
684+ fmt .Println ()
685+ fmt .Println ("------------------------------" )
686+ fmt .Printf ("%d REQUEST ANALYSIS\n " , result .BatchSize )
687+ fmt .Println ("------------------------------" )
688+
689+ if len (result .OperationTimes ) >= result .BatchSize {
690+ firstNResults := result .OperationTimes [:result .BatchSize ]
691+ if len (firstNResults ) > len (result .OperationTimes ) {
692+ firstNResults = result .OperationTimes
693+ }
694+
695+ completedCount := len (firstNResults )
696+ if completedCount > result .BatchSize {
697+ completedCount = result .BatchSize
698+ }
699+
700+ fmt .Printf ("Completed from first %d: %d/%d\n " , result .BatchSize , completedCount , result .BatchSize )
701+
702+ if len (firstNResults ) > 0 {
703+ var totalTime time.Duration
704+ minTime := firstNResults [0 ]
705+ maxTime := firstNResults [0 ]
706+
707+ for _ , t := range firstNResults {
708+ totalTime += t
709+ if t < minTime {
710+ minTime = t
711+ }
712+ if t > maxTime {
713+ maxTime = t
714+ }
715+ }
716+
717+ fmt .Printf ("Fastest (first %d): %v\n " , result .BatchSize , minTime )
718+ fmt .Printf ("Slowest (first %d): %v\n " , result .BatchSize , maxTime )
719+ }
720+ }
614721}
0 commit comments