mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
AddBlockHashes call uses lazy rlp decoding so it cannot be async since message is discarded by protocol
This commit is contained in:
parent
a7ac361c8f
commit
9ab3530df3
1 changed files with 102 additions and 102 deletions
|
|
@ -322,118 +322,118 @@ func (self *BlockPool) AddBlockHashes(next func() ([]byte, bool), peerId string)
|
||||||
// peer is still the best
|
// peer is still the best
|
||||||
poolLogger.Debugf("adding hashes for best peer %s", peerId)
|
poolLogger.Debugf("adding hashes for best peer %s", peerId)
|
||||||
|
|
||||||
self.wg.Add(1)
|
// self.wg.Add(1)
|
||||||
self.procWg.Add(1)
|
// self.procWg.Add(1)
|
||||||
|
|
||||||
go func() {
|
// go func() {
|
||||||
var size, n int
|
var size, n int
|
||||||
var hash []byte
|
var hash []byte
|
||||||
var ok bool = true
|
var ok bool = true
|
||||||
var section, child, parent *section
|
var section, child, parent *section
|
||||||
var entry *poolEntry
|
var entry *poolEntry
|
||||||
var nodes []*poolNode
|
var nodes []*poolNode
|
||||||
|
|
||||||
LOOP:
|
LOOP:
|
||||||
// iterate using next (rlp stream lazy decoder) feeding hashesC
|
// iterate using next (rlp stream lazy decoder) feeding hashesC
|
||||||
for hash, ok = next(); ok; hash, ok = next() {
|
for hash, ok = next(); ok; hash, ok = next() {
|
||||||
n++
|
n++
|
||||||
select {
|
select {
|
||||||
case <-self.quit:
|
case <-self.quit:
|
||||||
break LOOP
|
break LOOP
|
||||||
case <-peer.quitC:
|
case <-peer.quitC:
|
||||||
// if the peer is demoted, no more hashes taken
|
// if the peer is demoted, no more hashes taken
|
||||||
break LOOP
|
break LOOP
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if self.hasBlock(hash) {
|
if self.hasBlock(hash) {
|
||||||
// check if known block connecting the downloaded chain to our blockchain
|
// check if known block connecting the downloaded chain to our blockchain
|
||||||
poolLogger.Debugf("[%s] known block", name(hash))
|
poolLogger.Debugf("[%s] known block", name(hash))
|
||||||
// mark child as absolute pool root with parent known to blockchain
|
// mark child as absolute pool root with parent known to blockchain
|
||||||
if section != nil {
|
if section != nil {
|
||||||
self.connectToBlockChain(section)
|
self.connectToBlockChain(section)
|
||||||
} else {
|
} else {
|
||||||
if child != nil {
|
if child != nil {
|
||||||
self.connectToBlockChain(child)
|
self.connectToBlockChain(child)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break LOOP
|
|
||||||
}
|
}
|
||||||
// look up node in pool
|
break LOOP
|
||||||
entry = self.get(hash)
|
}
|
||||||
if entry != nil {
|
// look up node in pool
|
||||||
poolLogger.Debugf("[%s] found block", name(hash))
|
entry = self.get(hash)
|
||||||
// reached a known chain in the pool
|
if entry != nil {
|
||||||
if entry.node == entry.section.bottom && n == 1 {
|
poolLogger.Debugf("[%s] found block", name(hash))
|
||||||
// the first block hash received is an orphan in the pool, so rejoice and continue
|
// reached a known chain in the pool
|
||||||
poolLogger.Debugf("[%s] first hash is orphan block, keep building", name(hash))
|
if entry.node == entry.section.bottom && n == 1 {
|
||||||
child = entry.section
|
// the first block hash received is an orphan in the pool, so rejoice and continue
|
||||||
continue LOOP
|
poolLogger.Debugf("[%s] first hash is orphan block, keep building", name(hash))
|
||||||
}
|
child = entry.section
|
||||||
poolLogger.Debugf("[%s] reached blockpool chain", name(hash))
|
continue LOOP
|
||||||
parent = entry.section
|
|
||||||
break LOOP
|
|
||||||
}
|
}
|
||||||
// if node for block hash does not exist, create it and index in the pool
|
poolLogger.Debugf("[%s] reached blockpool chain", name(hash))
|
||||||
poolLogger.Debugf("[%s] create node %v", name(hash), size)
|
parent = entry.section
|
||||||
node := &poolNode{
|
break LOOP
|
||||||
hash: hash,
|
|
||||||
peer: peerId,
|
|
||||||
}
|
|
||||||
if size == 0 {
|
|
||||||
section = newSection()
|
|
||||||
}
|
|
||||||
nodes = append(nodes, node)
|
|
||||||
size++
|
|
||||||
} //for
|
|
||||||
|
|
||||||
self.chainLock.Lock()
|
|
||||||
poolLogger.Debugf("lock chain lock")
|
|
||||||
|
|
||||||
poolLogger.Debugf("read %v hashes added by %s", n, peerId)
|
|
||||||
|
|
||||||
if parent != nil && entry != nil && entry.node != parent.top {
|
|
||||||
poolLogger.Debugf("[%s] fork section", sectionName(parent))
|
|
||||||
parent.controlC <- false
|
|
||||||
waiter := make(chan bool)
|
|
||||||
parent.forkC <- waiter
|
|
||||||
chain := parent.nodes
|
|
||||||
parent.nodes = chain[entry.index:]
|
|
||||||
parent.top = parent.nodes[0]
|
|
||||||
orphan := newSection()
|
|
||||||
self.link(orphan, parent.child)
|
|
||||||
self.processSection(orphan, chain[0:entry.index])
|
|
||||||
orphan.controlC <- false
|
|
||||||
close(waiter)
|
|
||||||
}
|
}
|
||||||
|
// if node for block hash does not exist, create it and index in the pool
|
||||||
if size > 0 {
|
poolLogger.Debugf("[%s] create node %v", name(hash), size)
|
||||||
self.processSection(section, nodes)
|
node := &poolNode{
|
||||||
poolLogger.Debugf("[%s]->[%s](%v)->[%s] new chain section", sectionName(parent), sectionName(section), size, sectionName(child))
|
hash: hash,
|
||||||
self.link(parent, section)
|
peer: peerId,
|
||||||
self.link(section, child)
|
|
||||||
} else {
|
|
||||||
poolLogger.Debugf("[%s]->[%s] connecting known sections", sectionName(parent), sectionName(child))
|
|
||||||
self.link(parent, child)
|
|
||||||
}
|
}
|
||||||
|
if size == 0 {
|
||||||
self.chainLock.Unlock()
|
section = newSection()
|
||||||
poolLogger.Debugf("[%s] unlock chain lock", sectionName(section))
|
|
||||||
|
|
||||||
if parent != nil {
|
|
||||||
poolLogger.Debugf("[%s] activating parent chain [%s]...", name(parent.top.hash), sectionName(parent))
|
|
||||||
self.activateChain(parent, peer)
|
|
||||||
poolLogger.Debugf("[%s] activated parent chain [%s]. done", name(parent.top.hash), sectionName(parent))
|
|
||||||
}
|
}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
size++
|
||||||
|
} //for
|
||||||
|
|
||||||
if section != nil {
|
self.chainLock.Lock()
|
||||||
poolLogger.Debugf("[%s] activate new section process", sectionName(section))
|
poolLogger.Debugf("lock chain lock")
|
||||||
peer.addSection(section.top.hash, section)
|
|
||||||
section.controlC <- true
|
|
||||||
}
|
|
||||||
self.procWg.Done()
|
|
||||||
self.wg.Done()
|
|
||||||
|
|
||||||
}()
|
poolLogger.Debugf("read %v hashes added by %s", n, peerId)
|
||||||
|
|
||||||
|
if parent != nil && entry != nil && entry.node != parent.top {
|
||||||
|
poolLogger.Debugf("[%s] fork section", sectionName(parent))
|
||||||
|
parent.controlC <- false
|
||||||
|
waiter := make(chan bool)
|
||||||
|
parent.forkC <- waiter
|
||||||
|
chain := parent.nodes
|
||||||
|
parent.nodes = chain[entry.index:]
|
||||||
|
parent.top = parent.nodes[0]
|
||||||
|
orphan := newSection()
|
||||||
|
self.link(orphan, parent.child)
|
||||||
|
self.processSection(orphan, chain[0:entry.index])
|
||||||
|
orphan.controlC <- false
|
||||||
|
close(waiter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if size > 0 {
|
||||||
|
self.processSection(section, nodes)
|
||||||
|
poolLogger.Debugf("[%s]->[%s](%v)->[%s] new chain section", sectionName(parent), sectionName(section), size, sectionName(child))
|
||||||
|
self.link(parent, section)
|
||||||
|
self.link(section, child)
|
||||||
|
} else {
|
||||||
|
poolLogger.Debugf("[%s]->[%s] connecting known sections", sectionName(parent), sectionName(child))
|
||||||
|
self.link(parent, child)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.chainLock.Unlock()
|
||||||
|
poolLogger.Debugf("[%s] unlock chain lock", sectionName(section))
|
||||||
|
|
||||||
|
if parent != nil {
|
||||||
|
poolLogger.Debugf("[%s] activating parent chain [%s]...", name(parent.top.hash), sectionName(parent))
|
||||||
|
self.activateChain(parent, peer)
|
||||||
|
poolLogger.Debugf("[%s] activated parent chain [%s]. done", name(parent.top.hash), sectionName(parent))
|
||||||
|
}
|
||||||
|
|
||||||
|
if section != nil {
|
||||||
|
poolLogger.Debugf("[%s] activate new section process", sectionName(section))
|
||||||
|
peer.addSection(section.top.hash, section)
|
||||||
|
section.controlC <- true
|
||||||
|
}
|
||||||
|
// self.procWg.Done()
|
||||||
|
// self.wg.Done()
|
||||||
|
|
||||||
|
// }()
|
||||||
}
|
}
|
||||||
|
|
||||||
func name(hash []byte) (name string) {
|
func name(hash []byte) (name string) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue