code: func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
  	logs := make(chan []*types.Log)
  	logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs)
  	if err != nil {
  		return rpc.ID(""), err
  	}
  
  	api.filtersMu.Lock()
  	api.filters[logsSub.ID] = &filter{typ: LogsSubscription, crit: crit, deadline: time.NewTimer(deadline), logs: make([]*types.Log, 0), s: logsSub}
  	api.filtersMu.Unlock()
  
  	go func() {
  		for {
  			select {
  			case l := <-logs:
  				api.filtersMu.Lock()
  				if f, found := api.filters[logsSub.ID]; found {
  					f.logs = append(f.logs, l...)
  				}
  				api.filtersMu.Unlock()
  			case <-logsSub.Err():
  				api.filtersMu.Lock()
  				delete(api.filters, logsSub.ID)
  				api.filtersMu.Unlock()
  				return
  			}
  		}
  	}()
  
  	return logsSub.ID, nil
  }
docs: // NewFilter creates a new filter and returns the filter id. It can be
  // used to retrieve logs when the state changes. This method cannot be
  // used to fetch logs that are already stored in the state.
  //
  // Default criteria for the from and to block are "latest".
  // Using "latest" as block number will return logs for mined blocks.
  // Using "pending" as block number returns logs for not yet mined (pending) blocks.
  // In case logs are removed (chain reorg) previously returned logs are returned
  // again but with the removed property set to true.
  //
  // In case "fromBlock" > "toBlock" an error is returned.
  //
  // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter