insert spawns a new goroutine to run a block insertion into the chain. If the block's number is at the same height as the current import phase, it updates the phase states accordingly.
(peer string, block *types.Block)
| 643 | // block's number is at the same height as the current import phase, it updates |
| 644 | // the phase states accordingly. |
| 645 | func (f *Fetcher) insert(peer string, block *types.Block) { |
| 646 | hash := block.Hash() |
| 647 | |
| 648 | // Run the import on a new thread |
| 649 | log.Debug("Importing propagated block", "peer", peer, "number", block.Number(), "hash", hash.Hex()) |
| 650 | go func() { |
| 651 | defer func() { f.done <- hash }() |
| 652 | |
| 653 | // If the parent's unknown, abort insertion |
| 654 | parent := f.getBlock(block.ParentHash()) |
| 655 | if parent == nil { |
| 656 | log.Debug("Unknown parent of propagated block", "peer", peer, "number", block.Number(), "hash", hash, "parent", block.ParentHash().Hex()) |
| 657 | return |
| 658 | } |
| 659 | // Quickly validate the header and propagate the block if it passes |
| 660 | switch err := f.verifyHeader(block.Header(), block.RefHeader()); err { |
| 661 | case nil: |
| 662 | case consensus.ErrFutureBlock: |
| 663 | // Weird future block, don't fail, but neither propagate |
| 664 | case consensus.ErrUnknownAncestor: |
| 665 | return |
| 666 | |
| 667 | default: |
| 668 | // Something went very wrong, drop the peer |
| 669 | log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash.Hex(), "err", err) |
| 670 | |
| 671 | log.Warn("dropping peer in fetcher", "peer", peer) |
| 672 | f.dropPeer(peer) |
| 673 | return |
| 674 | } |
| 675 | |
| 676 | // NB we actually insert the chain. run the actual import and log any issues |
| 677 | if _, err := f.insertChain(types.Blocks{block}); err != nil { |
| 678 | log.Debug("Propagated block import failed", "peer", peer, "number", block.Number(), "hash", hash.Hex(), "err", err) |
| 679 | return |
| 680 | } |
| 681 | |
| 682 | // If import succeeded, broadcast the block |
| 683 | propAnnounceOutTimer.UpdateSince(block.ReceivedAt) |
| 684 | go f.broadcastBlock(block, true) |
| 685 | |
| 686 | // Invoke the testing hook if needed |
| 687 | if f.importedHook != nil { |
| 688 | f.importedHook(block) |
| 689 | } |
| 690 | }() |
| 691 | } |
| 692 | |
| 693 | // forgetHash removes all traces of a block announcement from the fetcher's |
| 694 | // internal state. |
no test coverage detected