code: func (f *fetcher) Fetch(rctx context.Context) (Chunk, error) {
  	atomic.AddInt32(&f.requestCnt, 1)
  	defer func() {
  		// if all the requests are done the fetcher can be cancelled
  		if atomic.AddInt32(&f.requestCnt, -1) == 0 {
  			f.cancel()
  		}
  		f.span.Finish()
  	}()
  
  	// The peer asking for the chunk. Store in the shared peers map, but delete after the request
  	// has been delivered
  	peer := rctx.Value("peer")
  	if peer != nil {
  		f.peers.Store(peer, time.Now())
  		defer f.peers.Delete(peer)
  	}
  
  	// If there is a source in the context then it is an offer, otherwise a request
  	sourceIF := rctx.Value("source")
  
  	hopCount, _ := rctx.Value("hopcount").(uint8)
  
  	if sourceIF != nil {
  		var source enode.ID
  		if err := source.UnmarshalText([]byte(sourceIF.(string))); err != nil {
  			return nil, err
  		}
  		f.netFetcher.Offer(&source)
  	} else {
  		f.netFetcher.Request(hopCount)
  	}
  
  	// wait until either the chunk is delivered or the context is done
  	select {
  	case <-rctx.Done():
  		return nil, rctx.Err()
  	case <-f.deliveredC:
  		return f.chunk, nil
  	case <-f.cancelledC:
  		return nil, fmt.Errorf("fetcher cancelled")
  	}
  }
docs: // Fetch fetches the chunk synchronously, it is called by NetStore.Get is the chunk is not available
  // locally.