diff --git a/core/commands/ipns.go b/core/commands/ipns.go index eb4bc9ed66d..59128691402 100644 --- a/core/commands/ipns.go +++ b/core/commands/ipns.go @@ -45,6 +45,7 @@ Resolve the value of another name: }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name"), + cmds.BoolOption("nocache", "n", "Do not used cached entries"), }, Run: func(req cmds.Request, res cmds.Response) { @@ -62,15 +63,27 @@ Resolve the value of another name: } } - var resolver namesys.Resolver - resolver = n.Namesys - if local, _, _ := req.Option("local").Bool(); local { + nocache, _, _ := req.Option("nocache").Bool() + local, _, _ := req.Option("local").Bool() + + // default to nodes namesys resolver + var resolver namesys.Resolver = n.Namesys + + if local && nocache { + res.SetError(errors.New("cannot specify both local and nocache"), cmds.ErrNormal) + return + } + + if local { offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey) resolver = namesys.NewRoutingResolver(offroute, 0) } - var name string + if nocache { + resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0) + } + var name string if len(req.Arguments()) == 0 { if n.Identity == "" { res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal) diff --git a/namesys/routing.go b/namesys/routing.go index 99f806dcb68..93161df53b6 100644 --- a/namesys/routing.go +++ b/namesys/routing.go @@ -13,6 +13,7 @@ import ( pb "github.com/ipfs/go-ipfs/namesys/pb" path "github.com/ipfs/go-ipfs/path" routing "github.com/ipfs/go-ipfs/routing" + u "github.com/ipfs/go-ipfs/util" logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log" ) @@ -31,25 +32,31 @@ func (r *routingResolver) cacheGet(name string) (path.Path, bool) { r.cachelock.Lock() entry, ok := r.cache[name] r.cachelock.Unlock() - if ok && time.Now().Sub(entry.recvd) < r.cachelife { + if ok && time.Now().Before(entry.eol) { return entry.val, true } return "", false } -func (r *routingResolver) cacheSet(name string, val path.Path) { +func (r *routingResolver) cacheSet(name string, val path.Path, rec *pb.IpnsEntry) { + cacheTil := time.Now().Add(r.cachelife) + eol, ok := checkEOL(rec) + if ok && eol.Before(cacheTil) { + cacheTil = eol + } + r.cachelock.Lock() r.cache[name] = cacheEntry{ - val: val, - recvd: time.Now(), + val: val, + eol: eol, } r.cachelock.Unlock() } type cacheEntry struct { - val path.Path - recvd time.Time + val path.Path + eol time.Time } // NewRoutingResolver constructs a name resolver using the IPFS Routing system @@ -133,13 +140,25 @@ func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Pa if err != nil { return "", err } - r.cacheSet(name, p) + + r.cacheSet(name, p, entry) return p, nil } else { // Its an old style multihash record log.Warning("Detected old style multihash record") p := path.FromKey(key.Key(valh)) - r.cacheSet(name, p) + r.cacheSet(name, p, entry) return p, nil } } + +func checkEOL(e *pb.IpnsEntry) (time.Time, bool) { + if e.GetValidityType() == pb.IpnsEntry_EOL { + eol, err := u.ParseRFC3339(string(e.GetValidity())) + if err != nil { + return time.Time{}, false + } + return eol, true + } + return time.Time{}, false +} diff --git a/repo/config/init.go b/repo/config/init.go index 49d0a1ecb08..409edcd554c 100644 --- a/repo/config/init.go +++ b/repo/config/init.go @@ -64,6 +64,10 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { IPNS: "/ipns", }, + Ipns: Ipns{ + ResolveCacheTime: "1m", + }, + // tracking ipfs version used to generate the init folder and adding // update checker default setting. Version: VersionDefaultValue(), diff --git a/routing/dht/routing.go b/routing/dht/routing.go index 4bf2517c4d8..5f020619930 100644 --- a/routing/dht/routing.go +++ b/routing/dht/routing.go @@ -84,7 +84,10 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key key.Key) ([]byte, error) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() - vals, err := dht.GetValues(ctx, key, (KValue/2)+1) + // retrieve a majority of the expected record count + majority := (KValue / 2) + 1 + + vals, err := dht.GetValues(ctx, key, majority) if err != nil { return nil, err }