miner: refactor helper functions in worker.go (#21044)
This reduces complexity of some lengthy functions in worker.go, making the code easier to read.
This commit is contained in:
parent
28c5a8a54b
commit
37564ceda6
|
@ -137,9 +137,8 @@ var (
|
|||
errRecentlySigned = errors.New("recently signed")
|
||||
)
|
||||
|
||||
// SignerFn is a signer callback function to request a header to be signed by a
|
||||
// backing account.
|
||||
type SignerFn func(accounts.Account, string, []byte) ([]byte, error)
|
||||
// SignerFn hashes and signs the data to be signed by a backing account.
|
||||
type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error)
|
||||
|
||||
// ecrecover extracts the Ethereum account address from a signed header.
|
||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
||||
|
|
|
@ -305,6 +305,28 @@ func (w *worker) close() {
|
|||
close(w.exitCh)
|
||||
}
|
||||
|
||||
// recalcRecommit recalculates the resubmitting interval upon feedback.
|
||||
func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) time.Duration {
|
||||
var (
|
||||
prevF = float64(prev.Nanoseconds())
|
||||
next float64
|
||||
)
|
||||
if inc {
|
||||
next = prevF*(1-intervalAdjustRatio) + intervalAdjustRatio*(target+intervalAdjustBias)
|
||||
max := float64(maxRecommitInterval.Nanoseconds())
|
||||
if next > max {
|
||||
next = max
|
||||
}
|
||||
} else {
|
||||
next = prevF*(1-intervalAdjustRatio) + intervalAdjustRatio*(target-intervalAdjustBias)
|
||||
min := float64(minRecommit.Nanoseconds())
|
||||
if next < min {
|
||||
next = min
|
||||
}
|
||||
}
|
||||
return time.Duration(int64(next))
|
||||
}
|
||||
|
||||
// newWorkLoop is a standalone goroutine to submit new mining work upon received events.
|
||||
func (w *worker) newWorkLoop(recommit time.Duration) {
|
||||
var (
|
||||
|
@ -327,27 +349,6 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||
timer.Reset(recommit)
|
||||
atomic.StoreInt32(&w.newTxs, 0)
|
||||
}
|
||||
// recalcRecommit recalculates the resubmitting interval upon feedback.
|
||||
recalcRecommit := func(target float64, inc bool) {
|
||||
var (
|
||||
prev = float64(recommit.Nanoseconds())
|
||||
next float64
|
||||
)
|
||||
if inc {
|
||||
next = prev*(1-intervalAdjustRatio) + intervalAdjustRatio*(target+intervalAdjustBias)
|
||||
// Recap if interval is larger than the maximum time interval
|
||||
if next > float64(maxRecommitInterval.Nanoseconds()) {
|
||||
next = float64(maxRecommitInterval.Nanoseconds())
|
||||
}
|
||||
} else {
|
||||
next = prev*(1-intervalAdjustRatio) + intervalAdjustRatio*(target-intervalAdjustBias)
|
||||
// Recap if interval is less than the user specified minimum
|
||||
if next < float64(minRecommit.Nanoseconds()) {
|
||||
next = float64(minRecommit.Nanoseconds())
|
||||
}
|
||||
}
|
||||
recommit = time.Duration(int64(next))
|
||||
}
|
||||
// clearPending cleans the stale pending tasks.
|
||||
clearPending := func(number uint64) {
|
||||
w.pendingMu.Lock()
|
||||
|
@ -400,11 +401,12 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||
// Adjust resubmit interval by feedback.
|
||||
if adjust.inc {
|
||||
before := recommit
|
||||
recalcRecommit(float64(recommit.Nanoseconds())/adjust.ratio, true)
|
||||
target := float64(recommit.Nanoseconds()) / adjust.ratio
|
||||
recommit = recalcRecommit(minRecommit, recommit, target, true)
|
||||
log.Trace("Increase miner recommit interval", "from", before, "to", recommit)
|
||||
} else {
|
||||
before := recommit
|
||||
recalcRecommit(float64(minRecommit.Nanoseconds()), false)
|
||||
recommit = recalcRecommit(minRecommit, recommit, float64(minRecommit.Nanoseconds()), false)
|
||||
log.Trace("Decrease miner recommit interval", "from", before, "to", recommit)
|
||||
}
|
||||
|
||||
|
@ -553,7 +555,7 @@ func (w *worker) taskLoop() {
|
|||
continue
|
||||
}
|
||||
w.pendingMu.Lock()
|
||||
w.pendingTasks[w.engine.SealHash(task.block.Header())] = task
|
||||
w.pendingTasks[sealHash] = task
|
||||
w.pendingMu.Unlock()
|
||||
|
||||
if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil {
|
||||
|
@ -974,13 +976,9 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
|||
// and commits new work if consensus engine is running.
|
||||
func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error {
|
||||
// Deep copy receipts here to avoid interaction between different tasks.
|
||||
receipts := make([]*types.Receipt, len(w.current.receipts))
|
||||
for i, l := range w.current.receipts {
|
||||
receipts[i] = new(types.Receipt)
|
||||
*receipts[i] = *l
|
||||
}
|
||||
receipts := copyReceipts(w.current.receipts)
|
||||
s := w.current.state.Copy()
|
||||
block, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts)
|
||||
block, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, receipts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -991,15 +989,10 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
|
|||
select {
|
||||
case w.taskCh <- &task{receipts: receipts, state: s, block: block, createdAt: time.Now()}:
|
||||
w.unconfirmed.Shift(block.NumberU64() - 1)
|
||||
|
||||
feesWei := new(big.Int)
|
||||
for i, tx := range block.Transactions() {
|
||||
feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), tx.GasPrice()))
|
||||
}
|
||||
feesEth := new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether)))
|
||||
|
||||
log.Info("Commit new mining work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()),
|
||||
"uncles", len(uncles), "txs", w.current.tcount, "gas", block.GasUsed(), "fees", feesEth, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
"uncles", len(uncles), "txs", w.current.tcount,
|
||||
"gas", block.GasUsed(), "fees", totalFees(block, receipts),
|
||||
"elapsed", common.PrettyDuration(time.Since(start)))
|
||||
|
||||
case <-w.exitCh:
|
||||
log.Info("Worker has exited")
|
||||
|
@ -1011,6 +1004,16 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
|
|||
return nil
|
||||
}
|
||||
|
||||
// copyReceipts makes a deep copy of the given receipts.
|
||||
func copyReceipts(receipts []*types.Receipt) []*types.Receipt {
|
||||
result := make([]*types.Receipt, len(receipts))
|
||||
for i, l := range receipts {
|
||||
cpy := *l
|
||||
result[i] = &cpy
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// postSideBlock fires a side chain event, only use it for testing.
|
||||
func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
||||
select {
|
||||
|
@ -1018,3 +1021,12 @@ func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
|||
case <-w.exitCh:
|
||||
}
|
||||
}
|
||||
|
||||
// totalFees computes total consumed fees in ETH. Block transactions and receipts have to have the same order.
|
||||
func totalFees(block *types.Block, receipts []*types.Receipt) *big.Float {
|
||||
feesWei := new(big.Int)
|
||||
for i, tx := range block.Transactions() {
|
||||
feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), tx.GasPrice()))
|
||||
}
|
||||
return new(big.Float).Quo(new(big.Float).SetInt(feesWei), new(big.Float).SetInt(big.NewInt(params.Ether)))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue