func parseKey(maybe string) (Key, error) { h, err := mh.FromB58String(maybe) if err != nil { return nil, err } return &mhKey{mh: h}, nil }
// ResolvePath fetches the node for given path. It uses the first // path component as a hash (key) of the first node, then resolves // all other components walking the links, with ResolveLinks. func (s *Resolver) ResolvePath(fpath string) (*merkledag.Node, error) { log.Debugf("Resolve: '%s'", fpath) fpath = path.Clean(fpath) parts := strings.Split(fpath, "/") // skip over empty first elem if len(parts[0]) == 0 { parts = parts[1:] } // if nothing, bail. if len(parts) == 0 { return nil, fmt.Errorf("ipfs path must contain at least one component") } // first element in the path is a b58 hash (for now) h, err := mh.FromB58String(parts[0]) if err != nil { log.Debug("given path element is not a base58 string.\n") return nil, err } log.Debug("Resolve dag get.\n") nd, err := s.DAG.Get(u.Key(h)) if err != nil { return nil, err } return s.ResolveLinks(nd, parts[1:]) }
// Resolve implements Resolver. Uses the IPFS routing system to resolve SFS-like // names. func (r *routingResolver) Resolve(name string) (string, error) { log.Debugf("RoutingResolve: '%s'", name) ctx := context.TODO() hash, err := mh.FromB58String(name) if err != nil { log.Warning("RoutingResolve: bad input hash: [%s]\n", name) return "", err } // name should be a multihash. if it isn't, error out here. // use the routing system to get the name. // /ipns/<name> h := []byte("/ipns/" + string(hash)) ipnsKey := u.Key(h) val, err := r.routing.GetValue(ctx, ipnsKey) if err != nil { log.Warning("RoutingResolve get failed.") return "", err } entry := new(pb.IpnsEntry) err = proto.Unmarshal(val, entry) if err != nil { return "", err } // name should be a public key retrievable from ipfs // /ipfs/<name> key := u.Key("/pk/" + string(hash)) pkval, err := r.routing.GetValue(ctx, key) if err != nil { log.Warning("RoutingResolve PubKey Get failed.") return "", err } // get PublicKey from node.Data pk, err := ci.UnmarshalPublicKey(pkval) if err != nil { return "", err } hsh, _ := pk.Hash() log.Debugf("pk hash = %s", u.Key(hsh)) // check sig with pk if ok, err := pk.Verify(ipnsEntryDataForSig(entry), entry.GetSignature()); err != nil || !ok { return "", fmt.Errorf("Invalid value. Not signed by PrivateKey corresponding to %v", pk) } // ok sig checks out. this is a valid name. return string(entry.GetValue()), nil }
// Publish implements Publisher. Accepts a keypair and a value, // and publishes it out to the routing system func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error { log.Debugf("namesys: Publish %s", value) // validate `value` is a ref (multihash) _, err := mh.FromB58String(value) if err != nil { log.Errorf("hash cast failed: %s", value) return fmt.Errorf("publish value must be str multihash. %v", err) } ctx := context.TODO() data, err := createRoutingEntryData(k, value) if err != nil { log.Error("entry creation failed.") return err } pubkey := k.GetPublic() pkbytes, err := pubkey.Bytes() if err != nil { log.Error("pubkey getbytes failed.") return err } nameb := u.Hash(pkbytes) namekey := u.Key("/pk/" + string(nameb)) log.Debugf("Storing pubkey at: %s", namekey) // Store associated public key timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, namekey, pkbytes) if err != nil { return err } ipnskey := u.Key("/ipns/" + string(nameb)) log.Debugf("Storing ipns entry at: %s", ipnskey) // Store ipns entry at "/ipns/"+b58(h(pubkey)) timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*4)) err = p.routing.PutValue(timectx, ipnskey, data) if err != nil { return err } return nil }
// converts the Node object into a real dag.Node func deserializeNode(node *Node) (*dag.Node, error) { dagnode := new(dag.Node) dagnode.Data = node.Data dagnode.Links = make([]*dag.Link, len(node.Links)) for i, link := range node.Links { hash, err := mh.FromB58String(link.Hash) if err != nil { return nil, err } dagnode.Links[i] = &dag.Link{ Name: link.Name, Size: link.Size, Hash: hash, } } return dagnode, nil }
func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) { split := func(addr string) (string, string) { idx := strings.LastIndex(addr, "/") if idx == -1 { return "", addr } return addr[:idx], addr[idx+1:] } peers := []*config.BootstrapPeer{} for _, addr := range input { addrS, peeridS := split(addr) // make sure addrS parses as a multiaddr. if len(addrS) > 0 { maddr, err := ma.NewMultiaddr(addrS) if err != nil { return nil, err } addrS = maddr.String() } // make sure idS parses as a peer.ID _, err := mh.FromB58String(peeridS) if err != nil { return nil, err } // construct config entry peers = append(peers, &config.BootstrapPeer{ Address: addrS, PeerID: peeridS, }) } return peers, nil }
Arguments: []cmds.Argument{ cmds.StringArg("key", true, false, "The base58 multihash of an existing block to get"), }, Run: func(req cmds.Request) (interface{}, error) { n, err := req.Context().GetNode() if err != nil { return nil, err } key := req.Arguments()[0] if !u.IsValidHash(key) { return nil, cmds.Error{"Not a valid hash", cmds.ErrClient} } h, err := mh.FromB58String(key) if err != nil { return nil, err } k := u.Key(h) ctx, _ := context.WithTimeout(context.TODO(), time.Second*5) b, err := n.Blocks.GetBlock(ctx, k) if err != nil { return nil, err } log.Debugf("BlockGet key: '%q'", b.Key()) return bytes.NewReader(b.Data), nil }, }
// CanResolve implements Resolver. Checks whether name is a b58 encoded string. func (r *routingResolver) CanResolve(name string) bool { _, err := mh.FromB58String(name) return err == nil }