code: func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (common.Hash, error) {
  	c.log.Trace("Processing new chain section", "section", section)
  
  	// Reset and partial processing
  
  	if err := c.backend.Reset(c.ctx, section, lastHead); err != nil {
  		c.setValidSections(0)
  		return common.Hash{}, err
  	}
  
  	for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ {
  		hash := rawdb.ReadCanonicalHash(c.chainDb, number)
  		if hash == (common.Hash{}) {
  			return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number)
  		}
  		header := rawdb.ReadHeader(c.chainDb, hash, number)
  		if header == nil {
  			return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4])
  		} else if header.ParentHash != lastHead {
  			return common.Hash{}, fmt.Errorf("chain reorged during section processing")
  		}
  		if err := c.backend.Process(c.ctx, header); err != nil {
  			return common.Hash{}, err
  		}
  		lastHead = header.Hash()
  	}
  	if err := c.backend.Commit(); err != nil {
  		return common.Hash{}, err
  	}
  	return lastHead, nil
  }
docs: // processSection processes an entire section by calling backend functions while
  // ensuring the continuity of the passed headers. Since the chain mutex is not
  // held while processing, the continuity can be broken by a long reorg, in which
  // case the function returns with an error.