code: func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
  	var (
  		headers   = make(chan *types.Header)
  		headerSub = api.events.SubscribeNewHeads(headers)
  	)
  
  	api.filtersMu.Lock()
  	api.filters[headerSub.ID] = &filter{typ: BlocksSubscription, deadline: time.NewTimer(deadline), hashes: make([]common.Hash, 0), s: headerSub}
  	api.filtersMu.Unlock()
  
  	go func() {
  		for {
  			select {
  			case h := <-headers:
  				api.filtersMu.Lock()
  				if f, found := api.filters[headerSub.ID]; found {
  					f.hashes = append(f.hashes, h.Hash())
  				}
  				api.filtersMu.Unlock()
  			case <-headerSub.Err():
  				api.filtersMu.Lock()
  				delete(api.filters, headerSub.ID)
  				api.filtersMu.Unlock()
  				return
  			}
  		}
  	}()
  
  	return headerSub.ID
  }
docs: // NewBlockFilter creates a filter that fetches blocks that are imported into the chain.
  // It is part of the filter package since polling goes with eth_getFilterChanges.
  //
  // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter