Pārlūkot izejas kodu

Merge branch 'ethersphere-frontier/blockpool' into develop

obscuren 10 gadi atpakaļ
vecāks
revīzija
01ee012197

+ 68 - 44
blockpool/blockpool.go

@@ -132,6 +132,7 @@ type node struct {
 	block   *types.Block
 	hashBy  string
 	blockBy string
+	peers   map[string]bool
 	td      *big.Int
 }
 
@@ -376,13 +377,14 @@ func (self *BlockPool) AddBlockHashes(next func() (common.Hash, bool), peerId st
 	var nodes []*node
 
 	hash, ok = next()
-	bestpeer.lock.Lock()
+	bestpeer.lock.RLock()
 
 	plog.Debugf("AddBlockHashes: peer <%s> starting from [%s] (peer head: %s)", peerId, hex(bestpeer.parentHash), hex(bestpeer.currentBlockHash))
 
 	// first check if we are building the head section of a peer's chain
 	if bestpeer.parentHash == hash {
 		if self.hasBlock(bestpeer.currentBlockHash) {
+			bestpeer.lock.RUnlock()
 			return
 		}
 		/*
@@ -396,6 +398,7 @@ func (self *BlockPool) AddBlockHashes(next func() (common.Hash, bool), peerId st
 		if entry := self.get(bestpeer.currentBlockHash); entry == nil {
 			plog.DebugDetailf("AddBlockHashes: peer <%s> (head: %s) head section starting from [%s] ", peerId, hex(bestpeer.currentBlockHash), hex(bestpeer.parentHash))
 			// if head block is not yet in the pool, create entry and start node list for section
+
 			node := &node{
 				hash:    bestpeer.currentBlockHash,
 				block:   bestpeer.currentBlock,
@@ -421,7 +424,7 @@ func (self *BlockPool) AddBlockHashes(next func() (common.Hash, bool), peerId st
 	}
 	// the switch channel signals peerswitch event
 	switchC := bestpeer.switchC
-	bestpeer.lock.Unlock()
+	bestpeer.lock.RUnlock()
 
 	// iterate over hashes coming from peer (first round we have hash set above)
 LOOP:
@@ -547,8 +550,10 @@ LOOP:
 		In this case no activation should happen
 	*/
 	if parent != nil && !peerswitch {
-		self.activateChain(parent, bestpeer, nil)
+		bestpeer.lock.RLock()
+		self.activateChain(parent, bestpeer, bestpeer.switchC, nil)
 		plog.DebugDetailf("AddBlockHashes: peer <%s> (head: %s): parent section [%s]", peerId, hex(bestpeer.currentBlockHash), sectionhex(parent))
+		bestpeer.lock.RUnlock()
 	}
 
 	/*
@@ -622,53 +627,60 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
 	self.status.lock.Unlock()
 
 	entry := self.get(hash)
+	blockIsCurrentHead := false
+	sender.lock.RLock()
+	currentBlockHash := sender.currentBlockHash
+	currentBlock := sender.currentBlock
+	currentBlockC := sender.currentBlockC
+	switchC := sender.switchC
+	sender.lock.RUnlock()
 
 	// a peer's current head block is appearing the first time
-	if hash == sender.currentBlockHash {
-		if sender.currentBlock == nil {
-			plog.Debugf("AddBlock: add head block %s for peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
+	if hash == currentBlockHash {
+		// 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)
+		blockIsCurrentHead = true
+		if currentBlock == nil {
+			sender.lock.Lock()
 			sender.setChainInfoFromBlock(block)
+			sender.lock.Unlock()
 
 			self.status.lock.Lock()
 			self.status.values.BlockHashes++
 			self.status.values.Blocks++
 			self.status.values.BlocksInPool++
 			self.status.lock.Unlock()
-		} else {
-			plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), peerId, hex(sender.currentBlockHash))
 			// signal to head section process
-			sender.currentBlockC <- block
+			select {
+			case currentBlockC <- block:
+			case <-switchC:
+			}
+		} else {
+			plog.DebugDetailf("AddBlock: head block %s for peer <%s> (head: %s) already known", hex(hash), peerId, hex(currentBlockHash))
 		}
 	} else {
 
-		plog.DebugDetailf("AddBlock: block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
-
-		sender.lock.Lock()
-		// update peer chain info if more recent than what we registered
-		if block.Td != nil && block.Td.Cmp(sender.td) > 0 {
-			sender.td = block.Td
-			sender.currentBlockHash = block.Hash()
-			sender.parentHash = block.ParentHash()
-			sender.currentBlock = block
-			sender.headSection = nil
-		}
-		sender.lock.Unlock()
+		plog.DebugDetailf("AddBlock: block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(currentBlockHash))
 
 		/* @zelig !!!
-		requested 5 hashes from both A & B. A responds sooner then B, process blocks. Close section.
-		delayed B sends you block ... UNREQUESTED. Blocked
-			if entry == nil {
-				plog.DebugDetailf("AddBlock: unrequested block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
-				sender.addError(ErrUnrequestedBlock, "%x", hash)
-
-				self.status.lock.Lock()
-				self.status.badPeers[peerId]++
-				self.status.lock.Unlock()
-				return
-			}
+		   requested 5 hashes from both A & B. A responds sooner then B, process blocks. Close section.
+		   delayed B sends you block ... UNREQUESTED. Blocked
+		     if entry == nil {
+		       plog.DebugDetailf("AddBlock: unrequested block %s received from peer <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
+		       sender.addError(ErrUnrequestedBlock, "%x", hash)
+
+		       self.status.lock.Lock()
+		       self.status.badPeers[peerId]++
+		       self.status.lock.Unlock()
+		       return
+		     }
 		*/
 	}
+
 	if entry == nil {
+		// FIXME: here check the cache find or create node -
+		// put peer as blockBy!
 		return
 	}
 
@@ -676,10 +688,22 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
 	node.lock.Lock()
 	defer node.lock.Unlock()
 
+	// register peer on node as source
+	if node.peers == nil {
+		node.peers = make(map[string]bool)
+	}
+	FoundBlockCurrentHead, found := node.peers[sender.id]
+	if !found || FoundBlockCurrentHead {
+		// if found but not FoundBlockCurrentHead, then no update
+		// necessary (||)
+		node.peers[sender.id] = blockIsCurrentHead
+		// for those that are false, TD will update their head
+		// for those that are true, TD is checked !
+		// this is checked at the time of TD calculation in checkTD
+	}
 	// check if block already received
 	if node.block != nil {
 		plog.DebugDetailf("AddBlock: block %s from peer <%s> (head: %s) already sent by <%s> ", hex(hash), peerId, hex(sender.currentBlockHash), node.blockBy)
-		return
 	}
 
 	// check if block is already inserted in the blockchain
@@ -690,6 +714,8 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
 
 	/*
 		@zelig needs discussing
+		Viktor: pow check can be delayed in a go routine and therefore cache
+		creation is not blocking
 			// validate block for PoW
 			if !self.verifyPoW(block) {
 				plog.Warnf("AddBlock: invalid PoW on block %s from peer  <%s> (head: %s)", hex(hash), peerId, hex(sender.currentBlockHash))
@@ -705,7 +731,6 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
 
 	node.block = block
 	node.blockBy = peerId
-	node.td = block.Td // optional field
 
 	self.status.lock.Lock()
 	self.status.values.Blocks++
@@ -719,11 +744,7 @@ func (self *BlockPool) AddBlock(block *types.Block, peerId string) {
   It activates the section process on incomplete sections with peer.
   It relinks orphaned sections with their parent if root block (and its parent hash) is known.
 */
-func (self *BlockPool) activateChain(sec *section, p *peer, connected map[common.Hash]*section) {
-
-	p.lock.RLock()
-	switchC := p.switchC
-	p.lock.RUnlock()
+func (self *BlockPool) activateChain(sec *section, p *peer, switchC chan bool, connected map[common.Hash]*section) {
 
 	var i int
 
@@ -766,14 +787,17 @@ LOOP:
 // check if block's actual TD (calculated after successful insertChain) is identical to TD advertised for peer's head block.
 func (self *BlockPool) checkTD(nodes ...*node) {
 	for _, n := range nodes {
-		if n.td != nil {
+		// skip check if queued future block
+		if n.td != nil && !n.block.Queued() {
 			plog.DebugDetailf("peer td %v =?= block td %v", n.td, n.block.Td)
+			/* @zelig: Commented out temp untill the rest of the network has been fixed.
 			if n.td.Cmp(n.block.Td) != 0 {
-				//self.peers.peerError(n.blockBy, ErrIncorrectTD, "on block %x", n.hash)
-				//self.status.lock.Lock()
-				//self.status.badPeers[n.blockBy]++
-				//self.status.lock.Unlock()
+				self.peers.peerError(n.blockBy, ErrIncorrectTD, "on block %x", n.hash)
+				self.status.lock.Lock()
+				self.status.badPeers[n.blockBy]++
+				self.status.lock.Unlock()
 			}
+			*/
 		}
 	}
 }

+ 4 - 0
blockpool/blockpool_test.go

@@ -7,6 +7,10 @@ import (
 	"github.com/ethereum/go-ethereum/blockpool/test"
 )
 
+func init() {
+	test.LogInit()
+}
+
 // using the mock framework in blockpool_util_test
 // we test various scenarios here
 

+ 1 - 1
blockpool/blockpool_util_test.go

@@ -87,7 +87,7 @@ func (self *blockPoolTester) insertChain(blocks types.Blocks) error {
 	var ok bool
 	for _, block := range blocks {
 		child = self.hashPool.HashesToIndexes([]common.Hash{block.Hash()})[0]
-		var td int
+		td := child
 		if self.tds != nil {
 			td, ok = self.tds[child]
 		}

+ 43 - 2
blockpool/errors_test.go

@@ -39,6 +39,8 @@ func TestInvalidBlock(t *testing.T) {
 }
 
 func TestVerifyPoW(t *testing.T) {
+	t.Skip() // :FIXME:
+
 	test.LogInit()
 	_, blockPool, blockPoolTester := newTestBlockPool(t)
 	blockPoolTester.blockChain[0] = nil
@@ -84,6 +86,8 @@ func TestVerifyPoW(t *testing.T) {
 }
 
 func TestUnrequestedBlock(t *testing.T) {
+	t.Skip() // :FIXME:
+
 	test.LogInit()
 	_, blockPool, blockPoolTester := newTestBlockPool(t)
 	blockPoolTester.blockChain[0] = nil
@@ -124,8 +128,6 @@ func TestErrInsufficientChainInfo(t *testing.T) {
 }
 
 func TestIncorrectTD(t *testing.T) {
-	t.Skip() // @zelig this one requires fixing for the TD
-
 	test.LogInit()
 	_, blockPool, blockPoolTester := newTestBlockPool(t)
 	blockPoolTester.blockChain[0] = nil
@@ -152,6 +154,45 @@ func TestIncorrectTD(t *testing.T) {
 	}
 }
 
+func TestSkipIncorrectTDonFutureBlocks(t *testing.T) {
+	// t.Skip() // @zelig this one requires fixing for the TD
+
+	test.LogInit()
+	_, blockPool, blockPoolTester := newTestBlockPool(t)
+	blockPoolTester.blockChain[0] = nil
+	blockPoolTester.initRefBlockChain(3)
+
+	blockPool.insertChain = func(blocks types.Blocks) error {
+		err := blockPoolTester.insertChain(blocks)
+		if err == nil {
+			for _, block := range blocks {
+				if block.Td.Cmp(common.Big3) == 0 {
+					block.Td = common.Big3
+					block.SetQueued(true)
+					break
+				}
+			}
+		}
+		return err
+	}
+
+	blockPool.Start()
+
+	peer1 := blockPoolTester.newPeer("peer1", 3, 3)
+	peer1.AddPeer()
+	go peer1.serveBlocks(2, 3)
+	go peer1.serveBlockHashes(3, 2, 1, 0)
+	peer1.serveBlocks(0, 1, 2)
+
+	blockPool.Wait(waitTimeout)
+	blockPool.Stop()
+	blockPoolTester.refBlockChain[3] = []int{}
+	blockPoolTester.checkBlockChain(blockPoolTester.refBlockChain)
+	if len(peer1.peerErrors) > 0 {
+		t.Errorf("expected no error, got %v (1 of %v)", peer1.peerErrors[0], len(peer1.peerErrors))
+	}
+}
+
 func TestPeerSuspension(t *testing.T) {
 	test.LogInit()
 	_, blockPool, blockPoolTester := newTestBlockPool(t)

+ 28 - 26
blockpool/peers.go

@@ -57,7 +57,8 @@ type peer struct {
 // peers is the component keeping a record of peers in a hashmap
 //
 type peers struct {
-	lock sync.RWMutex
+	lock   sync.RWMutex
+	bllock sync.Mutex
 
 	bp        *BlockPool
 	errors    *errs.Errors
@@ -109,15 +110,15 @@ func (self *peers) peerError(id string, code int, format string, params ...inter
 
 // record time of offence in blacklist to implement suspension for PeerSuspensionInterval
 func (self *peers) addToBlacklist(id string) {
-	self.lock.Lock()
-	defer self.lock.Unlock()
+	self.bllock.Lock()
+	defer self.bllock.Unlock()
 	self.blacklist[id] = time.Now()
 }
 
-// suspended checks if peer is still suspended
+// suspended checks if peer is still suspended, caller should hold peers.lock
 func (self *peers) suspended(id string) (s bool) {
-	self.lock.Lock()
-	defer self.lock.Unlock()
+	self.bllock.Lock()
+	defer self.bllock.Unlock()
 	if suspendedAt, ok := self.blacklist[id]; ok {
 		if s = suspendedAt.Add(self.bp.Config.PeerSuspensionInterval).After(time.Now()); !s {
 			// no longer suspended, delete entry
@@ -142,9 +143,8 @@ func (self *peer) setChainInfo(td *big.Int, c common.Hash) {
 	self.headSection = nil
 }
 
+// caller must hold peer lock
 func (self *peer) setChainInfoFromBlock(block *types.Block) {
-	self.lock.Lock()
-	defer self.lock.Unlock()
 	// use the optional TD to update peer td, this helps second best peer selection
 	// in case best peer is lost
 	if block.Td != nil && block.Td.Cmp(self.td) > 0 {
@@ -155,16 +155,12 @@ func (self *peer) setChainInfoFromBlock(block *types.Block) {
 		self.currentBlock = block
 		self.headSection = nil
 	}
-	self.bp.wg.Add(1)
-	go func() {
-		self.currentBlockC <- block
-		self.bp.wg.Done()
-	}()
 }
 
 // distribute block request among known peers
 func (self *peers) requestBlocks(attempts int, hashes []common.Hash) {
 	self.lock.RLock()
+
 	defer self.lock.RUnlock()
 	peerCount := len(self.peers)
 	// on first attempt use the best peer
@@ -210,13 +206,14 @@ func (self *peers) addPeer(
 	peerError func(*errs.Error),
 ) (best bool, suspended bool) {
 
+	self.lock.Lock()
+	defer self.lock.Unlock()
+
 	var previousBlockHash common.Hash
 	if self.suspended(id) {
 		suspended = true
 		return
 	}
-	self.lock.Lock()
-	defer self.lock.Unlock()
 	p, found := self.peers[id]
 	if found {
 		// when called on an already connected peer, it means a newBlockMsg is received
@@ -260,7 +257,7 @@ func (self *peers) addPeer(
 			p.headSectionC <- nil
 			if entry := self.bp.get(previousBlockHash); entry != nil {
 				plog.DebugDetailf("addPeer: <%s> previous head : %v found in pool, activate", id, hex(previousBlockHash))
-				self.bp.activateChain(entry.section, p, nil)
+				self.bp.activateChain(entry.section, p, p.switchC, nil)
 				p.sections = append(p.sections, previousBlockHash)
 			}
 		}
@@ -270,8 +267,8 @@ func (self *peers) addPeer(
 		currentTD := self.bp.getTD()
 		bestpeer := self.best
 		if bestpeer != nil {
-			bestpeer.lock.Lock()
-			defer bestpeer.lock.Unlock()
+			bestpeer.lock.RLock()
+			defer bestpeer.lock.RUnlock()
 			currentTD = self.best.td
 		}
 		if td.Cmp(currentTD) > 0 {
@@ -367,14 +364,14 @@ func (self *BlockPool) switchPeer(oldp, newp *peer) {
 			if connected[hash] == nil {
 				// if not deleted, then reread from pool (it can be orphaned top half of a split section)
 				if entry := self.get(hash); entry != nil {
-					self.activateChain(entry.section, newp, connected)
+					self.activateChain(entry.section, newp, newp.switchC, connected)
 					connected[hash] = entry.section
 					sections = append(sections, hash)
 				}
 			}
 		}
 		plog.DebugDetailf("<%s> section processes (%v non-contiguous sequences, was %v before)", newp.id, len(sections), len(newp.sections))
-		// need to lock now that newp is exposed to section processes
+		// need to lock now that newp is exposed to section processesr
 		newp.lock.Lock()
 		newp.sections = sections
 		newp.lock.Unlock()
@@ -462,6 +459,8 @@ func (self *peer) getCurrentBlock(currentBlock *types.Block) {
 }
 
 func (self *peer) getBlockHashes() bool {
+	self.lock.Lock()
+	defer self.lock.Unlock()
 	//if connecting parent is found
 	if self.bp.hasBlock(self.parentHash) {
 		plog.DebugDetailf("HeadSection: <%s> parent block %s found in blockchain", self.id, hex(self.parentHash))
@@ -474,13 +473,16 @@ func (self *peer) getBlockHashes() bool {
 			self.addError(ErrInvalidBlock, "%v", err)
 			self.bp.status.badPeers[self.id]++
 		} else {
+			/* @zelig: Commented out temp untill the rest of the network has been fixed.
 			// XXX added currentBlock check (?)
-			if self.currentBlock != nil && self.currentBlock.Td != nil {
+			if self.currentBlock != nil && self.currentBlock.Td != nil && !self.currentBlock.Queued() {
+				plog.DebugDetailf("HeadSection: <%s> inserted %s to blockchain... check TD %v =?= %v", self.id, hex(self.parentHash), self.td, self.currentBlock.Td)
 				if self.td.Cmp(self.currentBlock.Td) != 0 {
-					//self.addError(ErrIncorrectTD, "on block %x", self.currentBlockHash)
-					//self.bp.status.badPeers[self.id]++
+					self.addError(ErrIncorrectTD, "on block %x", self.currentBlockHash)
+					self.bp.status.badPeers[self.id]++
 				}
 			}
+			*/
 			headKey := self.parentHash
 			height := self.bp.status.chain[headKey] + 1
 			self.bp.status.chain[self.currentBlockHash] = height
@@ -504,7 +506,7 @@ func (self *peer) getBlockHashes() bool {
 				self.bp.newSection([]*node{n}).activate(self)
 			} else {
 				plog.DebugDetailf("HeadSection: <%s> connecting parent %s found in pool...head section [%s] exists...not requesting hashes", self.id, hex(self.parentHash), sectionhex(parent.section))
-				self.bp.activateChain(parent.section, self, nil)
+				self.bp.activateChain(parent.section, self, self.switchC, nil)
 			}
 		} else {
 			plog.DebugDetailf("HeadSection: <%s> section [%s] requestBlockHashes", self.id, sectionhex(self.headSection))
@@ -528,6 +530,7 @@ func (self *peer) run() {
 
 	self.lock.RLock()
 	switchC := self.switchC
+	plog.Debugf("HeadSection: <%s> section process for head %s started", self.id, hex(self.currentBlockHash))
 	self.lock.RUnlock()
 
 	self.blockHashesRequestTimer = nil
@@ -570,7 +573,6 @@ LOOP:
 			self.bp.status.badPeers[self.id]++
 			self.bp.status.lock.Unlock()
 			// there is no persistence here, so GC will just take care of cleaning up
-			break LOOP
 
 		// signal for peer switch, quit
 		case <-switchC:
@@ -593,9 +595,9 @@ LOOP:
 			self.bp.status.badPeers[self.id]++
 			self.bp.status.lock.Unlock()
 			plog.Debugf("HeadSection: <%s> (headsection [%s]) quit channel closed : timed out without providing new blocks...quitting", self.id, sectionhex(self.headSection))
-			break LOOP
 		}
 	}
+
 	if !self.idle {
 		self.idle = true
 		self.bp.wg.Done()

+ 4 - 8
blockpool/peers_test.go

@@ -144,7 +144,8 @@ func TestAddPeer(t *testing.T) {
 	blockPool.Stop()
 }
 
-func TestPeerPromotionByOptionalTdOnBlock(t *testing.T) {
+func TestPeerPromotionByTdOnBlock(t *testing.T) {
+	t.Skip()
 	test.LogInit()
 	_, blockPool, blockPoolTester := newTestBlockPool(t)
 	blockPoolTester.blockChain[0] = nil
@@ -168,13 +169,8 @@ func TestPeerPromotionByOptionalTdOnBlock(t *testing.T) {
 	best = peer2.AddPeer()
 	peer2.serveBlocks(3, 4)
 	peer2.serveBlockHashes(4, 3, 2, 1)
-	hashes := blockPoolTester.hashPool.IndexesToHashes([]int{2, 3})
-	peer1.waitBlocksRequests(3)
-	blockPool.AddBlock(&types.Block{
-		HeaderHash:       common.Hash(hashes[1]),
-		ParentHeaderHash: common.Hash(hashes[0]),
-		Td:               common.Big3,
-	}, "peer1")
+	// hashes := blockPoolTester.hashPool.IndexesToHashes([]int{2, 3})
+	peer1.serveBlocks(2, 3)
 
 	blockPool.RemovePeer("peer2")
 	if blockPool.peers.best.id != "peer1" {

+ 1 - 1
blockpool/section.go

@@ -489,7 +489,7 @@ func (self *section) blockHashesRequest() {
 				//  activate parent section with this peer
 				// but only if not during switch mode
 				plog.DebugDetailf("[%s] parent section [%s] activated\n", sectionhex(self), sectionhex(parentSection))
-				self.bp.activateChain(parentSection, self.peer, nil)
+				self.bp.activateChain(parentSection, self.peer, self.peer.switchC, nil)
 				// if not root of chain, switch off
 				plog.DebugDetailf("[%s] parent found, hash requests deactivated (after %v total attempts)\n", sectionhex(self), self.blockHashesRequests)
 				self.blockHashesRequestTimer = nil

+ 6 - 1
blockpool/status_test.go

@@ -60,6 +60,8 @@ func checkStatus(t *testing.T, bp *BlockPool, syncing bool, expected []int) (err
 }
 
 func TestBlockPoolStatus(t *testing.T) {
+	t.Skip() // :FIXME:
+
 	test.LogInit()
 	var err error
 	n := 3
@@ -87,7 +89,7 @@ func testBlockPoolStatus(t *testing.T) (err error) {
 	delete(blockPoolTester.refBlockChain, 6)
 
 	blockPool.Start()
-	defer blockPool.Stop()
+
 	blockPoolTester.tds = make(map[int]int)
 	blockPoolTester.tds[9] = 1
 	blockPoolTester.tds[11] = 3
@@ -107,6 +109,7 @@ func testBlockPoolStatus(t *testing.T) (err error) {
 	}
 
 	peer1.AddPeer()
+
 	expected = []int{0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}
 	err = checkStatus(nil, blockPool, true, expected)
 	if err != nil {
@@ -242,6 +245,8 @@ func testBlockPoolStatus(t *testing.T) (err error) {
 	peer3.serveBlocks(0, 1)
 	blockPool.Wait(waitTimeout)
 	time.Sleep(200 * time.Millisecond)
+	blockPool.Stop()
+
 	expected = []int{14, 3, 11, 3, 8, 4, 1, 8, 4, 3, 4, 3, 1}
 	err = checkStatus(nil, blockPool, false, expected)
 	if err != nil {

+ 1 - 0
core/chain_manager.go

@@ -463,6 +463,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
 			// Do not penelise on future block. We'll need a block queue eventually that will queue
 			// future block for future use
 			if err == BlockFutureErr {
+				block.SetQueued(true)
 				self.futureBlocks.Push(block)
 				stats.queued++
 				continue

+ 4 - 0
core/types/block.go

@@ -97,6 +97,7 @@ type Block struct {
 	uncles       []*Header
 	transactions Transactions
 	Td           *big.Int
+	queued       bool // flag for blockpool to skip TD check
 
 	receipts Receipts
 }
@@ -268,6 +269,9 @@ func (self *Block) SetNonce(nonce uint64) {
 	self.header.SetNonce(nonce)
 }
 
+func (self *Block) Queued() bool     { return self.queued }
+func (self *Block) SetQueued(q bool) { self.queued = q }
+
 func (self *Block) Bloom() Bloom             { return self.header.Bloom }
 func (self *Block) Coinbase() common.Address { return self.header.Coinbase }
 func (self *Block) Time() int64              { return int64(self.header.Time) }

+ 10 - 0
errs/errors.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 
 	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
 )
 
 /*
@@ -76,9 +77,18 @@ func (self Error) Error() (message string) {
 	return self.message
 }
 
+func (self Error) Log(v glog.Verbose) {
+	if v {
+		v.Infoln(self)
+	}
+	//log.Sendln(self.level, self)
+}
+
+/*
 func (self Error) Log(log *logger.Logger) {
 	log.Sendln(self.level, self)
 }
+*/
 
 /*
 err.Fatal() is true if err's severity level is 0 or 1 (logger.ErrorLevel or logger.Silence)

+ 10 - 5
eth/protocol.go

@@ -8,6 +8,7 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/errs"
 	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/rlp"
 )
@@ -366,7 +367,8 @@ func (self *ethProtocol) requestBlocks(hashes []common.Hash) error {
 
 func (self *ethProtocol) protoError(code int, format string, params ...interface{}) (err *errs.Error) {
 	err = self.errors.New(code, format, params...)
-	err.Log(self.peer.Logger)
+	//err.Log(self.peer.Logger)
+	err.Log(glog.V(logger.Info))
 	return
 }
 
@@ -382,8 +384,11 @@ func (self *ethProtocol) sendStatus() error {
 }
 
 func (self *ethProtocol) protoErrorDisconnect(err *errs.Error) {
-	err.Log(self.peer.Logger)
-	if err.Fatal() {
-		self.peer.Disconnect(p2p.DiscSubprotocolError)
-	}
+	//err.Log(self.peer.Logger)
+	err.Log(glog.V(logger.Info))
+	/*
+		if err.Fatal() {
+			self.peer.Disconnect(p2p.DiscSubprotocolError)
+		}
+	*/
 }