@cryptotaxi247 / kubo / commits / 60708ea60

store IPNS records *outside* of the DHT

fixes #4749 License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>

Steven Allen committed May 9, 2018 at 09:21 UTC 60708ea60ed7ccb258c73f8a95818390fcda74d6
8 files changed +223 -174
core/core.go
+1 -1
@@ -513,7 +513,7 @@ func (n *IpfsNode) setupIpnsRepublisher() error {
513 return err
514 }
515
516 - n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.PrivateKey, n.Repo.Keystore())
516 + n.IpnsRepub = ipnsrp.NewRepublisher(n.Namesys, n.Repo.Datastore(), n.PrivateKey, n.Repo.Keystore())
517
518 if cfg.Ipns.RepublishPeriod != "" {
519 d, err := time.ParseDuration(cfg.Ipns.RepublishPeriod)
namesys/namesys.go
+30 -81
@@ -3,7 +3,6 @@ package namesys
3 import (
4 "context"
5 "strings"
6 - "sync"
6 "time"
7
8 opts "github.com/ipfs/go-ipfs/namesys/opts"
@@ -37,10 +36,10 @@ func NewNameSystem(r routing.ValueStore, ds ds.Datastore, cachesize int) NameSys
36 resolvers: map[string]resolver{
37 "dns": NewDNSResolver(),
38 "proquint": new(ProquintResolver),
40 - "dht": NewRoutingResolver(r, cachesize),
39 + "ipns": NewRoutingResolver(r, cachesize),
40 },
41 publishers: map[string]Publisher{
43 - "dht": NewRoutingPublisher(r, ds),
42 + "ipns": NewRoutingPublisher(r, ds),
43 },
44 }
45 }
@@ -71,66 +70,32 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string, options *opts.Reso
70 return "", ErrResolveFailed
71 }
72
74 - makePath := func(p path.Path) (path.Path, error) {
75 - if len(segments) > 3 {
76 - return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
77 - } else {
78 - return p, nil
79 - }
80 - }
81 -
73 // Resolver selection:
83 - // 1. if it is a multihash resolve through "pubsub" (if available),
84 - // with fallback to "dht"
74 + // 1. if it is a multihash resolve through "ipns".
75 // 2. if it is a domain name, resolve through "dns"
76 // 3. otherwise resolve through the "proquint" resolver
77 key := segments[2]
88 -
89 - _, err := mh.FromB58String(key)
90 - if err == nil {
91 - res, ok := ns.resolvers["pubsub"]
92 - if ok {
93 - p, err := res.resolveOnce(ctx, key, options)
94 - if err == nil {
95 - return makePath(p)
96 - }
97 - }
98 -
99 - res, ok = ns.resolvers["dht"]
100 - if ok {
101 - p, err := res.resolveOnce(ctx, key, options)
102 - if err == nil {
103 - return makePath(p)
104 - }
105 - }
106 -
107 - return "", ErrResolveFailed
78 + resName := "proquint"
79 + if _, err := mh.FromB58String(key); err == nil {
80 + resName = "ipns"
81 + } else if isd.IsDomain(key) {
82 + resName = "dns"
83 }
84
110 - if isd.IsDomain(key) {
111 - res, ok := ns.resolvers["dns"]
112 - if ok {
113 - p, err := res.resolveOnce(ctx, key, options)
114 - if err == nil {
115 - return makePath(p)
116 - }
117 - }
118 -
85 + res, ok := ns.resolvers[resName]
86 + if !ok {
87 + log.Debugf("no resolver found for %s", name)
88 return "", ErrResolveFailed
89 }
121 -
122 - res, ok := ns.resolvers["proquint"]
123 - if ok {
124 - p, err := res.resolveOnce(ctx, key, options)
125 - if err == nil {
126 - return makePath(p)
127 - }
128 -
90 + p, err := res.resolveOnce(ctx, key, options)
91 + if err != nil {
92 return "", ErrResolveFailed
93 }
94
132 - log.Debugf("no resolver found for %s", name)
133 - return "", ErrResolveFailed
95 + if len(segments) > 3 {
96 + return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
97 + }
98 + return p, nil
99 }
100
101 // Publish implements Publisher
@@ -139,39 +104,23 @@ func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) e
104 }
105
106 func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error {
142 - var dhtErr error
143 -
144 - wg := &sync.WaitGroup{}
145 - wg.Add(1)
146 - go func() {
147 - dhtErr = ns.publishers["dht"].PublishWithEOL(ctx, name, value, eol)
148 - if dhtErr == nil {
149 - ns.addToDHTCache(name, value, eol)
150 - }
151 - wg.Done()
152 - }()
153 -
154 - pub, ok := ns.publishers["pubsub"]
155 - if ok {
156 - wg.Add(1)
157 - go func() {
158 - err := pub.PublishWithEOL(ctx, name, value, eol)
159 - if err != nil {
160 - log.Warningf("error publishing %s with pubsub: %s", name, err.Error())
161 - }
162 - wg.Done()
163 - }()
164 - }
165 -
166 - wg.Wait()
167 - return dhtErr
107 + pub, ok := ns.publishers["ipns"]
108 + if !ok {
109 + return ErrPublishFailed
110 + }
111 + if err := pub.PublishWithEOL(ctx, name, value, eol); err != nil {
112 + return err
113 + }
114 + ns.addToIpnsCache(name, value, eol)
115 + return nil
116 +
117 }
118
170 -func (ns *mpns) addToDHTCache(key ci.PrivKey, value path.Path, eol time.Time) {
171 - rr, ok := ns.resolvers["dht"].(*routingResolver)
119 +func (ns *mpns) addToIpnsCache(key ci.PrivKey, value path.Path, eol time.Time) {
120 + rr, ok := ns.resolvers["ipns"].(*routingResolver)
121 if !ok {
122 // should never happen, purely for sanity
174 - log.Panicf("unexpected type %T as DHT resolver.", ns.resolvers["dht"])
123 + log.Panicf("unexpected type %T as DHT resolver.", ns.resolvers["ipns"])
124 }
125 if rr.cache == nil {
126 // resolver has no caching
namesys/namesys_test.go
+2 -2
@@ -59,8 +59,8 @@ func mockResolverTwo() *mockResolver {
59 func TestNamesysResolution(t *testing.T) {
60 r := &mpns{
61 resolvers: map[string]resolver{
62 - "dht": mockResolverOne(),
63 - "dns": mockResolverTwo(),
62 + "ipns": mockResolverOne(),
63 + "dns": mockResolverTwo(),
64 },
65 }
66
namesys/publisher.go
+150 -56
@@ -4,6 +4,8 @@ import (
4 "bytes"
5 "context"
6 "fmt"
7 + "strings"
8 + "sync"
9 "time"
10
11 pb "github.com/ipfs/go-ipfs/namesys/pb"
@@ -12,15 +14,17 @@ import (
14 ft "github.com/ipfs/go-ipfs/unixfs"
15
16 u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
15 - dhtpb "gx/ipfs/QmTUyK82BVPA6LmSzEJpfEunk9uBaQzWtMsNP917tVj4sT/go-libp2p-record/pb"
17 routing "gx/ipfs/QmUHRKTeaoASDvDj7cTAXsmjAY7KQ13ErtzkQHZQq6uFUz/go-libp2p-routing"
17 - dshelp "gx/ipfs/QmYJgz1Z5PbBGP7n2XA8uv5sF1EKLfYUjL7kFemVAjMNqC/go-ipfs-ds-help"
18 proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
19 peer "gx/ipfs/QmcJukH2sAFjY3HdBKq35WDzWoL3UUu2gt9wdfqZTUyM74/go-libp2p-peer"
20 ci "gx/ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5/go-libp2p-crypto"
21 ds "gx/ipfs/QmeiCcJfDW1GJnWUArudsv5rQsihpi4oyddPhdqo3CfX6i/go-datastore"
22 + dsquery "gx/ipfs/QmeiCcJfDW1GJnWUArudsv5rQsihpi4oyddPhdqo3CfX6i/go-datastore/query"
23 + base32 "gx/ipfs/QmfVj3x4D6Jkq9SEoi5n2NmoUomLwoeiwnYz2KQa15wRw6/base32"
24 )
25
26 +const ipnsPrefix = "/ipns/"
27 +
28 const PublishPutValTimeout = time.Minute
29 const DefaultRecordTTL = 24 * time.Hour
30
@@ -29,6 +33,9 @@ const DefaultRecordTTL = 24 * time.Hour
33 type ipnsPublisher struct {
34 routing routing.ValueStore
35 ds ds.Datastore
36 +
37 + // Used to ensure we assign IPNS records *sequential* sequence numbers.
38 + mu sync.Mutex
39 }
40
41 // NewRoutingPublisher constructs a publisher for the IPFS Routing name system.
@@ -46,69 +53,157 @@ func (p *ipnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value path.Pa
53 return p.PublishWithEOL(ctx, k, value, time.Now().Add(DefaultRecordTTL))
54 }
55
49 -// PublishWithEOL is a temporary stand in for the ipns records implementation
50 -// see here for more details: https://github.com/ipfs/specs/tree/master/records
51 -func (p *ipnsPublisher) PublishWithEOL(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) error {
56 +func IpnsDsKey(id peer.ID) ds.Key {
57 + return ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id)))
58 +}
59 +
60 +// PublishedNames returns the latest IPNS records published by this node and
61 +// their expiration times.
62 +//
63 +// This method will not search the routing system for records published by other
64 +// nodes.
65 +func (p *ipnsPublisher) ListPublished(ctx context.Context) (map[peer.ID]*pb.IpnsEntry, error) {
66 + query, err := p.ds.Query(dsquery.Query{
67 + Prefix: ipnsPrefix,
68 + })
69 + if err != nil {
70 + return nil, err
71 + }
72 + defer query.Close()
73 +
74 + records := make(map[peer.ID]*pb.IpnsEntry)
75 + for {
76 + select {
77 + case result, ok := <-query.Next():
78 + if !ok {
79 + return records, nil
80 + }
81 + if result.Error != nil {
82 + return nil, result.Error
83 + }
84 + value, ok := result.Value.([]byte)
85 + if !ok {
86 + log.Error("found ipns record that we couldn't convert to a value")
87 + continue
88 + }
89 + e := new(pb.IpnsEntry)
90 + if err := proto.Unmarshal(value, e); err != nil {
91 + // Might as well return what we can.
92 + log.Error("found an invalid IPNS entry:", err)
93 + continue
94 + }
95 + if !strings.HasPrefix(result.Key, ipnsPrefix) {
96 + log.Errorf("datastore query for keys with prefix %s returned a key: %s", ipnsPrefix, result.Key)
97 + continue
98 + }
99 + k := result.Key[len(ipnsPrefix):]
100 + pid, err := base32.RawStdEncoding.DecodeString(k)
101 + if err != nil {
102 + log.Errorf("ipns ds key invalid: %s", result.Key)
103 + continue
104 + }
105 + records[peer.ID(pid)] = e
106 + case <-ctx.Done():
107 + return nil, ctx.Err()
108 + }
109 + }
110 +}
111
112 +// GetPublished returns the record this node has published corresponding to the
113 +// given peer ID.
114 +//
115 +// If `checkRouting` is true and we have no existing record, this method will
116 +// check the routing system for any existing records.
117 +func (p *ipnsPublisher) GetPublished(ctx context.Context, id peer.ID, checkRouting bool) (*pb.IpnsEntry, error) {
118 + ctx, cancel := context.WithTimeout(ctx, time.Second*30)
119 + defer cancel()
120 +
121 + dsVal, err := p.ds.Get(IpnsDsKey(id))
122 + var value []byte
123 + switch err {
124 + case nil:
125 + var ok bool
126 + value, ok = dsVal.([]byte)
127 + if !ok {
128 + return nil, fmt.Errorf("found ipns record that we couldn't convert to a value")
129 + }
130 + case ds.ErrNotFound:
131 + if !checkRouting {
132 + return nil, nil
133 + }
134 + _, ipnskey := IpnsKeysForID(id)
135 + value, err = p.routing.GetValue(ctx, ipnskey)
136 + if err != nil {
137 + // Not found or other network issue. Can't really do
138 + // anything about this case.
139 + return nil, nil
140 + }
141 + default:
142 + return nil, err
143 + }
144 + e := new(pb.IpnsEntry)
145 + if err := proto.Unmarshal(value, e); err != nil {
146 + return nil, err
147 + }
148 + return e, nil
149 +}
150 +
151 +func (p *ipnsPublisher) updateRecord(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) (*pb.IpnsEntry, error) {
152 id, err := peer.IDFromPrivateKey(k)
153 if err != nil {
55 - return err
154 + return nil, err
155 }
156
58 - _, ipnskey := IpnsKeysForID(id)
157 + p.mu.Lock()
158 + defer p.mu.Unlock()
159
160 // get previous records sequence number
61 - seqnum, err := p.getPreviousSeqNo(ctx, ipnskey)
161 + rec, err := p.GetPublished(ctx, id, true)
162 if err != nil {
63 - return err
163 + return nil, err
164 }
165
66 - // increment it
67 - seqnum++
68 -
69 - return PutRecordToRouting(ctx, k, value, seqnum, eol, p.routing, id)
70 -}
166 + seqno := rec.GetSequence() // returns 0 if rec is nil
167 + if rec != nil && value != path.Path(rec.GetValue()) {
168 + // Don't bother incrementing the sequence number unless the
169 + // value changes.
170 + seqno++
171 + }
172
72 -func (p *ipnsPublisher) getPreviousSeqNo(ctx context.Context, ipnskey string) (uint64, error) {
73 - prevrec, err := p.ds.Get(dshelp.NewKeyFromBinary([]byte(ipnskey)))
74 - if err != nil && err != ds.ErrNotFound {
75 - // None found, lets start at zero!
76 - return 0, err
173 + // Create record
174 + entry, err := CreateRoutingEntryData(k, value, seqno, eol)
175 + if err != nil {
176 + return nil, err
177 }
78 - var val []byte
79 - if err == nil {
80 - prbytes, ok := prevrec.([]byte)
81 - if !ok {
82 - return 0, fmt.Errorf("unexpected type returned from datastore: %#v", prevrec)
83 - }
84 - dhtrec := new(dhtpb.Record)
85 - err := proto.Unmarshal(prbytes, dhtrec)
86 - if err != nil {
87 - return 0, err
88 - }
178
90 - val = dhtrec.GetValue()
91 - } else {
92 - // try and check the dht for a record
93 - ctx, cancel := context.WithTimeout(ctx, time.Second*30)
94 - defer cancel()
179 + // Set the TTL
180 + // TODO: Make this less hacky.
181 + ttl, ok := checkCtxTTL(ctx)
182 + if ok {
183 + entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds()))
184 + }
185
96 - rv, err := p.routing.GetValue(ctx, ipnskey)
97 - if err != nil {
98 - // no such record found, start at zero!
99 - return 0, nil
100 - }
186 + data, err := proto.Marshal(entry)
187 + if err != nil {
188 + return nil, err
189 + }
190
102 - val = rv
191 + // Put the new record.
192 + if err := p.ds.Put(IpnsDsKey(id), data); err != nil {
193 + return nil, err
194 }
195 + return entry, nil
196 +}
197
105 - e := new(pb.IpnsEntry)
106 - err = proto.Unmarshal(val, e)
198 +// PublishWithEOL is a temporary stand in for the ipns records implementation
199 +// see here for more details: https://github.com/ipfs/specs/tree/master/records
200 +func (p *ipnsPublisher) PublishWithEOL(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) error {
201 + record, err := p.updateRecord(ctx, k, value, eol)
202 if err != nil {
108 - return 0, err
203 + return err
204 }
205
111 - return e.GetSequence(), nil
206 + return PutRecordToRouting(ctx, p.routing, k.GetPublic(), record)
207 }
208
209 // setting the TTL on published records is an experimental feature.
@@ -124,25 +219,24 @@ func checkCtxTTL(ctx context.Context) (time.Duration, bool) {
219 return d, ok
220 }
221
127 -func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqnum uint64, eol time.Time, r routing.ValueStore, id peer.ID) error {
222 +func PutRecordToRouting(ctx context.Context, r routing.ValueStore, k ci.PubKey, entry *pb.IpnsEntry) error {
223 ctx, cancel := context.WithCancel(ctx)
224 defer cancel()
225
131 - namekey, ipnskey := IpnsKeysForID(id)
132 - entry, err := CreateRoutingEntryData(k, value, seqnum, eol)
226 + errs := make(chan error, 2) // At most two errors (IPNS, and public key)
227 +
228 + id, err := peer.IDFromPublicKey(k)
229 if err != nil {
230 return err
231 }
232
137 - ttl, ok := checkCtxTTL(ctx)
138 - if ok {
139 - entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds()))
233 + // Attempt to extract the public key from the ID
234 + extractedPublicKey, err := id.ExtractPublicKey()
235 + if err != nil {
236 + return err
237 }
238
142 - errs := make(chan error, 2) // At most two errors (IPNS, and public key)
143 -
144 - // Attempt to extract the public key from the ID
145 - extractedPublicKey, _ := id.ExtractPublicKey()
239 + namekey, ipnskey := IpnsKeysForID(id)
240
241 go func() {
242 errs <- PublishEntry(ctx, r, ipnskey, entry)
@@ -151,7 +245,7 @@ func PutRecordToRouting(ctx context.Context, k ci.PrivKey, value path.Path, seqn
245 // Publish the public key if a public key cannot be extracted from the ID
246 if extractedPublicKey == nil {
247 go func() {
154 - errs <- PublishPublicKey(ctx, r, namekey, k.GetPublic())
248 + errs <- PublishPublicKey(ctx, r, namekey, k)
249 }()
250
251 if err := waitOnErrChan(ctx, errs); err != nil {
namesys/publisher_test.go
+6 -1
@@ -75,7 +75,12 @@ func testNamekeyPublisher(t *testing.T, keyType int, expectedErr error, expected
75 serv := mockrouting.NewServer()
76 r := serv.ClientWithDatastore(context.Background(), &identity{p}, dstore)
77
78 - err = PutRecordToRouting(ctx, privKey, value, seqnum, eol, r, id)
78 + entry, err := CreateRoutingEntryData(privKey, value, seqnum, eol)
79 + if err != nil {
80 + t.Fatal(err)
81 + }
82 +
83 + err = PutRecordToRouting(ctx, r, pubKey, entry)
84 if err != nil {
85 t.Fatal(err)
86 }
namesys/republisher/repub.go
+22 -30
@@ -13,9 +13,6 @@ import (
13 goprocess "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess"
14 gpctx "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess/context"
15 logging "gx/ipfs/QmTG23dvpBCBjqQwyDxV8CQT6jmS4PSftNr1VqHhE3MLy7/go-log"
16 - recpb "gx/ipfs/QmTUyK82BVPA6LmSzEJpfEunk9uBaQzWtMsNP917tVj4sT/go-libp2p-record/pb"
17 - routing "gx/ipfs/QmUHRKTeaoASDvDj7cTAXsmjAY7KQ13ErtzkQHZQq6uFUz/go-libp2p-routing"
18 - dshelp "gx/ipfs/QmYJgz1Z5PbBGP7n2XA8uv5sF1EKLfYUjL7kFemVAjMNqC/go-ipfs-ds-help"
16 proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
17 peer "gx/ipfs/QmcJukH2sAFjY3HdBKq35WDzWoL3UUu2gt9wdfqZTUyM74/go-libp2p-peer"
18 ic "gx/ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5/go-libp2p-crypto"
@@ -39,7 +36,7 @@ var FailureRetryInterval = time.Minute * 5
36 const DefaultRecordLifetime = time.Hour * 24
37
38 type Republisher struct {
42 - r routing.ValueStore
39 + ns namesys.Publisher
40 ds ds.Datastore
41 self ic.PrivKey
42 ks keystore.Keystore
@@ -51,9 +48,9 @@ type Republisher struct {
48 }
49
50 // NewRepublisher creates a new Republisher
54 -func NewRepublisher(r routing.ValueStore, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher {
51 +func NewRepublisher(ns namesys.Publisher, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher {
52 return &Republisher{
56 - r: r,
53 + ns: ns,
54 ds: ds,
55 self: self,
56 ks: ks,
@@ -90,6 +87,10 @@ func (rp *Republisher) republishEntries(p goprocess.Process) error {
87 ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p))
88 defer cancel()
89
90 + // TODO: Use rp.ipns.ListPublished(). We can't currently *do* that
91 + // because:
92 + // 1. There's no way to get keys from the keystore by ID.
93 + // 2. We don't actually have access to the IPNS publisher.
94 err := rp.republishEntry(ctx, rp.self)
95 if err != nil {
96 return err
@@ -125,8 +126,7 @@ func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) erro
126 log.Debugf("republishing ipns entry for %s", id)
127
128 // Look for it locally only
128 - _, ipnskey := namesys.IpnsKeysForID(id)
129 - p, seq, err := rp.getLastVal(ipnskey)
129 + p, err := rp.getLastVal(id)
130 if err != nil {
131 if err == errNoEntry {
132 return nil
@@ -136,33 +136,25 @@ func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) erro
136
137 // update record with same sequence number
138 eol := time.Now().Add(rp.RecordLifetime)
139 - err = namesys.PutRecordToRouting(ctx, priv, p, seq, eol, rp.r, id)
140 - if err != nil {
141 - return err
142 - }
143 -
144 - return nil
139 + return rp.ns.PublishWithEOL(ctx, priv, p, eol)
140 }
141
147 -func (rp *Republisher) getLastVal(k string) (path.Path, uint64, error) {
148 - ival, err := rp.ds.Get(dshelp.NewKeyFromBinary([]byte(k)))
149 - if err != nil {
150 - // not found means we dont have a previously published entry
151 - return "", 0, errNoEntry
142 +func (rp *Republisher) getLastVal(id peer.ID) (path.Path, error) {
143 + // Look for it locally only
144 + vali, err := rp.ds.Get(namesys.IpnsDsKey(id))
145 + switch err {
146 + case nil:
147 + case ds.ErrNotFound:
148 + return "", errNoEntry
149 + default:
150 + return "", err
151 }
152
154 - val := ival.([]byte)
155 - dhtrec := new(recpb.Record)
156 - err = proto.Unmarshal(val, dhtrec)
157 - if err != nil {
158 - return "", 0, err
159 - }
153 + val := vali.([]byte)
154
161 - // extract published data from record
155 e := new(pb.IpnsEntry)
163 - err = proto.Unmarshal(dhtrec.GetValue(), e)
164 - if err != nil {
165 - return "", 0, err
156 + if err := proto.Unmarshal(val, e); err != nil {
157 + return "", err
158 }
167 - return path.Path(e.Value), e.GetSequence(), nil
159 + return path.Path(e.Value), nil
160 }
namesys/republisher/repub_test.go
+1 -1
@@ -78,7 +78,7 @@ func TestRepublish(t *testing.T) {
78 // The republishers that are contained within the nodes have their timeout set
79 // to 12 hours. Instead of trying to tweak those, we're just going to pretend
80 // they dont exist and make our own.
81 - repub := NewRepublisher(publisher.Routing, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
81 + repub := NewRepublisher(rp, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
82 repub.Interval = time.Second
83 repub.RecordLifetime = time.Second * 5
84
namesys/resolve_test.go
+11 -2
@@ -70,7 +70,12 @@ func TestPrexistingExpiredRecord(t *testing.T) {
70 // Make an expired record and put it in the datastore
71 h := path.FromString("/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN")
72 eol := time.Now().Add(time.Hour * -1)
73 - err = PutRecordToRouting(context.Background(), privk, h, 0, eol, d, id)
73 +
74 + entry, err := CreateRoutingEntryData(privk, h, 0, eol)
75 + if err != nil {
76 + t.Fatal(err)
77 + }
78 + err = PutRecordToRouting(context.Background(), d, pubk, entry)
79 if err != nil {
80 t.Fatal(err)
81 }
@@ -107,7 +112,11 @@ func TestPrexistingRecord(t *testing.T) {
112 // Make a good record and put it in the datastore
113 h := path.FromString("/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN")
114 eol := time.Now().Add(time.Hour)
110 - err = PutRecordToRouting(context.Background(), privk, h, 0, eol, d, id)
115 + entry, err := CreateRoutingEntryData(privk, h, 0, eol)
116 + if err != nil {
117 + t.Fatal(err)
118 + }
119 + err = PutRecordToRouting(context.Background(), d, pubk, entry)
120 if err != nil {
121 t.Fatal(err)
122 }