code: func (d *deliverServiceImpl) StartDeliverForChannel(chainID string, ledgerInfo blocksprovider.LedgerInfo, finalizer func()) error {
  	d.lock.Lock()
  	defer d.lock.Unlock()
  	if d.stopping {
  		errMsg := fmt.Sprintf("Delivery service is stopping cannot join a new channel %s", chainID)
  		logger.Errorf(errMsg)
  		return errors.New(errMsg)
  	}
  	if _, exist := d.blockProviders[chainID]; exist {
  		errMsg := fmt.Sprintf("Delivery service - block provider already exists for %s found, can't start delivery", chainID)
  		logger.Errorf(errMsg)
  		return errors.New(errMsg)
  	} else {
  		client := d.newClient(chainID, ledgerInfo)
  		logger.Debug("This peer will pass blocks from orderer service to other peers for channel", chainID)
  		d.blockProviders[chainID] = blocksprovider.NewBlocksProvider(chainID, client, d.conf.Gossip, d.conf.CryptoSvc)
  		go d.launchBlockProvider(chainID, finalizer)
  	}
  	return nil
  }
docs: // StartDeliverForChannel starts blocks delivery for channel
  // initializes the grpc stream for given chainID, creates blocks provider instance
  // that spawns in go routine to read new blocks starting from the position provided by ledger
  // info instance.