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
}