code: func (s *ChainService) rollBackToHeight(height uint32) (*waddrmgr.BlockStamp, error) {
  	header, headerHeight, err := s.BlockHeaders.ChainTip()
  	if err != nil {
  		return nil, err
  	}
  	bs := &waddrmgr.BlockStamp{
  		Height: int32(headerHeight),
  		Hash:   header.BlockHash(),
  	}
  
  	_, regHeight, err := s.RegFilterHeaders.ChainTip()
  	if err != nil {
  		return nil, err
  	}
  
  	for uint32(bs.Height) > height {
  		header, _, err := s.BlockHeaders.FetchHeader(&bs.Hash)
  		if err != nil {
  			return nil, err
  		}
  
  		newTip := &header.PrevBlock
  
  		// Only roll back filter headers if they've caught up this far.
  		if uint32(bs.Height) <= regHeight {
  			newFilterTip, err := s.RegFilterHeaders.RollbackLastBlock(newTip)
  			if err != nil {
  				return nil, err
  			}
  			regHeight = uint32(newFilterTip.Height)
  		}
  
  		bs, err = s.BlockHeaders.RollbackLastBlock()
  		if err != nil {
  			return nil, err
  		}
  
  		// Notifications are asynchronous, so we include the previous
  		// header in the disconnected notification in case we're rolling
  		// back farther and the notification subscriber needs it but
  		// can't read it before it's deleted from the store.
  		prevHeader, _, err := s.BlockHeaders.FetchHeader(newTip)
  		if err != nil {
  			return nil, err
  		}
  
  		// Now we send the block disconnected notifications.
  		s.blockManager.onBlockDisconnected(
  			*header, headerHeight, *prevHeader,
  		)
  	}
  	return bs, nil
  }
docs: // rollBackToHeight rolls back all blocks until it hits the specified height.
  // It sends notifications along the way.