From db21c1cd8b190ec6345483c43e7d3816c427cbec Mon Sep 17 00:00:00 2001 From: Antonio Navarro Perez Date: Thu, 7 Jul 2022 10:04:38 +0200 Subject: [PATCH] Fix: Handle correctly keys on Get/Put Value and Get/Put IPNS. --- client/getipns.go | 6 ++++-- client/putipns.go | 14 +++++++++++++- client/store.go | 36 +++++++++++++++++++++++++++++++++--- go.mod | 2 +- test/clientserver_test.go | 14 ++++++++------ 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/client/getipns.go b/client/getipns.go index 94c9c59..1ab09b0 100644 --- a/client/getipns.go +++ b/client/getipns.go @@ -4,6 +4,8 @@ import ( "context" "github.com/ipfs/go-delegated-routing/gen/proto" + ipns "github.com/ipfs/go-ipns" + "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/routing" ) @@ -21,7 +23,7 @@ func (fp *Client) GetIPNS(ctx context.Context, id []byte) ([]byte, error) { if len(records) == 0 { return nil, routing.ErrNotFound } - best, err := fp.validator.Select(string(id), records) + best, err := fp.validator.Select(ipns.RecordKey(peer.ID(id)), records) if err != nil { return nil, err } @@ -66,7 +68,7 @@ func (fp *Client) GetIPNSAsync(ctx context.Context, id []byte) (<-chan GetIPNSAs continue } - if err = fp.validator.Validate(string(id), r0.Resp.Record); err != nil { + if err = fp.validator.Validate(ipns.RecordKey(peer.ID(id)), r0.Resp.Record); err != nil { r1.Err = err select { case <-ctx.Done(): diff --git a/client/putipns.go b/client/putipns.go index e146205..f0a5064 100644 --- a/client/putipns.go +++ b/client/putipns.go @@ -4,10 +4,17 @@ import ( "context" "github.com/ipfs/go-delegated-routing/gen/proto" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/pkg/errors" ) func (fp *Client) PutIPNS(ctx context.Context, id []byte, record []byte) error { - _, err := fp.client.PutIPNS(ctx, &proto.PutIPNSRequest{ID: id, Record: record}) + _, err := peer.IDFromString(string(id)) + if err != nil { + return errors.Wrap(err, "invalid peer ID") + } + + _, err = fp.client.PutIPNS(ctx, &proto.PutIPNSRequest{ID: id, Record: record}) if err != nil { return err } @@ -19,6 +26,11 @@ type PutIPNSAsyncResult struct { } func (fp *Client) PutIPNSAsync(ctx context.Context, id []byte, record []byte) (<-chan PutIPNSAsyncResult, error) { + _, err := peer.IDFromString(string(id)) + if err != nil { + return nil, errors.Wrap(err, "invalid peer ID") + } + ch0, err := fp.client.PutIPNS_Async(ctx, &proto.PutIPNSRequest{ID: id, Record: record}) if err != nil { return nil, err diff --git a/client/store.go b/client/store.go index 503c420..d7def6a 100644 --- a/client/store.go +++ b/client/store.go @@ -3,19 +3,40 @@ package client import ( "context" + "github.com/ipfs/go-ipns" "github.com/libp2p/go-libp2p-core/routing" + record "github.com/libp2p/go-libp2p-record" + "github.com/pkg/errors" ) var _ routing.ValueStore = &Client{} // PutValue adds value corresponding to given Key. func (c *Client) PutValue(ctx context.Context, key string, val []byte, opts ...routing.Option) error { - return c.PutIPNS(ctx, []byte(key), val) + ns, path, err := record.SplitKey(key) + if err != nil { + return errors.Wrap(err, "invalid key") + } + + if ns != "ipns" { + return ipns.ErrKeyFormat + } + + return c.PutIPNS(ctx, []byte(path), val) } // GetValue searches for the value corresponding to given Key. func (c *Client) GetValue(ctx context.Context, key string, opts ...routing.Option) ([]byte, error) { - return c.GetIPNS(ctx, []byte(key)) + ns, path, err := record.SplitKey(key) + if err != nil { + return nil, errors.Wrap(err, "invalid key") + } + + if ns != "ipns" { + return nil, ipns.ErrKeyFormat + } + + return c.GetIPNS(ctx, []byte(path)) } // SearchValue searches for better and better values from this value @@ -29,7 +50,16 @@ func (c *Client) GetValue(ctx context.Context, key string, opts ...routing.Optio // Implementations of this methods won't return ErrNotFound. When a value // couldn't be found, the channel will get closed without passing any results func (c *Client) SearchValue(ctx context.Context, key string, opts ...routing.Option) (<-chan []byte, error) { - resChan, err := c.GetIPNSAsync(ctx, []byte(key)) + ns, path, err := record.SplitKey(key) + if err != nil { + return nil, errors.Wrap(err, "invalid key") + } + + if ns != "ipns" { + return nil, ipns.ErrKeyFormat + } + + resChan, err := c.GetIPNSAsync(ctx, []byte(path)) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index cf30bf0..a2109a3 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/libp2p/go-libp2p-record v0.1.3 github.com/multiformats/go-multiaddr v0.5.0 github.com/multiformats/go-multihash v0.1.0 + github.com/pkg/errors v0.8.1 ) require ( @@ -34,7 +35,6 @@ require ( github.com/multiformats/go-multicodec v0.5.0 // indirect github.com/multiformats/go-varint v0.0.6 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pkg/errors v0.8.1 // indirect github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/test/clientserver_test.go b/test/clientserver_test.go index d8956c7..d7102bb 100644 --- a/test/clientserver_test.go +++ b/test/clientserver_test.go @@ -73,7 +73,7 @@ func testClientServer(t *testing.T, numIter int) (avgLatency time.Duration, delt } // exercise GetIPNS - record, err := c.GetIPNS(context.Background(), testIPNSID) + record, err := c.GetIPNS(context.Background(), []byte(testPeerIDFromIPNS)) if err != nil { t.Fatal(err) } @@ -102,7 +102,7 @@ func testClientServer(t *testing.T, numIter int) (avgLatency time.Duration, delt } // exercise PutIPNS - err = c.PutIPNS(context.Background(), testIPNSID, testIPNSRecord) + err = c.PutIPNS(context.Background(), []byte(testPeerIDFromIPNS), testIPNSRecord) if err != nil { t.Fatal(err) } @@ -188,7 +188,7 @@ func TestCancelContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - gir, err := c.GetIPNSAsync(ctx, testIPNSID) + gir, err := c.GetIPNSAsync(ctx, []byte(testPeerIDFromIPNS)) if err != nil { t.Fatal(err) } @@ -202,7 +202,7 @@ func TestCancelContext(t *testing.T) { ctx, cancel = context.WithCancel(context.Background()) - pir, err := c.PutIPNSAsync(ctx, testIPNSID, testIPNSRecord) + pir, err := c.PutIPNSAsync(ctx, []byte(testPeerIDFromIPNS), testIPNSRecord) if err != nil { t.Fatal(err) } @@ -293,8 +293,9 @@ var ( Addrs: []multiaddr.Multiaddr{testMultiaddr}, } // IPNS - testIPNSID []byte - testIPNSRecord []byte + testPeerIDFromIPNS peer.ID + testIPNSID []byte + testIPNSRecord []byte ) // TestMain generates a valid IPNS key and record for testing purposes. @@ -307,6 +308,7 @@ func TestMain(m *testing.M) { if err != nil { panic(err) } + testPeerIDFromIPNS = peerID testIPNSID = []byte(ipns.RecordKey(peerID)) entry, err := ipns.Create(privateKey, testIPNSID, 0, time.Now().Add(time.Hour), time.Hour) if err != nil {