@ -38,6 +38,13 @@ type Agent interface {
GetHashRate ( ) int64
}
const MINING_LOG_AT_DEPTH = 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
// all of the current state information
type environment struct {
@ -54,6 +61,7 @@ type environment struct {
lowGasTransactors * set . Set
ownedAccounts * set . Set
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
@ -209,6 +217,18 @@ out:
events . Unsubscribe ( )
}
func newLocalMinedBlock ( blockNumber uint64 , prevMinedBlocks * UInt64RingBuffer ) ( minedBlocks * UInt64RingBuffer ) {
if prevMinedBlocks == nil {
minedBlocks = & UInt64RingBuffer { next : 0 , ints : make ( [ ] uint64 , MINING_LOG_AT_DEPTH ) }
} else {
minedBlocks = prevMinedBlocks
}
minedBlocks . ints [ minedBlocks . next ] = blockNumber
minedBlocks . next = ( minedBlocks . next + 1 ) % len ( minedBlocks . ints )
return minedBlocks
}
func ( self * worker ) wait ( ) {
for {
for block := range self . recv {
@ -232,6 +252,8 @@ func (self *worker) wait() {
glog . V ( logger . Info ) . Infof ( "🔨 Mined %sblock #%v (%x)" , stale , block . Number ( ) , block . Hash ( ) . Bytes ( ) [ : 4 ] )
self . current . localMinedBlocks = newLocalMinedBlock ( block . Number ( ) . Uint64 ( ) , self . current . localMinedBlocks )
jsonlogger . LogJson ( & logger . EthMinerNewBlock {
BlockHash : block . Hash ( ) . Hex ( ) ,
BlockNumber : block . Number ( ) ,
@ -286,6 +308,9 @@ func (self *worker) makeCurrent() {
current . ignoredTransactors = set . New ( )
current . lowGasTransactors = set . New ( )
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 ) )
@ -304,6 +329,38 @@ func (w *worker) setGasPrice(p *big.Int) {
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 - MINING_LOG_AT_DEPTH
if self . isBlockLocallyMined ( inspectBlockNum ) {
glog . V ( logger . Info ) . Infof ( "🔨 🔗 Mined %d blocks back: block #%v" , MINING_LOG_AT_DEPTH , inspectBlockNum )
}
}
}
}
func ( self * worker ) commitNewWork ( ) {
self . mu . Lock ( )
defer self . mu . Unlock ( )
@ -312,6 +369,7 @@ func (self *worker) commitNewWork() {
self . currentMu . Lock ( )
defer self . currentMu . Unlock ( )
previous := self . current
self . makeCurrent ( )
current := self . current
@ -347,6 +405,7 @@ func (self *worker) commitNewWork() {
// We only care about logging if we're actually mining
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 ) )
self . logLocalMinedBlocks ( previous )
}
for _ , hash := range badUncles {