@ -496,6 +496,9 @@ func (self *ChainManager) procFutureBlocks() {
}
func ( self * ChainManager ) InsertChain ( chain types . Blocks ) error {
self . mu . Lock ( )
defer self . mu . Unlock ( )
// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
var (
queue = make ( [ ] interface { } , len ( chain ) )
@ -543,55 +546,51 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
block . Td = new ( big . Int ) . Set ( CalculateTD ( block , self . GetBlock ( block . ParentHash ( ) ) ) )
self . mu . Lock ( )
{
cblock := self . currentBlock
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
// not in the canonical chain.
self . write ( block )
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
if block . Td . Cmp ( self . td ) > 0 {
//if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 {
if block . Number ( ) . Cmp ( cblock . Number ( ) ) <= 0 {
chash := cblock . Hash ( )
hash := block . Hash ( )
if glog . V ( logger . Info ) {
glog . Infof ( "Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n" , block . Header ( ) . Number , hash [ : 4 ] , block . Td , cblock . Header ( ) . Number , chash [ : 4 ] , self . td )
}
// during split we merge two different chains and create the new canonical chain
self . merge ( self . getBlockByNumber ( block . NumberU64 ( ) ) , block )
queue [ i ] = ChainSplitEvent { block , logs }
queueEvent . splitCount ++
cblock := self . currentBlock
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are
// not in the canonical chain.
self . write ( block )
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
if block . Td . Cmp ( self . td ) > 0 {
//if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 {
if block . Number ( ) . Cmp ( cblock . Number ( ) ) <= 0 {
chash := cblock . Hash ( )
hash := block . Hash ( )
if glog . V ( logger . Info ) {
glog . Infof ( "Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n" , block . Header ( ) . Number , hash [ : 4 ] , block . Td , cblock . Header ( ) . Number , chash [ : 4 ] , self . td )
}
// during split we merge two different chains and create the new canonical chain
self . merge ( self . getBlockByNumber ( block . NumberU64 ( ) ) , block )
self . setTotalDifficulty ( block . Td )
self . insert ( block )
queue [ i ] = ChainSplitEvent { block , logs }
queueEvent . splitCount ++
}
jsonlogger . LogJson ( & logger . EthChainNewHead {
BlockHash : block . Hash ( ) . Hex ( ) ,
BlockNumber : block . Number ( ) ,
ChainHeadHash : cblock . Hash ( ) . Hex ( ) ,
BlockPrevHash : block . ParentHash ( ) . Hex ( ) ,
} )
self . setTotalDifficulty ( block . Td )
self . insert ( block )
self . setTransState ( state . New ( block . Root ( ) , self . stateDb ) )
self . txState . SetState ( state . New ( block . Root ( ) , self . stateDb ) )
jsonlogger . LogJson ( & logger . EthChainNewHead {
BlockHash : block . Hash ( ) . Hex ( ) ,
BlockNumber : block . Number ( ) ,
ChainHeadHash : cblock . Hash ( ) . Hex ( ) ,
BlockPrevHash : block . ParentHash ( ) . Hex ( ) ,
} )
queue [ i ] = ChainEvent { block , logs }
queueEvent . canonicalCount ++
self . setTransState ( state . New ( block . Root ( ) , self . stateDb ) )
self . txState . SetState ( state . New ( block . Root ( ) , self . stateDb ) )
if glog . V ( logger . Debug ) {
glog . Infof ( "inserted block #%d (%d TXs %d UNCs) (%x...)\n" , block . Number ( ) , len ( block . Transactions ( ) ) , len ( block . Uncles ( ) ) , block . Hash ( ) . Bytes ( ) [ 0 : 4 ] )
}
} else {
queue [ i ] = ChainSideEvent { block , logs }
queueEvent . sideCount ++
queue [ i ] = ChainEvent { block , logs }
queueEvent . canonicalCount ++
if glog . V ( logger . Debug ) {
glog . Infof ( "inserted block #%d (%d TXs %d UNCs) (%x...)\n" , block . Number ( ) , len ( block . Transactions ( ) ) , len ( block . Uncles ( ) ) , block . Hash ( ) . Bytes ( ) [ 0 : 4 ] )
}
} else {
queue [ i ] = ChainSideEvent { block , logs }
queueEvent . sideCount ++
}
self . mu . Unlock ( )
stats . processed ++