From 58a95f364c4dea6f0865567631b7508574c0a8e6 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Wed, 4 Mar 2020 21:31:22 +0100 Subject: [PATCH] refactor: error on resolve /ipns/{cidv1-dag-pb} ipfs resolve of /ipns/{cidv1} where CID has multicodec other than libp2p-key returns a meaningful error that includes fixed multicodec See also: https://github.com/ipfs/go-ipfs/pull/6096#discussion_r387184055 License: MIT Signed-off-by: Marcin Rataj --- namesys/namesys.go | 20 +++++++++++++++++++- namesys/routing.go | 18 ------------------ test/sharness/t0160-resolve.sh | 9 +++++++++ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/namesys/namesys.go b/namesys/namesys.go index ce84f6a9859..d25e08e84a3 100644 --- a/namesys/namesys.go +++ b/namesys/namesys.go @@ -2,10 +2,12 @@ package namesys import ( "context" + "fmt" "strings" "time" lru "github.com/hashicorp/golang-lru" + cid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" path "github.com/ipfs/go-path" opts "github.com/ipfs/interface-go-ipfs-core/options/namesys" @@ -116,7 +118,23 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts. // 3. otherwise resolve through the "proquint" resolver var res resolver - if _, err := peer.Decode(key); err == nil { + _, err := peer.Decode(key) + + // CIDs in IPNS are expected to have libp2p-key multicodec + // We ease the transition by returning a more meaningful error with a valid CID + if err != nil && err.Error() == "can't convert CID of type protobuf to a peer ID" { + ipnsCid, cidErr := cid.Decode(key) + if cidErr == nil && ipnsCid.Version() == 1 && ipnsCid.Type() != cid.Libp2pKey { + fixedCid := cid.NewCidV1(cid.Libp2pKey, ipnsCid.Hash()).String() + codecErr := fmt.Errorf("peer ID represented as CIDv1 require libp2p-key multicodec: retry with %s", fixedCid) + log.Debugf("RoutingResolver: could not convert public key hash %s to peer ID: %s\n", key, codecErr) + out <- onceResult{err: codecErr} + close(out) + return out + } + } + + if err == nil { res = ns.ipnsResolver } else if isd.IsDomain(key) { res = ns.dnsResolver diff --git a/namesys/routing.go b/namesys/routing.go index bf94abb4aa6..8eec9df802f 100644 --- a/namesys/routing.go +++ b/namesys/routing.go @@ -60,25 +60,7 @@ func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, option name = strings.TrimPrefix(name, "/ipns/") - // Fix PeerID represented as CIDv1 with invalid multicodec - if name[:4] == "bafy" { // TODO: is this a safe way of detecting base32-dag-pb? - ipnsCid, err := cid.Decode(name) - if err == nil && ipnsCid.Type() != cid.Libp2pKey { - // CIDs in IPNS are expected to have libp2p-key multicodec. - // We ease the transition by fixing multicodec on the fly: - // https://github.com/ipfs/go-ipfs/issues/5287#issuecomment-492163929 - name = cid.NewCidV1(cid.Libp2pKey, ipnsCid.Hash()).String() - } - } - pid, err := peer.Decode(name) - if err != nil { - log.Debugf("RoutingResolver: could not convert public key hash %s to peer ID: %s\n", name, err) - out <- onceResult{err: err} - close(out) - cancel() - return out - } // Name should be the hash of a public key retrievable from ipfs. // We retrieve the public key here to make certain that it's in the peer diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index 87740685644..03062778116 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -116,6 +116,15 @@ test_resolve_cmd_b32() { test_resolve_setup_name "self" "/ipfs/$c_hash_b32" test_resolve "/ipns/$self_hash" "/ipfs/$c_hash_b32" --cid-base=base32 + + # peer ID represented as CIDv1 require libp2p-key multicodec + # https://github.com/libp2p/specs/blob/master/RFC/0001-text-peerid-cid.md + local self_hash_b32protobuf=$(echo $self_hash | ipfs cid format -v 1 -b b --codec protobuf) + local self_hash_b32libp2pkey=$(echo $self_hash | ipfs cid format -v 1 -b b --codec libp2p-key) + test_expect_success "resolve of /ipns/{cidv1} with multicodec other than libp2p-key returns a meaningful error" ' + test_expect_code 1 ipfs resolve /ipns/$self_hash_b32protobuf 2>cidcodec_error && + grep "Error: peer ID represented as CIDv1 require libp2p-key multicodec: retry with $self_hash_b32libp2pkey" cidcodec_error + ' }