@@ -272,11 +272,7 @@ func (pm *ProtocolManager) handle(p *peer) error {
272
272
defer pm .removePeer (p .id )
273
273
274
274
// Register the peer in the downloader. If the downloader considers it banned, we disconnect
275
- err := pm .downloader .RegisterPeer (p .id , p .version , p .Head (),
276
- p .RequestHeadersByHash , p .RequestHeadersByNumber ,
277
- p .RequestBodies , p .RequestReceipts , p .RequestNodeData ,
278
- )
279
- if err != nil {
275
+ if err := pm .downloader .RegisterPeer (p .id , p .version , p .Head , p .RequestHeadersByHash , p .RequestHeadersByNumber , p .RequestBodies , p .RequestReceipts , p .RequestNodeData ); err != nil {
280
276
return err
281
277
}
282
278
// Propagate existing transactions. new transactions appearing
@@ -411,7 +407,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
411
407
// If we already have a DAO header, we can check the peer's TD against it. If
412
408
// the peer's ahead of this, it too must have a reply to the DAO check
413
409
if daoHeader := pm .blockchain .GetHeaderByNumber (pm .chainconfig .DAOForkBlock .Uint64 ()); daoHeader != nil {
414
- if p . Td () .Cmp (pm .blockchain .GetTd (daoHeader .Hash ())) >= 0 {
410
+ if _ , td := p . Head (); td .Cmp (pm .blockchain .GetTd (daoHeader .Hash ())) >= 0 {
415
411
verifyDAO = false
416
412
}
417
413
}
@@ -617,7 +613,6 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
617
613
// Mark the hashes as present at the remote node
618
614
for _ , block := range announces {
619
615
p .MarkBlock (block .Hash )
620
- p .SetHead (block .Hash )
621
616
}
622
617
// Schedule all the unknown hashes for retrieval
623
618
unknown := make ([]announce , 0 , len (announces ))
@@ -644,15 +639,23 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
644
639
645
640
// Mark the peer as owning the block and schedule it for import
646
641
p .MarkBlock (request .Block .Hash ())
647
- p .SetHead (request .Block .Hash ())
648
-
649
642
pm .fetcher .Enqueue (p .id , request .Block )
650
643
651
- // Update the peers total difficulty if needed, schedule a download if gapped
652
- if request .TD .Cmp (p .Td ()) > 0 {
653
- p .SetTd (request .TD )
654
- td := pm .blockchain .GetTd (pm .blockchain .CurrentBlock ().Hash ())
655
- if request .TD .Cmp (new (big.Int ).Add (td , request .Block .Difficulty ())) > 0 {
644
+ // Assuming the block is importable by the peer, but possibly not yet done so,
645
+ // calculate the head hash and TD that the peer truly must have.
646
+ var (
647
+ trueHead = request .Block .ParentHash ()
648
+ trueTD = new (big.Int ).Sub (request .TD , request .Block .Difficulty ())
649
+ )
650
+ // Update the peers total difficulty if better than the previous
651
+ if _ , td := p .Head (); trueTD .Cmp (td ) > 0 {
652
+ p .SetHead (trueHead , trueTD )
653
+
654
+ // Schedule a sync if above ours. Note, this will not fire a sync for a gap of
655
+ // a singe block (as the true TD is below the propagated block), however this
656
+ // scenario should easily be covered by the fetcher.
657
+ currentBlock := pm .blockchain .CurrentBlock ()
658
+ if trueTD .Cmp (pm .blockchain .GetTd (currentBlock .Hash ())) > 0 {
656
659
go pm .synchronise (p )
657
660
}
658
661
}
0 commit comments