code: func storeFilter(dbTx database.Tx, block *btcutil.Block, f *gcs.Filter,
  	filterType wire.FilterType) error {
  	if uint8(filterType) > maxFilterType {
  		return errors.New("unsupported filter type")
  	}
  
  	// Figure out which buckets to use.
  	fkey := cfIndexKeys[filterType]
  	hkey := cfHeaderKeys[filterType]
  	hashkey := cfHashKeys[filterType]
  
  	// Start by storing the filter.
  	h := block.Hash()
  	filterBytes, err := f.NBytes()
  	if err != nil {
  		return err
  	}
  	err = dbStoreFilterIdxEntry(dbTx, fkey, h, filterBytes)
  	if err != nil {
  		return err
  	}
  
  	// Next store the filter hash.
  	filterHash, err := builder.GetFilterHash(f)
  	if err != nil {
  		return err
  	}
  	err = dbStoreFilterIdxEntry(dbTx, hashkey, h, filterHash[:])
  	if err != nil {
  		return err
  	}
  
  	// Then fetch the previous block's filter header.
  	var prevHeader *chainhash.Hash
  	ph := &block.MsgBlock().Header.PrevBlock
  	if ph.IsEqual(&zeroHash) {
  		prevHeader = &zeroHash
  	} else {
  		pfh, err := dbFetchFilterIdxEntry(dbTx, hkey, ph)
  		if err != nil {
  			return err
  		}
  
  		// Construct the new block's filter header, and store it.
  		prevHeader, err = chainhash.NewHash(pfh)
  		if err != nil {
  			return err
  		}
  	}
  
  	fh, err := builder.MakeHeaderForFilter(f, *prevHeader)
  	if err != nil {
  		return err
  	}
  	return dbStoreFilterIdxEntry(dbTx, hkey, h, fh[:])
  }
docs: // storeFilter stores a given filter, and performs the steps needed to
  // generate the filter's header.