@@ -126,6 +126,7 @@ type environment struct {
126
126
traceEnv * tracing.TraceEnv // env for tracing
127
127
accRows * types.RowConsumption // accumulated row consumption for a block
128
128
nextL1MsgIndex uint64 // next L1 queue index to be processed
129
+ start time.Time // time we started building this block
129
130
}
130
131
131
132
// task contains all information for consensus engine sealing and result submitting.
@@ -424,15 +425,10 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t
424
425
func (w * worker ) newWorkLoop (recommit time.Duration ) {
425
426
defer w .wg .Done ()
426
427
var (
427
- interrupt * int32
428
- minRecommit = recommit // minimal resubmit interval specified by user.
429
- timestamp int64 // timestamp for each round of mining.
428
+ interrupt * int32
429
+ timestamp int64 // timestamp for each round of mining.
430
430
)
431
431
432
- timer := time .NewTimer (0 )
433
- defer timer .Stop ()
434
- <- timer .C // discard the initial tick
435
-
436
432
// commit aborts in-flight transaction execution with given signal and resubmits a new one.
437
433
commit := func (noempty bool , s int32 ) {
438
434
if interrupt != nil {
@@ -444,7 +440,6 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
444
440
case <- w .exitCh :
445
441
return
446
442
}
447
- timer .Reset (recommit )
448
443
atomic .StoreInt32 (& w .newTxs , 0 )
449
444
atomic .StoreInt32 (& w .newL1Msgs , 0 )
450
445
}
@@ -465,54 +460,10 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
465
460
clearPending (w .chain .CurrentBlock ().NumberU64 ())
466
461
timestamp = time .Now ().Unix ()
467
462
commit (false , commitInterruptNewHead )
468
-
469
463
case head := <- w .chainHeadCh :
470
464
clearPending (head .Block .NumberU64 ())
471
465
timestamp = time .Now ().Unix ()
472
466
commit (true , commitInterruptNewHead )
473
-
474
- case <- timer .C :
475
- // If mining is running resubmit a new work cycle periodically to pull in
476
- // higher priced transactions. Disable this overhead for pending blocks.
477
- if w .isRunning () && (w .chainConfig .Clique == nil || w .chainConfig .Clique .Period > 0 ) {
478
- // Short circuit if no new transaction arrives.
479
- if atomic .LoadInt32 (& w .newTxs ) == 0 && atomic .LoadInt32 (& w .newL1Msgs ) == 0 {
480
- timer .Reset (recommit )
481
- continue
482
- }
483
- commit (true , commitInterruptResubmit )
484
- }
485
-
486
- case interval := <- w .resubmitIntervalCh :
487
- // Adjust resubmit interval explicitly by user.
488
- if interval < minRecommitInterval {
489
- log .Warn ("Sanitizing miner recommit interval" , "provided" , interval , "updated" , minRecommitInterval )
490
- interval = minRecommitInterval
491
- }
492
- log .Info ("Miner recommit interval update" , "from" , minRecommit , "to" , interval )
493
- minRecommit , recommit = interval , interval
494
-
495
- if w .resubmitHook != nil {
496
- w .resubmitHook (minRecommit , recommit )
497
- }
498
-
499
- case adjust := <- w .resubmitAdjustCh :
500
- // Adjust resubmit interval by feedback.
501
- if adjust .inc {
502
- before := recommit
503
- target := float64 (recommit .Nanoseconds ()) / adjust .ratio
504
- recommit = recalcRecommit (minRecommit , recommit , target , true )
505
- log .Trace ("Increase miner recommit interval" , "from" , before , "to" , recommit )
506
- } else {
507
- before := recommit
508
- recommit = recalcRecommit (minRecommit , recommit , float64 (minRecommit .Nanoseconds ()), false )
509
- log .Trace ("Decrease miner recommit interval" , "from" , before , "to" , recommit )
510
- }
511
-
512
- if w .resubmitHook != nil {
513
- w .resubmitHook (minRecommit , recommit )
514
- }
515
-
516
467
case <- w .exitCh :
517
468
return
518
469
}
@@ -532,58 +483,29 @@ func (w *worker) mainLoop() {
532
483
}
533
484
}()
534
485
486
+ sealTimer := time .NewTimer (0 )
487
+ defer sealTimer .Stop ()
488
+
535
489
for {
536
490
select {
537
491
case req := <- w .newWorkCh :
538
492
w .commitNewWork (req .interrupt , req .noempty , req .timestamp )
539
- // new block created.
540
-
541
- case ev := <- w .chainSideCh :
542
- // Short circuit for duplicate side blocks
543
- if _ , exist := w .localUncles [ev .Block .Hash ()]; exist {
544
- continue
493
+ if w .chainConfig .Clique != nil {
494
+ sealTimer .Reset (time .Duration (w .chainConfig .Clique .Period ) * time .Second )
545
495
}
546
- if _ , exist := w .remoteUncles [ev .Block .Hash ()]; exist {
547
- continue
548
- }
549
- // Add side block to possible uncle block set depending on the author.
550
- if w .isLocalBlock != nil && w .isLocalBlock (ev .Block ) {
551
- w .localUncles [ev .Block .Hash ()] = ev .Block
496
+ case <- sealTimer .C :
497
+ if w .current != nil && w .current .tcount != 0 {
498
+ w .commit (nil , w .fullTaskHook , true )
552
499
} else {
553
- w . remoteUncles [ ev . Block . Hash ()] = ev . Block
500
+ sealTimer . Reset ( time . Second )
554
501
}
555
- // If our mining block contains less than 2 uncle blocks,
556
- // add the new uncle block if valid and regenerate a mining block.
557
- if w .isRunning () && w .current != nil && w .current .uncles .Cardinality () < 2 {
558
- start := time .Now ()
559
- if err := w .commitUncle (w .current , ev .Block .Header ()); err == nil {
560
- var uncles []* types.Header
561
- w .current .uncles .Each (func (item interface {}) bool {
562
- hash , ok := item .(common.Hash )
563
- if ! ok {
564
- return false
565
- }
566
- uncle , exist := w .localUncles [hash ]
567
- if ! exist {
568
- uncle , exist = w .remoteUncles [hash ]
569
- }
570
- if ! exist {
571
- return false
572
- }
573
- uncles = append (uncles , uncle .Header ())
574
- return false
575
- })
576
- w .commit (uncles , nil , true , start )
577
- }
578
- }
579
-
580
502
case ev := <- w .txsCh :
581
- // Apply transactions to the pending state if we're not mining.
503
+ // Apply transactions to the pending state
582
504
//
583
505
// Note all transactions received may not be continuous with transactions
584
506
// already included in the current mining block. These transactions will
585
507
// be automatically eliminated.
586
- if ! w . isRunning () && w .current != nil {
508
+ if w .current != nil {
587
509
// If block is already full, abort
588
510
if gp := w .current .gasPool ; gp != nil && gp .Gas () < params .TxGas {
589
511
continue
@@ -599,10 +521,11 @@ func (w *worker) mainLoop() {
599
521
}
600
522
txset := types .NewTransactionsByPriceAndNonce (w .current .signer , txs , w .current .header .BaseFee )
601
523
tcount := w .current .tcount
602
- w .commitTransactions (txset , coinbase , nil )
603
- // Only update the snapshot if any new transactons were added
604
- // to the pending block
605
- if tcount != w .current .tcount {
524
+ if seal := w .commitTransactions (txset , coinbase , nil ); seal {
525
+ w .commit (nil , w .fullTaskHook , true )
526
+ } else if tcount != w .current .tcount {
527
+ // Only update the snapshot if any new transactons were added
528
+ // to the pending block
606
529
w .updateSnapshot ()
607
530
}
608
531
} else {
@@ -799,7 +722,7 @@ func (w *worker) resultLoop() {
799
722
}
800
723
801
724
// makeCurrent creates a new environment for the current cycle.
802
- func (w * worker ) makeCurrent (parent * types.Block , header * types.Header ) error {
725
+ func (w * worker ) makeCurrent (parent * types.Block , header * types.Header , start time. Time ) error {
803
726
// Retrieve the parent state to execute on top and start a prefetcher for
804
727
// the miner to speed block sealing up a bit
805
728
state , err := w .chain .StateAt (parent .Root ())
@@ -829,6 +752,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
829
752
header : header ,
830
753
traceEnv : traceEnv ,
831
754
accRows : nil ,
755
+ start : start ,
832
756
}
833
757
// when 08 is processed ancestors contain 07 (quick block)
834
758
for _ , ancestor := range w .chain .GetBlocksFromHash (parent .Hash (), 7 ) {
@@ -995,7 +919,7 @@ func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Addres
995
919
return receipt .Logs , traces , nil
996
920
}
997
921
998
- func (w * worker ) commitTransactions (txs types.OrderedTransactionSet , coinbase common.Address , interrupt * int32 ) ( bool , bool ) {
922
+ func (w * worker ) commitTransactions (txs types.OrderedTransactionSet , coinbase common.Address , interrupt * int32 ) bool {
999
923
defer func (t0 time.Time ) {
1000
924
l2CommitTxsTimer .Update (time .Since (t0 ))
1001
925
}(time .Now ())
@@ -1004,7 +928,7 @@ func (w *worker) commitTransactions(txs types.OrderedTransactionSet, coinbase co
1004
928
1005
929
// Short circuit if current is nil
1006
930
if w .current == nil {
1007
- return true , circuitCapacityReached
931
+ return false
1008
932
}
1009
933
1010
934
gasLimit := w .current .header .GasLimit
@@ -1023,18 +947,7 @@ loop:
1023
947
// For the first two cases, the semi-finished work will be discarded.
1024
948
// For the third case, the semi-finished work will be submitted to the consensus engine.
1025
949
if interrupt != nil && atomic .LoadInt32 (interrupt ) != commitInterruptNone {
1026
- // Notify resubmit loop to increase resubmitting interval due to too frequent commits.
1027
- if atomic .LoadInt32 (interrupt ) == commitInterruptResubmit {
1028
- ratio := float64 (gasLimit - w .current .gasPool .Gas ()) / float64 (gasLimit )
1029
- if ratio < 0.1 {
1030
- ratio = 0.1
1031
- }
1032
- w .resubmitAdjustCh <- & intervalAdjust {
1033
- ratio : ratio ,
1034
- inc : true ,
1035
- }
1036
- }
1037
- return atomic .LoadInt32 (interrupt ) == commitInterruptNewHead , circuitCapacityReached
950
+ return false
1038
951
}
1039
952
// If we don't have enough gas for any further transactions then we're done
1040
953
if w .current .gasPool .Gas () < params .TxGas {
@@ -1274,12 +1187,7 @@ loop:
1274
1187
}
1275
1188
w .pendingLogsFeed .Send (cpy )
1276
1189
}
1277
- // Notify resubmit loop to decrease resubmitting interval if current interval is larger
1278
- // than the user-specified one.
1279
- if interrupt != nil {
1280
- w .resubmitAdjustCh <- & intervalAdjust {inc : false }
1281
- }
1282
- return false , circuitCapacityReached
1190
+ return circuitCapacityReached
1283
1191
}
1284
1192
1285
1193
func (w * worker ) checkCurrentTxNumWithCCC (expected int ) {
@@ -1312,9 +1220,6 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
1312
1220
w .circuitCapacityChecker .Reset ()
1313
1221
log .Trace ("Worker reset ccc" , "id" , w .circuitCapacityChecker .ID )
1314
1222
1315
- if parent .Time () >= uint64 (timestamp ) {
1316
- timestamp = int64 (parent .Time () + 1 )
1317
- }
1318
1223
num := parent .Number ()
1319
1224
header := & types.Header {
1320
1225
ParentHash : parent .Hash (),
@@ -1359,7 +1264,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
1359
1264
}
1360
1265
}
1361
1266
// Could potentially happen if starting to mine in an odd state.
1362
- err := w .makeCurrent (parent , header )
1267
+ err := w .makeCurrent (parent , header , tstart )
1363
1268
if err != nil {
1364
1269
log .Error ("Failed to create mining context" , "err" , err )
1365
1270
return
@@ -1394,11 +1299,6 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
1394
1299
commitUncles (w .localUncles )
1395
1300
commitUncles (w .remoteUncles )
1396
1301
1397
- // Create an empty block based on temporary copied state for
1398
- // sealing in advance without waiting block execution finished.
1399
- if ! noempty && atomic .LoadUint32 (& w .noempty ) == 0 {
1400
- w .commit (uncles , nil , false , tstart )
1401
- }
1402
1302
// fetch l1Txs
1403
1303
var l1Messages []types.L1MessageTx
1404
1304
if w .chainConfig .Scroll .ShouldIncludeL1Messages () {
@@ -1423,60 +1323,52 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
1423
1323
localTxs [account ] = txs
1424
1324
}
1425
1325
}
1426
- var skipCommit , circuitCapacityReached bool
1326
+
1427
1327
if w .chainConfig .Scroll .ShouldIncludeL1Messages () && len (l1Messages ) > 0 {
1428
1328
log .Trace ("Processing L1 messages for inclusion" , "count" , len (l1Messages ))
1429
1329
txs , err := types .NewL1MessagesByQueueIndex (l1Messages )
1430
1330
if err != nil {
1431
1331
log .Error ("Failed to create L1 message set" , "l1Messages" , l1Messages , "err" , err )
1432
1332
return
1433
1333
}
1434
- skipCommit , circuitCapacityReached = w .commitTransactions (txs , w .coinbase , interrupt )
1435
- if skipCommit {
1334
+
1335
+ if seal := w .commitTransactions (txs , w .coinbase , interrupt ); seal {
1336
+ w .commit (uncles , w .fullTaskHook , true )
1436
1337
return
1437
1338
}
1438
1339
}
1439
1340
if w .prioritizedTx != nil && w .current .header .Number .Uint64 () > w .prioritizedTx .blockNumber {
1440
1341
w .prioritizedTx = nil
1441
1342
}
1442
- if ! circuitCapacityReached && w .prioritizedTx != nil && w .current .header .Number .Uint64 () == w .prioritizedTx .blockNumber {
1343
+ if w .prioritizedTx != nil && w .current .header .Number .Uint64 () == w .prioritizedTx .blockNumber {
1443
1344
tx := w .prioritizedTx .tx
1444
1345
from , _ := types .Sender (w .current .signer , tx ) // error already checked before
1445
1346
txList := map [common.Address ]types.Transactions {from : []* types.Transaction {tx }}
1446
1347
txs := types .NewTransactionsByPriceAndNonce (w .current .signer , txList , header .BaseFee )
1447
- skipCommit , circuitCapacityReached = w .commitTransactions (txs , w .coinbase , interrupt )
1448
- if skipCommit {
1348
+ if seal : = w .commitTransactions (txs , w .coinbase , interrupt ); seal {
1349
+ w . commit ( uncles , w . fullTaskHook , true )
1449
1350
return
1450
1351
}
1451
1352
}
1452
- if len (localTxs ) > 0 && ! circuitCapacityReached {
1353
+ if len (localTxs ) > 0 {
1453
1354
txs := types .NewTransactionsByPriceAndNonce (w .current .signer , localTxs , header .BaseFee )
1454
- skipCommit , circuitCapacityReached = w .commitTransactions (txs , w .coinbase , interrupt )
1455
- if skipCommit {
1355
+ if seal : = w .commitTransactions (txs , w .coinbase , interrupt ); seal {
1356
+ w . commit ( uncles , w . fullTaskHook , true )
1456
1357
return
1457
1358
}
1458
1359
}
1459
- if len (remoteTxs ) > 0 && ! circuitCapacityReached {
1360
+ if len (remoteTxs ) > 0 {
1460
1361
txs := types .NewTransactionsByPriceAndNonce (w .current .signer , remoteTxs , header .BaseFee )
1461
- // don't need to get `circuitCapacityReached` here because we don't have further `commitTransactions`
1462
- // after this one, and if we assign it won't take effect (`ineffassign`)
1463
- skipCommit , _ = w .commitTransactions (txs , w .coinbase , interrupt )
1464
- if skipCommit {
1362
+ if seal := w .commitTransactions (txs , w .coinbase , interrupt ); seal {
1363
+ w .commit (uncles , w .fullTaskHook , true )
1465
1364
return
1466
1365
}
1467
1366
}
1468
-
1469
- // do not produce empty blocks
1470
- if w .current .tcount == 0 {
1471
- return
1472
- }
1473
-
1474
- w .commit (uncles , w .fullTaskHook , true , tstart )
1475
1367
}
1476
1368
1477
1369
// commit runs any post-transaction state modifications, assembles the final block
1478
1370
// and commits new work if consensus engine is running.
1479
- func (w * worker ) commit (uncles []* types.Header , interval func (), update bool , start time. Time ) error {
1371
+ func (w * worker ) commit (uncles []* types.Header , interval func (), update bool ) error {
1480
1372
defer func (t0 time.Time ) {
1481
1373
l2CommitTimer .Update (time .Since (t0 ))
1482
1374
}(time .Now ())
@@ -1536,7 +1428,7 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
1536
1428
log .Info ("Commit new mining work" , "number" , block .Number (), "sealhash" , w .engine .SealHash (block .Header ()),
1537
1429
"uncles" , len (uncles ), "txs" , w .current .tcount ,
1538
1430
"gas" , block .GasUsed (), "fees" , totalFees (block , receipts ),
1539
- "elapsed" , common .PrettyDuration (time .Since (start )))
1431
+ "elapsed" , common .PrettyDuration (time .Since (w . current . start )))
1540
1432
1541
1433
case <- w .exitCh :
1542
1434
log .Info ("Worker has exited" )
@@ -1545,6 +1437,7 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
1545
1437
if update {
1546
1438
w .updateSnapshot ()
1547
1439
}
1440
+ w .current = nil
1548
1441
return nil
1549
1442
}
1550
1443
0 commit comments