@@ -162,6 +162,11 @@ func (com *Communication) Start(actors []*Actor, node *Node, txCurve map[int32]*
162
162
com .wg .Add (1 )
163
163
go com .Shutdown (miner , actors , node )
164
164
165
+ log .Printf ("%s: Generating %v blocks..." , miner , * startBlock )
166
+ if err := miner .Generate (uint32 (* startBlock ) - 1 ); err != nil {
167
+ return
168
+ }
169
+
165
170
return
166
171
}
167
172
@@ -428,159 +433,132 @@ func (com *Communication) estimateTpb(tpbChan chan<- int) {
428
433
func (com * Communication ) Communicate (txCurve map [int32 ]* Row , miner * Miner , actors []* Actor ) {
429
434
defer com .wg .Done ()
430
435
431
- for {
436
+ for h , row := range txCurve {
437
+ // wait until this block is processed
432
438
select {
433
- case h := <- com .height :
434
-
435
- // stop simulation if we're at the last block
436
- if h > int32 (* stopBlock ) {
437
- close (com .exit )
438
- return
439
- }
440
-
441
- // disable mining until the required no. of tx are in mempool
442
- if err := miner .StopMining (); err != nil {
443
- close (com .exit )
444
- return
445
- }
446
-
447
- // wait until this block is processed
448
- select {
449
- case <- com .blockQueue .processed :
450
- case <- com .exit :
451
- return
452
- }
453
-
454
- var wg sync.WaitGroup
455
- // count the number of utxos available in total
456
- var utxoCount int
457
- for _ , a := range actors {
458
- utxoCount += len (a .utxoQueue .utxos )
459
- }
439
+ case <- com .blockQueue .processed :
440
+ case <- com .exit :
441
+ return
442
+ }
460
443
461
- // the required transactions are divided into two groups because we need some of them to
462
- // contribute to the utxo count required for the next block and the rest to contribute to
463
- // the tx count
464
- //
465
- // it is possible to keep dividing the same utxo until it's broken into the required
466
- // number of pieces but we want to stay close to the real world scenario and maximize
467
- // the number of utxos used
468
- //
469
- // E.g: Assume the following CSV
470
- //
471
- // block,utxos,tx
472
- // 20000,40000,20000
473
- // 20001,50000,25000
474
- //
475
- // at block 19999, we need to ensure that next block has 40K utxos
476
- // we have 19999 - blockchain.CoinbaseMaturity = 19899 utxos
477
- // we need to create 40K-19899 = 20101 utxos so in this case, so
478
- // we create 20101 tx which give 1 net utxo output
479
- //
480
- // at block 20000, we need to ensure that next block has 50K utxos
481
- // we already have 40K by the previous iteration, so we need 50-40 = 10K utxos
482
- // we also need to generate 20K tx before the next block, so
483
- // create 10000 tx which generate 1 net utxo plus 10000 tx without any net utxo
484
- //
485
- // since we cannot generate more tx than the no of available utxos, the no of tx
486
- // that can be generated at any iteration is limited by the utxos available
487
-
488
- // in case the next row doesn't exist, we initialize the required no of utxos to zero
489
- // so we keep the utxoCount same as current count
490
- next , ok := txCurve [h + 2 ]
491
- if ! ok {
492
- next = & Row {}
493
- next .utxoCount = utxoCount
494
- }
444
+ var wg sync.WaitGroup
445
+ // count the number of utxos available in total
446
+ var utxoCount int
447
+ for _ , a := range actors {
448
+ utxoCount += len (a .utxoQueue .utxos )
449
+ }
495
450
496
- // reqUtxoCount is the number of utxos required
497
- reqUtxoCount := 0
498
- if next .utxoCount > utxoCount {
499
- reqUtxoCount = next .utxoCount - utxoCount
500
- }
451
+ // the required transactions are divided into two groups because we need some of them to
452
+ // contribute to the utxo count required for the next block and the rest to contribute to
453
+ // the tx count
454
+ //
455
+ // it is possible to keep dividing the same utxo until it's broken into the required
456
+ // number of pieces but we want to stay close to the real world scenario and maximize
457
+ // the number of utxos used
458
+ //
459
+ // E.g: Assume the following CSV
460
+ //
461
+ // block,utxos,tx
462
+ // 20000,40000,20000
463
+ // 20001,50000,25000
464
+ //
465
+ // at block 19999, we need to ensure that next block has 40K utxos
466
+ // we have 19999 - blockchain.CoinbaseMaturity = 19899 utxos
467
+ // we need to create 40K-19899 = 20101 utxos so in this case, so
468
+ // we create 20101 tx which give 1 net utxo output
469
+ //
470
+ // at block 20000, we need to ensure that next block has 50K utxos
471
+ // we already have 40K by the previous iteration, so we need 50-40 = 10K utxos
472
+ // we also need to generate 20K tx before the next block, so
473
+ // create 10000 tx which generate 1 net utxo plus 10000 tx without any net utxo
474
+ //
475
+ // since we cannot generate more tx than the no of available utxos, the no of tx
476
+ // that can be generated at any iteration is limited by the utxos available
477
+
478
+ // in case the next row doesn't exist, we initialize the required no of utxos to zero
479
+ // so we keep the utxoCount same as current count
480
+ next , ok := txCurve [h + 1 ]
481
+ if ! ok {
482
+ next = & Row {}
483
+ next .utxoCount = utxoCount
484
+ }
501
485
502
- // in case this row doesn't exist, we initialize the required no of tx to reqUtxoCount
503
- // i.e one tx per utxo required
504
- row , ok := txCurve [h + 1 ]
505
- if ! ok {
506
- row = & Row {}
507
- row .txCount = reqUtxoCount
508
- }
486
+ // reqUtxoCount is the number of utxos required
487
+ reqUtxoCount := 0
488
+ if next .utxoCount > utxoCount {
489
+ reqUtxoCount = next .utxoCount - utxoCount
490
+ }
509
491
510
- // reqTxCount is the number of tx that will generate reqUtxoCount
511
- // no of utxos
512
- reqTxCount := row .txCount
513
- if reqTxCount > utxoCount {
514
- log .Printf ("Warning: capping no of transactions at %v based on no of available utxos" , utxoCount )
515
- // cap the total no of tx at the no of available utxos
516
- reqTxCount = utxoCount
517
- }
492
+ // reqTxCount is the number of tx that will generate reqUtxoCount
493
+ // no of utxos
494
+ reqTxCount := row .txCount
495
+ if reqTxCount > utxoCount {
496
+ log .Printf ("Warning: capping no of transactions at %v based on no of available utxos" , utxoCount )
497
+ // cap the total no of tx at the no of available utxos
498
+ reqTxCount = utxoCount
499
+ }
518
500
519
- var multiplier , totalUtxos , totalTx int
520
- // skip if we already have more than the no of utxos required
521
- if reqUtxoCount > 0 {
522
- // e.g: if we need 18K utxos in 12K tx
523
- // multiplier = [18000/12000] = [1.5] = 2
524
- // totalUtxos = 18000/2 = 9000
525
- // totalTx = 120000 - 9000 = 3000
526
- multiplier = int (math .Ceil (float64 (reqUtxoCount ) / float64 (reqTxCount )))
527
- if multiplier > * maxSplit {
528
- // cap maximum splits at maxSplit
529
- multiplier = * maxSplit
530
- }
531
- totalUtxos = reqUtxoCount / multiplier
501
+ var multiplier , totalUtxos , totalTx int
502
+ // skip if we already have more than the no of utxos required
503
+ if reqUtxoCount > 0 {
504
+ // e.g: if we need 18K utxos in 12K tx
505
+ // multiplier = [18000/12000] = [1.5] = 2
506
+ // totalUtxos = 18000/2 = 9000
507
+ // totalTx = 120000 - 9000 = 3000
508
+ multiplier = int (math .Ceil (float64 (reqUtxoCount ) / float64 (reqTxCount )))
509
+ if multiplier > * maxSplit {
510
+ // cap maximum splits at maxSplit
511
+ multiplier = * maxSplit
532
512
}
513
+ totalUtxos = reqUtxoCount / multiplier
514
+ }
533
515
534
- // if we're not already covered by the utxo transactions, generate additional tx
535
- if reqTxCount > totalUtxos {
536
- totalTx = reqTxCount - totalUtxos
537
- }
516
+ // if we're not already covered by the utxo transactions, generate additional tx
517
+ if reqTxCount > totalUtxos {
518
+ totalTx = reqTxCount - totalUtxos
519
+ }
538
520
539
- if reqTxCount > 0 {
540
- log .Printf ("Generating %v transactions ..." , reqTxCount )
541
- }
542
- if totalTx > 0 {
543
- for i := 0 ; i < totalTx ; i ++ {
544
- fmt .Printf ("\r %d/%d" , i + 1 , reqTxCount )
545
- a := actors [rand .Int ()% len (actors )]
546
- addr := a .ownedAddresses [rand .Int ()% len (a .ownedAddresses )]
547
- select {
548
- case com .downstream <- addr :
549
- // For every address sent downstream (one transaction about to happen),
550
- // spawn a goroutine to listen for an accepted transaction in the mempool
551
- wg .Add (1 )
552
- go com .txPoolRecv (& wg )
553
- case <- com .exit :
554
- return
555
- }
521
+ if reqTxCount > 0 {
522
+ log .Printf ("Generating %v transactions ..." , reqTxCount )
523
+ }
524
+ if totalTx > 0 {
525
+ for i := 0 ; i < totalTx ; i ++ {
526
+ fmt .Printf ("\r %d/%d" , i + 1 , reqTxCount )
527
+ a := actors [rand .Int ()% len (actors )]
528
+ addr := a .ownedAddresses [rand .Int ()% len (a .ownedAddresses )]
529
+ select {
530
+ case com .downstream <- addr :
531
+ // For every address sent downstream (one transaction about to happen),
532
+ // spawn a goroutine to listen for an accepted transaction in the mempool
533
+ wg .Add (1 )
534
+ go com .txPoolRecv (& wg )
535
+ case <- com .exit :
536
+ return
556
537
}
557
538
}
539
+ }
558
540
559
- if totalUtxos > 0 {
560
- for i := 0 ; i < totalUtxos ; i ++ {
561
- fmt .Printf ("\r %d/%d" , i + totalTx + 1 , reqTxCount )
562
- select {
563
- case com .split <- multiplier :
564
- // For every address sent downstream (one transaction about to happen),
565
- // spawn a goroutine to listen for an accepted transaction in the mempool
566
- wg .Add (1 )
567
- go com .txPoolRecv (& wg )
568
- case <- com .exit :
569
- return
570
- }
541
+ if totalUtxos > 0 {
542
+ for i := 0 ; i < totalUtxos ; i ++ {
543
+ fmt .Printf ("\r %d/%d" , i + totalTx + 1 , reqTxCount )
544
+ select {
545
+ case com .split <- multiplier :
546
+ // For every address sent downstream (one transaction about to happen),
547
+ // spawn a goroutine to listen for an accepted transaction in the mempool
548
+ wg .Add (1 )
549
+ go com .txPoolRecv (& wg )
550
+ case <- com .exit :
551
+ return
571
552
}
572
553
}
554
+ }
573
555
574
- fmt .Printf ("\n " )
575
- log .Printf ("Waiting for miner..." )
576
- wg .Wait ()
577
- // mine the above tx in the next block
578
- if err := miner .StartMining (); err != nil {
579
- close (com .exit )
580
- return
581
- }
582
- case <- com .exit :
583
- return
556
+ fmt .Printf ("\n " )
557
+ log .Printf ("Waiting for miner..." )
558
+ wg .Wait ()
559
+ // mine the above tx in the next block
560
+ if err := miner .Generate (1 ); err != nil {
561
+ close (com .exit )
584
562
}
585
563
}
586
564
}
0 commit comments