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")
|
errRecentlySigned = errors.New("recently signed")
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignerFn is a signer callback function to request a header to be signed by a
|
// SignerFn hashes and signs the data to be signed by a backing account.
|
||||||
// backing account.
|
type SignerFn func(signer accounts.Account, mimeType string, message []byte) ([]byte, error)
|
||||||
type SignerFn func(accounts.Account, string, []byte) ([]byte, error)
|
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
||||||
|
@ -305,6 +305,28 @@ func (w *worker) close() {
|
|||||||
close(w.exitCh)
|
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.
|
// newWorkLoop is a standalone goroutine to submit new mining work upon received events.
|
||||||
func (w *worker) newWorkLoop(recommit time.Duration) {
|
func (w *worker) newWorkLoop(recommit time.Duration) {
|
||||||
var (
|
var (
|
||||||
@ -327,27 +349,6 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||||||
timer.Reset(recommit)
|
timer.Reset(recommit)
|
||||||
atomic.StoreInt32(&w.newTxs, 0)
|
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 cleans the stale pending tasks.
|
||||||
clearPending := func(number uint64) {
|
clearPending := func(number uint64) {
|
||||||
w.pendingMu.Lock()
|
w.pendingMu.Lock()
|
||||||
@ -400,11 +401,12 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||||||
// Adjust resubmit interval by feedback.
|
// Adjust resubmit interval by feedback.
|
||||||
if adjust.inc {
|
if adjust.inc {
|
||||||
before := recommit
|
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)
|
log.Trace("Increase miner recommit interval", "from", before, "to", recommit)
|
||||||
} else {
|
} else {
|
||||||
before := recommit
|
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)
|
log.Trace("Decrease miner recommit interval", "from", before, "to", recommit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +555,7 @@ func (w *worker) taskLoop() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
w.pendingMu.Lock()
|
w.pendingMu.Lock()
|
||||||
w.pendingTasks[w.engine.SealHash(task.block.Header())] = task
|
w.pendingTasks[sealHash] = task
|
||||||
w.pendingMu.Unlock()
|
w.pendingMu.Unlock()
|
||||||
|
|
||||||
if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil {
|
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.
|
// and commits new work if consensus engine is running.
|
||||||
func (w *worker) commit(uncles []*types.Header, interval func(), update bool, start time.Time) error {
|
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.
|
// Deep copy receipts here to avoid interaction between different tasks.
|
||||||
receipts := make([]*types.Receipt, len(w.current.receipts))
|
receipts := copyReceipts(w.current.receipts)
|
||||||
for i, l := range w.current.receipts {
|
|
||||||
receipts[i] = new(types.Receipt)
|
|
||||||
*receipts[i] = *l
|
|
||||||
}
|
|
||||||
s := w.current.state.Copy()
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -991,15 +989,10 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
|
|||||||
select {
|
select {
|
||||||
case w.taskCh <- &task{receipts: receipts, state: s, block: block, createdAt: time.Now()}:
|
case w.taskCh <- &task{receipts: receipts, state: s, block: block, createdAt: time.Now()}:
|
||||||
w.unconfirmed.Shift(block.NumberU64() - 1)
|
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()),
|
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:
|
case <-w.exitCh:
|
||||||
log.Info("Worker has exited")
|
log.Info("Worker has exited")
|
||||||
@ -1011,6 +1004,16 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
|
|||||||
return nil
|
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.
|
// postSideBlock fires a side chain event, only use it for testing.
|
||||||
func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
||||||
select {
|
select {
|
||||||
@ -1018,3 +1021,12 @@ func (w *worker) postSideBlock(event core.ChainSideEvent) {
|
|||||||
case <-w.exitCh:
|
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
Block a user