mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
Merge remote-tracking branch 'upstream/develop' into bzz
This commit is contained in:
commit
a83e02416a
8 changed files with 138 additions and 100 deletions
|
|
@ -259,8 +259,8 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
|
func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
|
||||||
current, max := js.ethereum.Downloader().Stats()
|
pending, cached := js.ethereum.Downloader().Stats()
|
||||||
v, _ := call.Otto.ToValue(fmt.Sprintf("%d/%d", current, max))
|
v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached})
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -49,7 +50,8 @@ type dumbterm struct{ r *bufio.Reader }
|
||||||
|
|
||||||
func (r dumbterm) Prompt(p string) (string, error) {
|
func (r dumbterm) Prompt(p string) (string, error) {
|
||||||
fmt.Print(p)
|
fmt.Print(p)
|
||||||
return r.r.ReadString('\n')
|
line, err := r.r.ReadString('\n')
|
||||||
|
return strings.TrimSuffix(line, "\n"), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r dumbterm) PasswordPrompt(p string) (string, error) {
|
func (r dumbterm) PasswordPrompt(p string) (string, error) {
|
||||||
|
|
@ -190,30 +192,52 @@ func (self *jsre) exec(filename string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *jsre) interactive() {
|
func (self *jsre) interactive() {
|
||||||
for {
|
// Read input lines.
|
||||||
input, err := self.Prompt(self.ps1)
|
prompt := make(chan string)
|
||||||
if err != nil {
|
inputln := make(chan string)
|
||||||
break
|
go func() {
|
||||||
}
|
defer close(inputln)
|
||||||
if input == "" {
|
for {
|
||||||
continue
|
line, err := self.Prompt(<-prompt)
|
||||||
}
|
if err != nil {
|
||||||
str += input + "\n"
|
return
|
||||||
self.setIndent()
|
}
|
||||||
if indentCount <= 0 {
|
inputln <- line
|
||||||
if input == "exit" {
|
}
|
||||||
break
|
}()
|
||||||
|
// Wait for Ctrl-C, too.
|
||||||
|
sig := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sig, os.Interrupt)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if self.atexit != nil {
|
||||||
|
self.atexit()
|
||||||
|
}
|
||||||
|
self.re.Stop(false)
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
prompt <- self.ps1
|
||||||
|
select {
|
||||||
|
case <-sig:
|
||||||
|
fmt.Println("caught interrupt, exiting")
|
||||||
|
return
|
||||||
|
case input, ok := <-inputln:
|
||||||
|
if !ok || indentCount <= 0 && input == "exit" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if input == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
str += input + "\n"
|
||||||
|
self.setIndent()
|
||||||
|
if indentCount <= 0 {
|
||||||
|
hist := str[:len(str)-1]
|
||||||
|
self.AppendHistory(hist)
|
||||||
|
self.parseInput(str)
|
||||||
|
str = ""
|
||||||
}
|
}
|
||||||
hist := str[:len(str)-1]
|
|
||||||
self.AppendHistory(hist)
|
|
||||||
self.parseInput(str)
|
|
||||||
str = ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.atexit != nil {
|
|
||||||
self.atexit()
|
|
||||||
}
|
|
||||||
self.re.Stop(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *jsre) withHistory(op func(*os.File)) {
|
func (self *jsre) withHistory(op func(*os.File)) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ type Database interface {
|
||||||
Put(key []byte, value []byte)
|
Put(key []byte, value []byte)
|
||||||
Get(key []byte) ([]byte, error)
|
Get(key []byte) ([]byte, error)
|
||||||
Delete(key []byte) error
|
Delete(key []byte) error
|
||||||
LastKnownTD() []byte
|
|
||||||
Close()
|
Close()
|
||||||
Flush() error
|
Flush() error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -285,9 +285,8 @@ func (self *BlockProcessor) GetBlockReceipts(bhash common.Hash) (receipts types.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validates the current block. Returns an error if the block was invalid,
|
// See YP section 4.3.4. "Block Header Validity"
|
||||||
// an uncle or anything that isn't on the current block chain.
|
// Validates a block. Returns an error if the block is invalid.
|
||||||
// Validation validates easy over difficult (dagger takes longer time = difficult)
|
|
||||||
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error {
|
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error {
|
||||||
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
|
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
|
||||||
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
|
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
|
||||||
|
|
@ -298,16 +297,14 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b
|
||||||
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// block.gasLimit - parent.gasLimit <= parent.gasLimit / GasLimitBoundDivisor
|
|
||||||
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
|
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
|
||||||
a.Abs(a)
|
a.Abs(a)
|
||||||
b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor)
|
b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor)
|
||||||
if !(a.Cmp(b) <= 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) {
|
if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) {
|
||||||
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow future blocks up to 10 seconds
|
if int64(block.Time) > time.Now().Unix() {
|
||||||
if int64(block.Time) > time.Now().Unix()+4 {
|
|
||||||
return BlockFutureErr
|
return BlockFutureErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ func CalcGasLimit(parent *types.Block) *big.Int {
|
||||||
|
|
||||||
gl := new(big.Int).Sub(parent.GasLimit(), decay)
|
gl := new(big.Int).Sub(parent.GasLimit(), decay)
|
||||||
gl = gl.Add(gl, contrib)
|
gl = gl.Add(gl, contrib)
|
||||||
|
gl = gl.Add(gl, big.NewInt(1))
|
||||||
gl = common.BigMax(gl, params.MinGasLimit)
|
gl = common.BigMax(gl, params.MinGasLimit)
|
||||||
|
|
||||||
if gl.Cmp(params.GenesisGasLimit) < 0 {
|
if gl.Cmp(params.GenesisGasLimit) < 0 {
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,22 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *ProtocolManager) removePeer(id string) {
|
func (pm *ProtocolManager) removePeer(id string) {
|
||||||
// Unregister the peer from the downloader
|
// Short circuit if the peer was already removed
|
||||||
pm.downloader.UnregisterPeer(id)
|
peer := pm.peers.Peer(id)
|
||||||
|
if peer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
glog.V(logger.Debug).Infoln("Removing peer", id)
|
||||||
|
|
||||||
// Remove the peer from the Ethereum peer set too
|
// Unregister the peer from the downloader and Ethereum peer set
|
||||||
glog.V(logger.Detail).Infoln("Removing peer", id)
|
pm.downloader.UnregisterPeer(id)
|
||||||
if err := pm.peers.Unregister(id); err != nil {
|
if err := pm.peers.Unregister(id); err != nil {
|
||||||
glog.V(logger.Error).Infoln("Removal failed:", err)
|
glog.V(logger.Error).Infoln("Removal failed:", err)
|
||||||
}
|
}
|
||||||
|
// Hard disconnect at the networking layer
|
||||||
|
if peer != nil {
|
||||||
|
peer.Peer.Disconnect(p2p.DiscUselessPeer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *ProtocolManager) Start() {
|
func (pm *ProtocolManager) Start() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package ethdb
|
package ethdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/compression/rle"
|
"github.com/ethereum/go-ethereum/compression/rle"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
|
@ -15,14 +13,10 @@ import (
|
||||||
var OpenFileLimit = 64
|
var OpenFileLimit = 64
|
||||||
|
|
||||||
type LDBDatabase struct {
|
type LDBDatabase struct {
|
||||||
|
// filename for reporting
|
||||||
fn string
|
fn string
|
||||||
|
// LevelDB instance
|
||||||
mu sync.Mutex
|
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
|
|
||||||
queue map[string][]byte
|
|
||||||
|
|
||||||
quit chan struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
|
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
|
||||||
|
|
@ -40,85 +34,39 @@ func NewLDBDatabase(file string) (*LDBDatabase, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
database := &LDBDatabase{
|
database := &LDBDatabase{
|
||||||
fn: file,
|
fn: file,
|
||||||
db: db,
|
db: db,
|
||||||
quit: make(chan struct{}),
|
|
||||||
}
|
}
|
||||||
database.makeQueue()
|
|
||||||
|
|
||||||
return database, nil
|
return database, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LDBDatabase) makeQueue() {
|
|
||||||
self.queue = make(map[string][]byte)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put puts the given key / value to the queue
|
// Put puts the given key / value to the queue
|
||||||
func (self *LDBDatabase) Put(key []byte, value []byte) {
|
func (self *LDBDatabase) Put(key []byte, value []byte) {
|
||||||
self.mu.Lock()
|
self.db.Put(key, rle.Compress(value), nil)
|
||||||
defer self.mu.Unlock()
|
|
||||||
|
|
||||||
self.queue[string(key)] = value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the given key if it's present.
|
// Get returns the given key if it's present.
|
||||||
func (self *LDBDatabase) Get(key []byte) ([]byte, error) {
|
func (self *LDBDatabase) Get(key []byte) ([]byte, error) {
|
||||||
self.mu.Lock()
|
|
||||||
defer self.mu.Unlock()
|
|
||||||
|
|
||||||
// Check queue first
|
|
||||||
if dat, ok := self.queue[string(key)]; ok {
|
|
||||||
return dat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dat, err := self.db.Get(key, nil)
|
dat, err := self.db.Get(key, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return rle.Decompress(dat)
|
return rle.Decompress(dat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes the key from the queue and database
|
// Delete deletes the key from the queue and database
|
||||||
func (self *LDBDatabase) Delete(key []byte) error {
|
func (self *LDBDatabase) Delete(key []byte) error {
|
||||||
self.mu.Lock()
|
|
||||||
defer self.mu.Unlock()
|
|
||||||
|
|
||||||
// make sure it's not in the queue
|
|
||||||
delete(self.queue, string(key))
|
|
||||||
|
|
||||||
return self.db.Delete(key, nil)
|
return self.db.Delete(key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LDBDatabase) LastKnownTD() []byte {
|
|
||||||
data, _ := self.Get([]byte("LTD"))
|
|
||||||
|
|
||||||
if len(data) == 0 {
|
|
||||||
data = []byte{0x0}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LDBDatabase) NewIterator() iterator.Iterator {
|
func (self *LDBDatabase) NewIterator() iterator.Iterator {
|
||||||
return self.db.NewIterator(nil, nil)
|
return self.db.NewIterator(nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush flushes out the queue to leveldb
|
// Flush flushes out the queue to leveldb
|
||||||
func (self *LDBDatabase) Flush() error {
|
func (self *LDBDatabase) Flush() error {
|
||||||
self.mu.Lock()
|
return nil
|
||||||
defer self.mu.Unlock()
|
|
||||||
|
|
||||||
batch := new(leveldb.Batch)
|
|
||||||
|
|
||||||
for key, value := range self.queue {
|
|
||||||
batch.Put([]byte(key), rle.Compress(value))
|
|
||||||
}
|
|
||||||
self.makeQueue() // reset the queue
|
|
||||||
|
|
||||||
glog.V(logger.Detail).Infoln("Flush database: ", self.fn)
|
|
||||||
|
|
||||||
return self.db.Write(batch, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LDBDatabase) Write(batch *leveldb.Batch) error {
|
func (self *LDBDatabase) Write(batch *leveldb.Batch) error {
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,13 @@ type Agent interface {
|
||||||
GetHashRate() int64
|
GetHashRate() int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const miningLogAtDepth = 5
|
||||||
|
|
||||||
|
type uint64RingBuffer struct {
|
||||||
|
ints []uint64 //array of all integers in buffer
|
||||||
|
next int //where is the next insertion? assert 0 <= next < len(ints)
|
||||||
|
}
|
||||||
|
|
||||||
// environment is the workers current environment and holds
|
// environment is the workers current environment and holds
|
||||||
// all of the current state information
|
// all of the current state information
|
||||||
type environment struct {
|
type environment struct {
|
||||||
|
|
@ -54,6 +61,7 @@ type environment struct {
|
||||||
lowGasTransactors *set.Set
|
lowGasTransactors *set.Set
|
||||||
ownedAccounts *set.Set
|
ownedAccounts *set.Set
|
||||||
lowGasTxs types.Transactions
|
lowGasTxs types.Transactions
|
||||||
|
localMinedBlocks *uint64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// env returns a new environment for the current cycle
|
// env returns a new environment for the current cycle
|
||||||
|
|
@ -209,6 +217,18 @@ out:
|
||||||
events.Unsubscribe()
|
events.Unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (minedBlocks *uint64RingBuffer) {
|
||||||
|
if prevMinedBlocks == nil {
|
||||||
|
minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth+1)}
|
||||||
|
} else {
|
||||||
|
minedBlocks = prevMinedBlocks
|
||||||
|
}
|
||||||
|
|
||||||
|
minedBlocks.ints[minedBlocks.next] = blockNumber
|
||||||
|
minedBlocks.next = (minedBlocks.next + 1) % len(minedBlocks.ints)
|
||||||
|
return minedBlocks
|
||||||
|
}
|
||||||
|
|
||||||
func (self *worker) wait() {
|
func (self *worker) wait() {
|
||||||
for {
|
for {
|
||||||
for block := range self.recv {
|
for block := range self.recv {
|
||||||
|
|
@ -224,13 +244,16 @@ func (self *worker) wait() {
|
||||||
}
|
}
|
||||||
self.mux.Post(core.NewMinedBlockEvent{block})
|
self.mux.Post(core.NewMinedBlockEvent{block})
|
||||||
|
|
||||||
var stale string
|
var stale, confirm string
|
||||||
canonBlock := self.chain.GetBlockByNumber(block.NumberU64())
|
canonBlock := self.chain.GetBlockByNumber(block.NumberU64())
|
||||||
if canonBlock != nil && canonBlock.Hash() != block.Hash() {
|
if canonBlock != nil && canonBlock.Hash() != block.Hash() {
|
||||||
stale = "stale-"
|
stale = "stale "
|
||||||
|
} else {
|
||||||
|
confirm = "Wait 5 blocks for confirmation"
|
||||||
|
self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(logger.Info).Infof("🔨 Mined %sblock #%v (%x)", stale, block.Number(), block.Hash().Bytes()[:4])
|
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
|
||||||
|
|
||||||
jsonlogger.LogJson(&logger.EthMinerNewBlock{
|
jsonlogger.LogJson(&logger.EthMinerNewBlock{
|
||||||
BlockHash: block.Hash().Hex(),
|
BlockHash: block.Hash().Hex(),
|
||||||
|
|
@ -265,8 +288,10 @@ func (self *worker) push() {
|
||||||
|
|
||||||
func (self *worker) makeCurrent() {
|
func (self *worker) makeCurrent() {
|
||||||
block := self.chain.NewBlock(self.coinbase)
|
block := self.chain.NewBlock(self.coinbase)
|
||||||
if block.Time() == self.chain.CurrentBlock().Time() {
|
parent := self.chain.GetBlock(block.ParentHash())
|
||||||
block.Header().Time++
|
|
||||||
|
if block.Time() <= parent.Time() {
|
||||||
|
block.Header().Time = parent.Header().Time + 1
|
||||||
}
|
}
|
||||||
block.Header().Extra = self.extra
|
block.Header().Extra = self.extra
|
||||||
|
|
||||||
|
|
@ -286,8 +311,10 @@ func (self *worker) makeCurrent() {
|
||||||
current.ignoredTransactors = set.New()
|
current.ignoredTransactors = set.New()
|
||||||
current.lowGasTransactors = set.New()
|
current.lowGasTransactors = set.New()
|
||||||
current.ownedAccounts = accountAddressesSet(accounts)
|
current.ownedAccounts = accountAddressesSet(accounts)
|
||||||
|
if self.current != nil {
|
||||||
|
current.localMinedBlocks = self.current.localMinedBlocks
|
||||||
|
}
|
||||||
|
|
||||||
parent := self.chain.GetBlock(current.block.ParentHash())
|
|
||||||
current.coinbase.SetGasPool(core.CalcGasLimit(parent))
|
current.coinbase.SetGasPool(core.CalcGasLimit(parent))
|
||||||
|
|
||||||
self.current = current
|
self.current = current
|
||||||
|
|
@ -304,6 +331,38 @@ func (w *worker) setGasPrice(p *big.Int) {
|
||||||
w.mux.Post(core.GasPriceChanged{w.gasPrice})
|
w.mux.Post(core.GasPriceChanged{w.gasPrice})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *worker) isBlockLocallyMined(deepBlockNum uint64) bool {
|
||||||
|
//Did this instance mine a block at {deepBlockNum} ?
|
||||||
|
var isLocal = false
|
||||||
|
for idx, blockNum := range self.current.localMinedBlocks.ints {
|
||||||
|
if deepBlockNum == blockNum {
|
||||||
|
isLocal = true
|
||||||
|
self.current.localMinedBlocks.ints[idx] = 0 //prevent showing duplicate logs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Short-circuit on false, because the previous and following tests must both be true
|
||||||
|
if !isLocal {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//Does the block at {deepBlockNum} send earnings to my coinbase?
|
||||||
|
var block = self.chain.GetBlockByNumber(deepBlockNum)
|
||||||
|
return block.Header().Coinbase == self.coinbase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *worker) logLocalMinedBlocks(previous *environment) {
|
||||||
|
if previous != nil && self.current.localMinedBlocks != nil {
|
||||||
|
nextBlockNum := self.current.block.Number().Uint64()
|
||||||
|
for checkBlockNum := previous.block.Number().Uint64(); checkBlockNum < nextBlockNum; checkBlockNum++ {
|
||||||
|
inspectBlockNum := checkBlockNum - miningLogAtDepth
|
||||||
|
if self.isBlockLocallyMined(inspectBlockNum) {
|
||||||
|
glog.V(logger.Info).Infof("🔨 🔗 Mined %d blocks back: block #%v", miningLogAtDepth, inspectBlockNum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *worker) commitNewWork() {
|
func (self *worker) commitNewWork() {
|
||||||
self.mu.Lock()
|
self.mu.Lock()
|
||||||
defer self.mu.Unlock()
|
defer self.mu.Unlock()
|
||||||
|
|
@ -312,6 +371,7 @@ func (self *worker) commitNewWork() {
|
||||||
self.currentMu.Lock()
|
self.currentMu.Lock()
|
||||||
defer self.currentMu.Unlock()
|
defer self.currentMu.Unlock()
|
||||||
|
|
||||||
|
previous := self.current
|
||||||
self.makeCurrent()
|
self.makeCurrent()
|
||||||
current := self.current
|
current := self.current
|
||||||
|
|
||||||
|
|
@ -347,6 +407,7 @@ func (self *worker) commitNewWork() {
|
||||||
// We only care about logging if we're actually mining
|
// We only care about logging if we're actually mining
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if atomic.LoadInt32(&self.mining) == 1 {
|
||||||
glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles\n", current.block.Number(), current.tcount, len(uncles))
|
glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles\n", current.block.Number(), current.tcount, len(uncles))
|
||||||
|
self.logLocalMinedBlocks(previous)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hash := range badUncles {
|
for _, hash := range badUncles {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue