@@ -31,17 +31,18 @@ const DefaultPrefix protocol.ID = "/ipfs"
3131
3232// Options is a structure containing all the options that can be used when constructing a DHT.
3333type config struct {
34- datastore ds.Batching
35- validator record.Validator
36- mode ModeOpt
37- protocolPrefix protocol.ID
38- bucketSize int
39- concurrency int
40- resiliency int
41- maxRecordAge time.Duration
42- enableProviders bool
43- enableValues bool
44- queryPeerFilter QueryFilterFunc
34+ datastore ds.Batching
35+ validator record.Validator
36+ validatorChanged bool // if true implies that the validator has been changed and that defaults should not be used
37+ mode ModeOpt
38+ protocolPrefix protocol.ID
39+ bucketSize int
40+ concurrency int
41+ resiliency int
42+ maxRecordAge time.Duration
43+ enableProviders bool
44+ enableValues bool
45+ queryPeerFilter QueryFilterFunc
4546
4647 routingTable struct {
4748 refreshQueryTimeout time.Duration
@@ -72,10 +73,10 @@ func (c *config) apply(opts ...Option) error {
7273// applyFallbacks sets default values that could not be applied during config creation since they are dependent
7374// on other configuration parameters (e.g. optA is by default 2x optB) and/or on the Host
7475func (c * config ) applyFallbacks (h host.Host ) {
75- if c . protocolPrefix == DefaultPrefix {
76- nsval , ok := c .validator .( record.NamespacedValidator )
77- if ok {
78- nsval [ "ipns" ] = ipns.Validator {KeyBook : h .Peerstore ()}
76+ if ! c . validatorChanged {
77+ c .validator = record.NamespacedValidator {
78+ "pk" : record. PublicKeyValidator {},
79+ "ipns" : ipns.Validator {KeyBook : h .Peerstore ()},
7980 }
8081 }
8182}
@@ -88,9 +89,6 @@ const defaultBucketSize = 20
8889// defaults are the default DHT options. This option will be automatically
8990// prepended to any options you pass to the DHT constructor.
9091var defaults = func (o * config ) error {
91- o .validator = record.NamespacedValidator {
92- "pk" : record.PublicKeyValidator {},
93- }
9492 o .datastore = dssync .MutexWrap (ds .NewMapDatastore ())
9593 o .protocolPrefix = DefaultPrefix
9694 o .enableProviders = true
@@ -187,30 +185,45 @@ func Mode(m ModeOpt) Option {
187185
188186// Validator configures the DHT to use the specified validator.
189187//
190- // Defaults to a namespaced validator that can only validate public keys.
191- // For the default protocol prefix it defaults to a namespaced validator that
192- // supports validating both public key and IPNS records
188+ // Defaults to a namespaced validator that can validate both public key (under the "pk"
189+ // namespaced) and IPNS records (under the "ipns" namespace). Setting the validator
190+ // implies that the user wants to control the validators and therefore the default
191+ // public key and IPNS validators will not be added.
193192func Validator (v record.Validator ) Option {
194193 return func (c * config ) error {
195194 c .validator = v
195+ c .validatorChanged = true
196196 return nil
197197 }
198198}
199199
200200// NamespacedValidator adds a validator namespaced under `ns`. This option fails
201- // if the DHT is not using a `record.NamespacedValidator` as it's validator (it
202- // uses one by default but this can be overridden with the `Validator` option).
201+ // if the DHT is not using a `record.NamespacedValidator` as its validator. If
202+ // the validator has yet to be modified (e.g. by the `Validator` option) then
203+ // a NamespacedValidator will be created implicitly. Adding a namespaced
204+ // validator implies that the user wants to control the validators and therefore
205+ // the default public key and IPNS validators will not be added.
203206//
204207// Example: Given a validator registered as `NamespacedValidator("ipns",
205208// myValidator)`, all records with keys starting with `/ipns/` will be validated
206209// with `myValidator`.
207210func NamespacedValidator (ns string , v record.Validator ) Option {
208211 return func (c * config ) error {
209- nsval , ok := c .validator .(record.NamespacedValidator )
210- if ! ok {
211- return fmt .Errorf ("can only add namespaced validators to a NamespacedValidator" )
212+ // while the validator will not change if there's an error setting the validator that is only possible
213+ // if the validator has already been changed
214+ c .validatorChanged = true
215+
216+ if c .validator == nil {
217+ c .validator = record.NamespacedValidator {
218+ ns : v ,
219+ }
220+ } else {
221+ nsval , ok := c .validator .(record.NamespacedValidator )
222+ if ! ok {
223+ return fmt .Errorf ("can only add namespaced validators to a NamespacedValidator" )
224+ }
225+ nsval [ns ] = v
212226 }
213- nsval [ns ] = v
214227 return nil
215228 }
216229}
0 commit comments