@ -18,6 +18,7 @@ type peer struct {
// last known blockchain status
td * big . Int
tdAdvertised bool
currentBlockHash common . Hash
currentBlock * types . Block
parentHash common . Hash
@ -135,21 +136,52 @@ func (self *peer) addError(code int, format string, params ...interface{}) {
}
// caller must hold peer lock
func ( self * peer ) setChainInfo ( td * big . Int , c common . Hash ) {
func ( self * peer ) setChainInfo ( td * big . Int , currentBlockHash common . Hash ) {
self . lock . Lock ( )
defer self . lock . Unlock ( )
if self . currentBlockHash != currentBlockHash {
previousBlockHash := self . currentBlockHash
plog . Debugf ( "addPeer: Update peer <%s> with td %v and current block %s (was %v)" , self . id , td , hex ( currentBlockHash ) , hex ( previousBlockHash ) )
self . td = td
self . currentBlockHash = c
self . currentBlockHash = currentBlockHash
self . currentBlock = nil
self . parentHash = common . Hash { }
self . headSection = nil
}
self . tdAdvertised = true
}
// caller must hold peer lock
func ( self * peer ) setChainInfoFromBlock ( block * types . Block ) {
// use the optional TD to update peer td, this helps second best peer selection
func ( self * peer ) setChainInfoFromBlock ( block * types . Block ) ( td * big . Int , currentBlockHash common . Hash ) {
self . lock . Lock ( )
defer self . lock . Unlock ( )
hash := block . Hash ( )
// this happens when block came in a newblock message but
// also if sent in a blockmsg (for instance, if we requested, only if we
// dont apply on blockrequests the restriction of flood control)
currentBlockHash = self . currentBlockHash
if currentBlockHash == hash && self . currentBlock == nil {
// signal to head section process
plog . DebugDetailf ( "AddBlock: head block %s for peer <%s> (head: %s) received\n" , hex ( hash ) , self . id , hex ( currentBlockHash ) )
select {
case self . currentBlockC <- block :
case <- self . switchC :
}
return self . td , currentBlockHash
} else {
plog . DebugDetailf ( "AddBlock: head block %s for peer <%s> (head: %s) already known" , hex ( hash ) , self . id , hex ( currentBlockHash ) )
return nil , currentBlockHash
}
}
// this will use the TD given by the first peer to update peer td, this helps second best peer selection
// :FIXME: node
func ( self * peer ) setChainInfoFromNode ( n * node ) {
// in case best peer is lost
if block . Td != nil && block . Td . Cmp ( self . td ) > 0 {
plog . DebugDetailf ( "setChainInfoFromBlock: update <%s> - head: %v->%v - TD: %v->%v" , self . id , hex ( self . currentBlockHash ) , hex ( block . Hash ( ) ) , self . td , block . Td )
self . td = block . Td
block := n . block
hash := block . Hash ( )
if n . td != nil && n . td . Cmp ( self . td ) > 0 {
plog . DebugDetailf ( "AddBlock: update peer <%s> - head: %v->%v - TD: %v->%v" , self . id , hex ( self . currentBlockHash ) , hex ( hash ) , self . td , n . td )
self . td = n . td
self . currentBlockHash = block . Hash ( )
self . parentHash = block . ParentHash ( )
self . currentBlock = block
@ -218,17 +250,11 @@ func (self *peers) addPeer(
if found {
// when called on an already connected peer, it means a newBlockMsg is received
// peer head info is updated
p . lock . Lock ( )
if p . currentBlockHash != currentBlockHash {
previousBlockHash = p . currentBlockHash
plog . Debugf ( "addPeer: Update peer <%s> with td %v and current block %s (was %v)" , id , td , hex ( currentBlockHash ) , hex ( previousBlockHash ) )
p . setChainInfo ( td , currentBlockHash )
// FIXME: only count the same block once
self . status . lock . Lock ( )
self . status . values . NewBlocks ++
self . status . lock . Unlock ( )
}
p . lock . Unlock ( )
} else {
p = self . newPeer ( td , currentBlockHash , id , requestBlockHashes , requestBlocks , peerError )
@ -333,8 +359,8 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
close ( oldp . switchC )
}
if newp != nil {
newp . idleC = make ( chan bool )
newp . switchC = make ( chan bool )
// newp.idleC = make(chan bool)
// newp.switchC = make(chan bool)
// if new best peer has no head section yet, create it and run it
// otherwise head section is an element of peer.sections
if newp . headSection == nil {
@ -354,6 +380,9 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
}
} ( )
} else {
newp . idleC = make ( chan bool )
newp . switchC = make ( chan bool )
}
var connected = make ( map [ common . Hash ] * section )
@ -528,10 +557,12 @@ func (self *peer) getBlockHashes() bool {
// main loop for head section process
func ( self * peer ) run ( ) {
self . lock . RLock ( )
self . lock . Lock ( )
self . switchC = make ( chan bool )
self . idleC = make ( chan bool )
switchC := self . switchC
plog . Debugf ( "HeadSection: <%s> section process for head %s started" , self . id , hex ( self . currentBlockHash ) )
self . lock . R Unlock( )
self . lock . Unlock ( )
self . blockHashesRequestTimer = nil