// IsValidHash checks whether a given hash is valid (b58 decodable, len > 0) func IsValidHash(s string) bool { out := b58.Decode(s) if out == nil || len(out) == 0 { return false } _, err := mh.Cast(out) if err != nil { return false } return true }
func Decode(encoding, digest string) (mh.Multihash, error) { switch encoding { case "raw": return mh.Cast([]byte(digest)) case "hex": return hex.DecodeString(digest) case "base58": return base58.Decode(digest), nil case "base64": return base64.StdEncoding.DecodeString(digest) default: return nil, fmt.Errorf("unknown encoding: %s", encoding) } }
// AllKeysChan runs a query for keys from the blockstore. // this is very simplistic, in the future, take dsq.Query as a param? // // AllKeysChan respects context func (bs *blockstore) AllKeysChan(ctx context.Context) (<-chan key.Key, error) { // KeysOnly, because that would be _a lot_ of data. q := dsq.Query{KeysOnly: true} // datastore/namespace does *NOT* fix up Query.Prefix q.Prefix = BlockPrefix.String() res, err := bs.datastore.Query(q) if err != nil { return nil, err } // this function is here to compartmentalize get := func() (k key.Key, ok bool) { select { case <-ctx.Done(): return k, false case e, more := <-res.Next(): if !more { return k, false } if e.Error != nil { return k, false } // need to convert to key.Key using key.KeyFromDsKey. k = key.KeyFromDsKey(ds.NewKey(e.Key)) // key must be a multihash. else ignore it. _, err := mh.Cast([]byte(k)) if err != nil { return "", true } return k, true } } output := make(chan key.Key) go func() { defer func() { res.Process().Close() // ensure exit (signals early exit, too) close(output) }() for { k, ok := get() if !ok { return } if k == "" { continue } select { case <-ctx.Done(): return case output <- k: } } }() return output, nil }