mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
Merge d53486746f into 288700c4d8
This commit is contained in:
commit
75f416099a
7 changed files with 243 additions and 10 deletions
|
|
@ -108,6 +108,9 @@ func init() {
|
||||||
utils.MiningEnabledFlag,
|
utils.MiningEnabledFlag,
|
||||||
utils.AutoDAGFlag,
|
utils.AutoDAGFlag,
|
||||||
utils.TargetGasLimitFlag,
|
utils.TargetGasLimitFlag,
|
||||||
|
utils.StrategyZerodiffEnabledFlag,
|
||||||
|
utils.StrategyZerodiffInstantTxsFlag,
|
||||||
|
utils.StrategyZerodiffMinEtherFlag,
|
||||||
utils.NATFlag,
|
utils.NATFlag,
|
||||||
utils.NoDiscoverFlag,
|
utils.NoDiscoverFlag,
|
||||||
utils.DiscoveryV5Flag,
|
utils.DiscoveryV5Flag,
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,14 @@ var AppHelpFlagGroups = []flagGroup{
|
||||||
utils.ExtraDataFlag,
|
utils.ExtraDataFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "MINER STRATEGY",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
utils.StrategyZerodiffEnabledFlag,
|
||||||
|
utils.StrategyZerodiffInstantTxsFlag,
|
||||||
|
utils.StrategyZerodiffMinEtherFlag,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "GAS PRICE ORACLE",
|
Name: "GAS PRICE ORACLE",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/les"
|
"github.com/ethereum/go-ethereum/les"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||||
|
|
@ -202,6 +203,19 @@ var (
|
||||||
Name: "extradata",
|
Name: "extradata",
|
||||||
Usage: "Block extra data set by the miner (default = client version)",
|
Usage: "Block extra data set by the miner (default = client version)",
|
||||||
}
|
}
|
||||||
|
StrategyZerodiffEnabledFlag = cli.BoolFlag{
|
||||||
|
Name: "miner.zerodiff",
|
||||||
|
Usage: "Enables the base zero-diff miner strategy (private networks)",
|
||||||
|
}
|
||||||
|
StrategyZerodiffInstantTxsFlag = cli.BoolFlag{
|
||||||
|
Name: "miner.zerodiff.instanttxs",
|
||||||
|
Usage: "Ignores zero-diff delays if block contains transactions (private networks)",
|
||||||
|
}
|
||||||
|
StrategyZerodiffMinEtherFlag = cli.IntFlag{
|
||||||
|
Name: "miner.zerodiff.minether",
|
||||||
|
Usage: "Ignores zero-diff delays if miner balance is below threshold (private networks)",
|
||||||
|
Value: 0,
|
||||||
|
}
|
||||||
// Account settings
|
// Account settings
|
||||||
UnlockedAccountFlag = cli.StringFlag{
|
UnlockedAccountFlag = cli.StringFlag{
|
||||||
Name: "unlock",
|
Name: "unlock",
|
||||||
|
|
@ -636,6 +650,24 @@ func MakeMinerExtra(extra []byte, ctx *cli.Context) []byte {
|
||||||
return extra
|
return extra
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeMinerStrategies assembles any miner strategies from the set command line
|
||||||
|
// flags.
|
||||||
|
func MakeMinerStrategies(ctx *cli.Context) []*miner.Strategy {
|
||||||
|
var strategies []*miner.Strategy
|
||||||
|
|
||||||
|
// If zero-diff mining is requested, assemble it
|
||||||
|
var (
|
||||||
|
zerodiffBaseline = ctx.GlobalBool(StrategyZerodiffEnabledFlag.Name)
|
||||||
|
zerodiffInstanttxs = ctx.GlobalBool(StrategyZerodiffInstantTxsFlag.Name)
|
||||||
|
zerodiffThreshold = ctx.GlobalInt(StrategyZerodiffMinEtherFlag.Name)
|
||||||
|
)
|
||||||
|
if zerodiffBaseline || zerodiffInstanttxs || zerodiffThreshold > 0 {
|
||||||
|
threshold := new(big.Int).Mul(big.NewInt(int64(zerodiffThreshold)), common.Ether)
|
||||||
|
strategies = append(strategies, miner.NewZeroDiffStrategy(zerodiffInstanttxs, threshold))
|
||||||
|
}
|
||||||
|
return strategies
|
||||||
|
}
|
||||||
|
|
||||||
// MakePasswordList reads password lines from the file specified by --password.
|
// MakePasswordList reads password lines from the file specified by --password.
|
||||||
func MakePasswordList(ctx *cli.Context) []string {
|
func MakePasswordList(ctx *cli.Context) []string {
|
||||||
path := ctx.GlobalString(PasswordFileFlag.Name)
|
path := ctx.GlobalString(PasswordFileFlag.Name)
|
||||||
|
|
@ -742,6 +774,7 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
|
||||||
DatabaseHandles: MakeDatabaseHandles(),
|
DatabaseHandles: MakeDatabaseHandles(),
|
||||||
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
|
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
|
||||||
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
|
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
|
||||||
|
MinerStrategies: MakeMinerStrategies(ctx),
|
||||||
ExtraData: MakeMinerExtra(extra, ctx),
|
ExtraData: MakeMinerExtra(extra, ctx),
|
||||||
DocRoot: ctx.GlobalString(DocRootFlag.Name),
|
DocRoot: ctx.GlobalString(DocRootFlag.Name),
|
||||||
GasPrice: GlobalBig(ctx, GasPriceFlag.Name),
|
GasPrice: GlobalBig(ctx, GasPriceFlag.Name),
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,11 @@ type Config struct {
|
||||||
PowShared bool
|
PowShared bool
|
||||||
ExtraData []byte
|
ExtraData []byte
|
||||||
|
|
||||||
Etherbase common.Address
|
Etherbase common.Address
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int
|
||||||
MinerThreads int
|
MinerThreads int
|
||||||
SolcPath string
|
MinerStrategies []*miner.Strategy
|
||||||
|
SolcPath string
|
||||||
|
|
||||||
GpoMinGasPrice *big.Int
|
GpoMinGasPrice *big.Int
|
||||||
GpoMaxGasPrice *big.Int
|
GpoMaxGasPrice *big.Int
|
||||||
|
|
@ -233,7 +234,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, maxPeers, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil {
|
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, maxPeers, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.pow)
|
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.pow, config.MinerStrategies)
|
||||||
eth.miner.SetGasPrice(config.GasPrice)
|
eth.miner.SetGasPrice(config.GasPrice)
|
||||||
eth.miner.SetExtra(config.ExtraData)
|
eth.miner.SetExtra(config.ExtraData)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,12 @@ type Miner struct {
|
||||||
shouldStart int32 // should start indicates whether we should start after sync
|
shouldStart int32 // should start indicates whether we should start after sync
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, pow pow.PoW, strategies []*Strategy) *Miner {
|
||||||
miner := &Miner{
|
miner := &Miner{
|
||||||
eth: eth,
|
eth: eth,
|
||||||
mux: mux,
|
mux: mux,
|
||||||
pow: pow,
|
pow: pow,
|
||||||
worker: newWorker(config, common.Address{}, eth, mux),
|
worker: newWorker(config, common.Address{}, eth, mux, strategies),
|
||||||
canStart: 1,
|
canStart: 1,
|
||||||
}
|
}
|
||||||
go miner.update()
|
go miner.update()
|
||||||
|
|
|
||||||
157
miner/strategy.go
Normal file
157
miner/strategy.go
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright 2016 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
)
|
||||||
|
|
||||||
|
// zerodiffBlocktime block time for the zero-diff miner to target. Note, this
|
||||||
|
// needs to be in sync with the difficulty adjustment algorithm so chaning this
|
||||||
|
// or making it configurable doesn't make sense.
|
||||||
|
const zerodiffBlocktime = 15 * time.Second
|
||||||
|
|
||||||
|
// Strategy is a collection of optional callback methods that miner strategies
|
||||||
|
// may implement to influence the behavior of the miner.
|
||||||
|
type Strategy struct {
|
||||||
|
Name string // Name of the strategy for logging purposes
|
||||||
|
|
||||||
|
// OnNewWork is invoked when a new block is starting to be mined by the miner.
|
||||||
|
OnNewWork func(emux *event.TypeMux, chain *core.BlockChain, block *types.Block) error
|
||||||
|
|
||||||
|
// OnMinedBlock is invoked when a new block is mined by the miner.
|
||||||
|
OnMinedBlock func(emux *event.TypeMux, chain *core.BlockChain, pool *core.TxPool, block *types.Block) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewZeroDiffStrategy creates a mining strategy that aims to push the difficulty
|
||||||
|
// of the blocks down to zero. It tries to achive this by delaying found blocks
|
||||||
|
// to always be above the configured block time limit, pushing the difficulty
|
||||||
|
// down a bit after every block. Similarly if it notices the difficulty going up,
|
||||||
|
// it aborts mining altogether.
|
||||||
|
//
|
||||||
|
// The strategy has a few nice properties that is orthogonal both to multiple
|
||||||
|
// zero-diff miners as well as other plain miners:
|
||||||
|
//
|
||||||
|
// * The zero-diff miner may be ran with arbitrarilly many threads: if a block
|
||||||
|
// is found faster than the target block time, it will be delayed anyway, so
|
||||||
|
// the mining threads will go idle. If on the other hand the difficulty is
|
||||||
|
// pushed up by a rouge miner and abandoned, the multiple threads will allow
|
||||||
|
// pulling the difficulty down faster until it reaches sub-target times.
|
||||||
|
// * The zero-diff miner can play along nicely with non zero-diff miners, since
|
||||||
|
// it will either delay its block to above-target times, or outright discard
|
||||||
|
// its own block if another is found, thereby ensuring it only ever reduces
|
||||||
|
// the difficulty, never increases.
|
||||||
|
// * The zero-diff miner can also play along nicely with other zero-diff miners
|
||||||
|
// by simulating block times at random between [target, 1.1*target], allowing
|
||||||
|
// multiple zero-diff miners to co-exist and share blocks, without racing each
|
||||||
|
// other for blocks and leading to a high uncle rate.
|
||||||
|
//
|
||||||
|
// There are two short-circuits built in that can cause the zero-diff miner to
|
||||||
|
// temporarilly turn off and mine at full capacity:
|
||||||
|
//
|
||||||
|
// * If instant-transactions are requested, then blocks containing transactions
|
||||||
|
// will not be delayed at all; furthermore empty blocks will be fast-tracked
|
||||||
|
// too if the transaction pool contains pending transactions ready to be added
|
||||||
|
// to the next block.
|
||||||
|
// * If a minimum balance threshold is set for the miner, no delays will come
|
||||||
|
// into effect until that minimum threshold is reached.
|
||||||
|
//
|
||||||
|
// Note, this strategy is only meaningful in trusted private networks where the
|
||||||
|
// goal of mining is not to secure the network, rather to provide a stable but
|
||||||
|
// resource-light testbed.
|
||||||
|
func NewZeroDiffStrategy(instantTxs bool, minBalance *big.Int) *Strategy {
|
||||||
|
return &Strategy{
|
||||||
|
Name: "zero-diff",
|
||||||
|
|
||||||
|
OnNewWork: func(emux *event.TypeMux, chain *core.BlockChain, block *types.Block) error {
|
||||||
|
// If the difficulty is increasing, give a change for others to waste resources
|
||||||
|
if parent := chain.GetBlock(block.ParentHash(), block.NumberU64()-1); parent.Difficulty().Cmp(block.Difficulty()) < 0 {
|
||||||
|
// Before bailing out, do check if balance threshold needs to be reached
|
||||||
|
if minBalance != nil {
|
||||||
|
if state, _ := chain.State(); state.GetBalance(block.Coinbase()).Cmp(minBalance) < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Someone seems to be mining, listen for events though to avoid hangs if the other leaves
|
||||||
|
head := emux.Subscribe(core.ChainHeadEvent{})
|
||||||
|
defer head.Unsubscribe()
|
||||||
|
|
||||||
|
if chain.CurrentHeader().Hash() != block.ParentHash() {
|
||||||
|
return errors.New("stale work") // Another block arrived already, drop this
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-time.After(zerodiffBlocktime):
|
||||||
|
return nil // Ok, nobody else seems to be mining, fire up the CPU
|
||||||
|
case <-head.Chan():
|
||||||
|
return errors.New("concurrent miner") // Meh, someone's mining, let them burn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
|
||||||
|
OnMinedBlock: func(emux *event.TypeMux, chain *core.BlockChain, pool *core.TxPool, block *types.Block) error {
|
||||||
|
// A new block was mined, calculate the required delay
|
||||||
|
elapsed := time.Since(time.Unix(block.Time().Int64(), 0))
|
||||||
|
delay := float64(zerodiffBlocktime)*(1.0+rand.Float64()/10.0) - float64(elapsed)
|
||||||
|
|
||||||
|
// If the delay is negative, block times are way over the target already, release
|
||||||
|
if delay <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// If instant transactions are enabled and the block contains something, release
|
||||||
|
if instantTxs && len(block.Transactions()) > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// If minimum balance requirements are set but not met, release
|
||||||
|
if minBalance != nil {
|
||||||
|
if state, _ := chain.State(); state.GetBalance(block.Coinbase()).Cmp(minBalance) < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise monitor head and transaction events
|
||||||
|
head := emux.Subscribe(core.ChainHeadEvent{})
|
||||||
|
defer head.Unsubscribe()
|
||||||
|
|
||||||
|
txs := emux.Subscribe(core.TxPreEvent{})
|
||||||
|
defer txs.Unsubscribe()
|
||||||
|
|
||||||
|
// Double check for events that happened before subscriptions
|
||||||
|
if chain.CurrentHeader().Hash() != block.ParentHash() {
|
||||||
|
return errors.New("stale block") // Another block arrived already, drop this
|
||||||
|
}
|
||||||
|
if pend, _ := pool.Stats(); pend > 0 {
|
||||||
|
return nil // Transaction pending in the pool, release this and start processing them
|
||||||
|
}
|
||||||
|
// Wait for some event to occur that releases or bins the block
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Duration(delay)):
|
||||||
|
return nil // Timeout for difficulty reduction reached, release
|
||||||
|
case <-head.Chan():
|
||||||
|
return errors.New("concurrent block") // Alternate block arrived, drop this
|
||||||
|
case <-txs.Chan():
|
||||||
|
return nil // Transaction arrived, include it as fast as possible
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -114,7 +114,8 @@ type worker struct {
|
||||||
txQueueMu sync.Mutex
|
txQueueMu sync.Mutex
|
||||||
txQueue map[common.Hash]*types.Transaction
|
txQueue map[common.Hash]*types.Transaction
|
||||||
|
|
||||||
unconfirmed *unconfirmedBlocks // set of locally mined blocks pending canonicalness confirmations
|
unconfirmed *unconfirmedBlocks // Set of locally mined blocks pending confirmation
|
||||||
|
strategies []*Strategy // Miner strategies currently ran by the miner
|
||||||
|
|
||||||
// atomic status counters
|
// atomic status counters
|
||||||
mining int32
|
mining int32
|
||||||
|
|
@ -123,7 +124,7 @@ type worker struct {
|
||||||
fullValidation bool
|
fullValidation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWorker(config *params.ChainConfig, coinbase common.Address, eth Backend, mux *event.TypeMux) *worker {
|
func newWorker(config *params.ChainConfig, coinbase common.Address, eth Backend, mux *event.TypeMux, strategies []*Strategy) *worker {
|
||||||
worker := &worker{
|
worker := &worker{
|
||||||
config: config,
|
config: config,
|
||||||
eth: eth,
|
eth: eth,
|
||||||
|
|
@ -138,6 +139,7 @@ func newWorker(config *params.ChainConfig, coinbase common.Address, eth Backend,
|
||||||
txQueue: make(map[common.Hash]*types.Transaction),
|
txQueue: make(map[common.Hash]*types.Transaction),
|
||||||
agents: make(map[Agent]struct{}),
|
agents: make(map[Agent]struct{}),
|
||||||
unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), 5),
|
unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), 5),
|
||||||
|
strategies: strategies,
|
||||||
fullValidation: false,
|
fullValidation: false,
|
||||||
}
|
}
|
||||||
worker.events = worker.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{})
|
worker.events = worker.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{})
|
||||||
|
|
@ -275,6 +277,22 @@ func (self *worker) wait() {
|
||||||
block := result.Block
|
block := result.Block
|
||||||
work := result.Work
|
work := result.Work
|
||||||
|
|
||||||
|
// Run any miner strategies interested in block mine results and ensure none denies this block
|
||||||
|
denied := false
|
||||||
|
for _, strat := range self.strategies {
|
||||||
|
if strat.OnMinedBlock != nil {
|
||||||
|
glog.V(logger.Debug).Infof("Passing mined block #%d [%x…] to strategy %s", block.Number(), block.Hash().Bytes()[:4], strat.Name)
|
||||||
|
if err := strat.OnMinedBlock(self.mux, self.chain, self.eth.TxPool(), block); err != nil {
|
||||||
|
glog.V(logger.Debug).Infof("Mined block #%d [%x…] denied by strategy %s: %v", block.Number(), block.Hash().Bytes()[:4], strat.Name, err)
|
||||||
|
denied = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
glog.V(logger.Debug).Infof("Mined block #%d [%x…] accepted by strategy %s", block.Number(), block.Hash().Bytes()[:4], strat.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if denied {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if self.fullValidation {
|
if self.fullValidation {
|
||||||
if _, err := self.chain.InsertChain(types.Blocks{block}); err != nil {
|
if _, err := self.chain.InsertChain(types.Blocks{block}); err != nil {
|
||||||
log.Error(fmt.Sprint("mining err", err))
|
log.Error(fmt.Sprint("mining err", err))
|
||||||
|
|
@ -349,9 +367,22 @@ func (self *worker) wait() {
|
||||||
|
|
||||||
// push sends a new work task to currently live miner agents.
|
// push sends a new work task to currently live miner agents.
|
||||||
func (self *worker) push(work *Work) {
|
func (self *worker) push(work *Work) {
|
||||||
|
// If there are no agents mining, bail out
|
||||||
if atomic.LoadInt32(&self.mining) != 1 {
|
if atomic.LoadInt32(&self.mining) != 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Iterate over all miner strategies and ensure none denies this block
|
||||||
|
for _, strat := range self.strategies {
|
||||||
|
if strat.OnMinedBlock != nil {
|
||||||
|
glog.V(logger.Debug).Infof("Passing mining request #%d [%x…] to strategy %s", work.Block.Number(), work.Block.Hash().Bytes()[:4], strat.Name)
|
||||||
|
if err := strat.OnNewWork(self.mux, self.chain, work.Block); err != nil {
|
||||||
|
glog.V(logger.Debug).Infof("Mining request #%d [%x…] denied by strategy %s: %v", work.Block.Number(), work.Block.Hash().Bytes()[:4], strat.Name, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
glog.V(logger.Debug).Infof("Mining request #%d [%x…] accepted by strategy %s", work.Block.Number(), work.Block.Hash().Bytes()[:4], strat.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Block accepted for mining, proceed
|
||||||
for agent := range self.agents {
|
for agent := range self.agents {
|
||||||
atomic.AddInt32(&self.atWork, 1)
|
atomic.AddInt32(&self.atWork, 1)
|
||||||
if ch := agent.Work(); ch != nil {
|
if ch := agent.Work(); ch != nil {
|
||||||
|
|
@ -515,7 +546,7 @@ func (self *worker) commitNewWork() {
|
||||||
log.Info(fmt.Sprintf("commit new work on block %v with %d txs & %d uncles. Took %v\n", work.Block.Number(), work.tcount, len(uncles), time.Since(tstart)))
|
log.Info(fmt.Sprintf("commit new work on block %v with %d txs & %d uncles. Took %v\n", work.Block.Number(), work.tcount, len(uncles), time.Since(tstart)))
|
||||||
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
|
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
|
||||||
}
|
}
|
||||||
self.push(work)
|
go self.push(work)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
|
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue