Skip to content

Commit d213160

Browse files
committed
chore: apply feedback
1 parent b335bde commit d213160

File tree

7 files changed

+466
-468
lines changed

7 files changed

+466
-468
lines changed

namesys/dns_resolver.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ type LookupTXTFunc func(ctx context.Context, name string) (txt []string, err err
2121
// DNSResolver implements [Resolver] on DNS domains.
2222
type DNSResolver struct {
2323
lookupTXT LookupTXTFunc
24-
// TODO: maybe some sort of caching?
25-
// cache would need a timeout
2624
}
2725

2826
var _ Resolver = &DNSResolver{}
@@ -56,7 +54,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
5654
domain := segments[0]
5755

5856
if _, ok := dns.IsDomainName(domain); !ok {
59-
out <- ResolveResult{Err: fmt.Errorf("not a valid domain name: %s", domain)}
57+
out <- ResolveResult{Err: fmt.Errorf("not a valid domain name: %q", domain)}
6058
close(out)
6159
return out
6260
}

namesys/interface.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package namesys
2+
3+
import (
4+
"context"
5+
"errors"
6+
"time"
7+
8+
"github.com/ipfs/boxo/path"
9+
logging "github.com/ipfs/go-log/v2"
10+
ci "github.com/libp2p/go-libp2p/core/crypto"
11+
)
12+
13+
var log = logging.Logger("namesys")
14+
15+
var (
16+
// ErrResolveFailed signals an error when attempting to resolve.
17+
ErrResolveFailed = errors.New("could not resolve name")
18+
19+
// ErrResolveRecursion signals a recursion-depth limit.
20+
ErrResolveRecursion = errors.New("could not resolve name (recursion limit exceeded)")
21+
)
22+
23+
const (
24+
// DefaultDepthLimit is the default depth limit used by [Resolver].
25+
DefaultDepthLimit = 32
26+
27+
// UnlimitedDepth allows infinite recursion in [Resolver]. You probably don't want
28+
// to use this, but it's here if you absolutely trust resolution to eventually
29+
// complete and can't put an upper limit on how many steps it will take.
30+
UnlimitedDepth = 0
31+
32+
// DefaultIPNSRecordTTL specifies the time that the record can be cached before
33+
// checking if its validity again.
34+
DefaultIPNSRecordTTL = time.Minute
35+
36+
// DefaultIPNSRecordEOL specifies the time that the network will cache IPNS
37+
// records after being published. Records should be re-published before this
38+
// interval expires. We use the same default expiration as the DHT.
39+
DefaultIPNSRecordEOL = 48 * time.Hour
40+
41+
// DefaultResolverCacheTTL defines max TTL of a record placed in [NameSystem] cache.
42+
DefaultResolverCacheTTL = time.Minute
43+
)
44+
45+
// NameSystem represents a cohesive name publishing and resolving system.
46+
//
47+
// Publishing a name is the process of establishing a mapping, a key-value
48+
// pair, according to naming rules and databases.
49+
//
50+
// Resolving a name is the process of looking up the value associated with the
51+
// key (name).
52+
type NameSystem interface {
53+
Resolver
54+
Publisher
55+
}
56+
57+
// ResolveResult is the return type for [Resolver.ResolveAsync].
58+
type ResolveResult struct {
59+
Path path.Path
60+
TTL time.Duration
61+
Err error
62+
}
63+
64+
// Resolver is an object capable of resolving names.
65+
type Resolver interface {
66+
// Resolve performs a recursive lookup, returning the dereferenced path. For example,
67+
// if example.com has a DNS TXT record pointing to:
68+
//
69+
// /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
70+
//
71+
// and there is a DHT IPNS entry for
72+
//
73+
// QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
74+
// -> /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
75+
//
76+
// then
77+
//
78+
// Resolve(ctx, "/ipns/ipfs.io")
79+
//
80+
// will resolve both names, returning
81+
//
82+
// /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
83+
//
84+
// There is a default depth-limit to avoid infinite recursion. Most users will be fine with
85+
// this default limit, but if you need to adjust the limit you can specify it as an option.
86+
Resolve(ctx context.Context, name string, options ...ResolveOption) (value path.Path, ttl time.Duration, err error)
87+
88+
// ResolveAsync performs recursive name lookup, like Resolve, but it returns entries as
89+
// they are discovered in the DHT. Each returned result is guaranteed to be "better"
90+
// (which usually means newer) than the previous one.
91+
ResolveAsync(ctx context.Context, name string, options ...ResolveOption) <-chan ResolveResult
92+
}
93+
94+
// ResolveOptions specifies options for resolving an IPNS Path.
95+
type ResolveOptions struct {
96+
// Depth is the recursion depth limit.
97+
Depth uint
98+
99+
// DhtRecordCount is the number of IPNS Records to retrieve from the DHT
100+
// (the best record is selected from this set).
101+
DhtRecordCount uint
102+
103+
// DhtTimeout is the amount of time to wait for DHT records to be fetched
104+
// and verified. A zero value indicates that there is no explicit timeout
105+
// (although there is an implicit timeout due to dial timeouts within the DHT).
106+
DhtTimeout time.Duration
107+
}
108+
109+
// DefaultResolveOptions returns the default options for resolving an IPNS Path.
110+
func DefaultResolveOptions() ResolveOptions {
111+
return ResolveOptions{
112+
Depth: DefaultDepthLimit,
113+
DhtRecordCount: 16,
114+
DhtTimeout: time.Minute,
115+
}
116+
}
117+
118+
// ResolveOption is used to set a resolve option.
119+
type ResolveOption func(*ResolveOptions)
120+
121+
// ResolveWithDepth sets [ResolveOptions.Depth].
122+
func ResolveWithDepth(depth uint) ResolveOption {
123+
return func(o *ResolveOptions) {
124+
o.Depth = depth
125+
}
126+
}
127+
128+
// ResolveWithDhtRecordCount sets [ResolveOptions.DhtRecordCount].
129+
func ResolveWithDhtRecordCount(count uint) ResolveOption {
130+
return func(o *ResolveOptions) {
131+
o.DhtRecordCount = count
132+
}
133+
}
134+
135+
// ResolveWithDhtTimeout sets [ResolveOptions.ResolveWithDhtTimeout].
136+
func ResolveWithDhtTimeout(timeout time.Duration) ResolveOption {
137+
return func(o *ResolveOptions) {
138+
o.DhtTimeout = timeout
139+
}
140+
}
141+
142+
// ProcessResolveOptions converts an array of [ResolveOption] into a [ResolveOptions] object.
143+
func ProcessResolveOptions(opts []ResolveOption) ResolveOptions {
144+
resolveOptions := DefaultResolveOptions()
145+
for _, option := range opts {
146+
option(&resolveOptions)
147+
}
148+
return resolveOptions
149+
}
150+
151+
// Publisher is an object capable of publishing particular names.
152+
type Publisher interface {
153+
// Publish establishes a name-value mapping.
154+
// TODO make this not PrivKey specific.
155+
Publish(ctx context.Context, name ci.PrivKey, value path.Path, options ...PublishOption) error
156+
}
157+
158+
// PublishOptions specifies options for publishing an IPNS Record.
159+
type PublishOptions struct {
160+
EOL time.Time
161+
TTL time.Duration
162+
CompatibleWithV1 bool
163+
}
164+
165+
// DefaultPublishOptions returns the default options for publishing an IPNS Record.
166+
func DefaultPublishOptions() PublishOptions {
167+
return PublishOptions{
168+
EOL: time.Now().Add(DefaultIPNSRecordEOL),
169+
TTL: DefaultIPNSRecordTTL,
170+
}
171+
}
172+
173+
// PublishOption is used to set an option for [PublishOptions].
174+
type PublishOption func(*PublishOptions)
175+
176+
// PublishWithEOL sets [PublishOptions.EOL].
177+
func PublishWithEOL(eol time.Time) PublishOption {
178+
return func(o *PublishOptions) {
179+
o.EOL = eol
180+
}
181+
}
182+
183+
// PublishWithEOL sets [PublishOptions.TTL].
184+
func PublishWithTTL(ttl time.Duration) PublishOption {
185+
return func(o *PublishOptions) {
186+
o.TTL = ttl
187+
}
188+
}
189+
190+
// PublishCompatibleWithV1 sets [PublishOptions.CompatibleWithV1].
191+
func PublishCompatibleWithV1(compatible bool) PublishOption {
192+
return func(o *PublishOptions) {
193+
o.CompatibleWithV1 = compatible
194+
}
195+
}
196+
197+
// ProcessPublishOptions converts an array of [PublishOption] into a [PublishOptions] object.
198+
func ProcessPublishOptions(opts []PublishOption) PublishOptions {
199+
publishOptions := DefaultPublishOptions()
200+
for _, option := range opts {
201+
option(&publishOptions)
202+
}
203+
return publishOptions
204+
}

namesys/ipns_publisher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ func PublishPublicKey(ctx context.Context, r routing.ValueStore, key string, pub
252252
ctx, span := startSpan(ctx, "PublishPublicKey", trace.WithAttributes(attribute.String("Key", key)))
253253
defer span.End()
254254

255-
log.Debugf("Storing pubkey at: %s", key)
255+
log.Debugf("Storing pubkey at: %q", key)
256256
bytes, err := crypto.MarshalPublicKey(pubKey)
257257
if err != nil {
258258
return err

0 commit comments

Comments
 (0)