Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor record validation #17

Merged
merged 4 commits into from
Jun 2, 2018
Merged

refactor record validation #17

merged 4 commits into from
Jun 2, 2018

Conversation

Stebalien
Copy link
Member

@Stebalien Stebalien commented May 9, 2018

When generalizing routing, I noticed a couple of issues:

  1. Passing around separate validators/selectors is annoying. All records should support both validation and selection.
  2. We already need validators with state (e.g., access to the peerstore) so we might as well define them in terms of an interface.
  3. Not all record stores will use the record protobuf type and tying validation to it is kind of annoying.
  4. Using the same interface for the namespaced validator and the sub-validators is really convenient. The cost of having to re-split the key is minimal.

Stebalien added 2 commits May 2, 2018 15:21
Instead of re-implementing the key splitting logic everywhere, we might as well
expose it.
When generalizing routing, I noticed a couple of issues:

1. Passing around separate validators/selectors is annoying. All records should
   support both validation and selection.
2. We already need validators with state (e.g., access to the peerstore) so we
   might as well define them in terms of an interface.
3. Not all record stores will use the record protobuf type and tying validation
   to it is kind of annoying.
4. Using the same interface for the namespaced validator and the sub-validators
   is really convenient. The cost of having to re-split the key is minimal.
@ghost ghost assigned Stebalien May 9, 2018
@ghost ghost added the status/in-progress In progress label May 9, 2018
@Stebalien Stebalien requested a review from vyzo May 9, 2018 15:56
// Validate validates the given record, returning an error if it's
// invalid (e.g., expired, signed by the wrong key, etc.).
Validate(key string, value []byte) error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth making the Select function look more like the less parameter to Sort's Slice function?
Otherwise every Select implementation will need to implement similar functionality to iterate over the values, return an error if the list is empty, or if there is no value found etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, that can be implemented as a wrapper. Defining Select as we have here allows us to halve the number of times we have to deserialize the values when comparing multiple values.

Wrapper:

func Less(key string, values [][]byte, v Validator) func(i, j int) bool { /* ... */ }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien agreed. this is less a full sort and more a min function. unless there is use for a full priority sorted list of entries, i think this approach is fine.

Copy link
Contributor

@bigs bigs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! would only consider leveraging SplitN if that makes sense!


// SplitKey takes a key in the form `/$namespace/$path` and splits it into
// `$namespace` and `$path`.
func SplitKey(key string) (string, string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could simplify this a bit i think!

parts := strings.SplitN(key, "/", 3)
if len(parts) < 3 || len(parts[0]) > 0 || len(parts[1]) == 0 || len(parts[2]) == 0 {
    return "", "", ErrInvalidRecordType
}
return parts[1], parts[2], nil

dno if this matters tho!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I first wrote that function, I chose not to use SplitN to save on allocations. Basically, I want to make that function as fast as possible so we can call it with impunity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm. impl is strong as stands, then.

validator.go Outdated

// ErrBadRecord is returned any time a dht record is found to be
// incorrectly formatted or signed.
var ErrBadRecord = errors.New("bad dht record")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps for purposes of more specific logging, we could separate into

var ErrBadRecord = errors.New("bad dht record: improperly formatted")
var ErrBadSignature = errors.New("bad dht record: improperly signed")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it looks like ErrBadRecord isn't even used. Validators return different errors depending on what went wrong. I'll just remove that error.

// Validate validates the given record, returning an error if it's
// invalid (e.g., expired, signed by the wrong key, etc.).
Validate(key string, value []byte) error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien agreed. this is less a full sort and more a min function. unless there is use for a full priority sorted list of entries, i think this approach is fine.

@Stebalien Stebalien force-pushed the feat/routing-refactor branch from fa9cc59 to b3dd0d6 Compare May 31, 2018 19:06
@Stebalien Stebalien merged commit c4c6ef6 into master Jun 2, 2018
@ghost ghost removed the status/in-progress In progress label Jun 2, 2018
@Stebalien Stebalien deleted the feat/routing-refactor branch June 2, 2018 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants